AI Docs
Chat & Streaming
Transports
Tools
Middleware
Chat UI Recipes
Interrupts
MCP
Resumable Streams
Persistence
Persistence (Advanced)
Media
Embeddings
Reranking
Evaluate
Code Mode
Computer Use
Harness
- Build your first harness
- Host options
- Send and show media
- Connect clients
- Write a client in any language
- Access and tenants
- Run in the terminal
- Deploy a harness
- Send inputs safely
- Run a tool without a model
- Durable sessions
- Run background work on workers
- List, rename, and fork sessions
- Lifecycle and retention
- Run side effects once
- Wait for a person
- Build on the session log
- Control how a turn ends
- Store settings per thread
- Compact a long session
- Fork and reset a thread
- One log for a session tree
- Write a plugin
- Track usage and cost
- Ask before risky tool calls
- Give your agent coding tools
- Sandbox and extend the coding tools
- Run the coding tools for many threads
- Undo a turn
- Build a coding agent
- Delegate to coding agents
- Switch between agent profiles
- Auth and connectors
- Share a thread between people
- Connect model providers
- Build your own UI
- Code mode in a harness
- Work until a goal is met
- Run agents from a harness
- Hand off a conversation
- Add skills
- Use MCP servers
- Give your agent a computer
- Use from any MCP client
- Use a harness from an editor (ACP)
Sandboxes
- Overview
- Quick Start
- Providers
- Harnesses
- Harness Auth
- Workspace
- Tools
- Policy
- Lifecycle & Snapshots
- Portable Snapshots
- Keep Files After Reload
- Save a Named Version
- Branch From a Version
- Send a Frozen File
- Let the Agent Save and Fork
- Pick Which Files to Keep
- What a Snapshot Stores
- Instance Durability
- Durable Runs
- Events
Sandboxes (Advanced)
Advanced
- Runtime Context
- Bring Your Own Key
- Keep Keys on the Server
- Debug Logging
- Multimodal Content
- Files API
- Per-Model Type Safety
- Runtime Adapter Switching
- Tree-Shaking
- Extend Adapter
- Extend Adapter: Advanced
- Typed Pre-Configured Options
- Test with a Fake Model
- Prompt Caching
- Mid-Conversation Changes
- Approval Flow Processing
AI/LLM: This documentation page is available in plain markdown format at/ai/latest/docs/mcp/server-sample.md
MCP
Draft Text from a Tool
sample lets an MCP tool call a model for a draft, such as a short note. The tool itself has no model.
Call it as ctx.context.sample inside the tool.
Quick setup#
You need an MCP server first. If you do not have one, start with Serve Tools over HTTP.
- Give .server() the type MCPToolContext, so ctx.context.sample type-checks.
- Call ctx.context.sample with the messages for the model.
- Pass a sample function to createMCPServer. It answers the sample request.
ts
import { toolDefinition } from '@tanstack/ai'
import { createMCPServer } from '@tanstack/ai-mcp/server'
import type { MCPToolContext } from '@tanstack/ai-mcp/server'
import { z } from 'zod'
const draftNote = toolDefinition({
name: 'draft_note',
description: 'Draft a short note about a topic',
inputSchema: z.object({
topic: z.string(),
}),
}).server<MCPToolContext>(async (args, ctx) => {
const draft = await ctx.context.sample({
messages: [
{
role: 'user',
content: `Write a short note about ${args.topic}.`,
},
],
})
if (typeof draft !== 'string') {
throw new Error('The sample result is not text.')
}
return draft
})
const server = createMCPServer({
name: 'notes',
version: '1.0.0',
tools: [draftNote],
sample: async (request) => {
const first = request.messages[0]
const content = first === undefined ? '' : first.content
return `Draft: ${content}`
},
})
export function handleMcp(request: Request) {
return server.fetch(request)
}Call draft_note with a topic. The tool result is the draft text. In this example, the sample function returns Draft: plus the message. In your app, call your model there.
How it works#
- ctx.context.sample is a method on the context of the tool.
- The sample function has the type (request) => Promise<unknown>.
- Who answers depends on the MCP spec version of the client. See the table below.
Advanced#
Spec 2025 and spec 2026#
| Spec | Result |
|---|---|
| Spec 2025 | ctx.context.sample asks the MCP client. It does not call the sample function. |
| Spec 2026 | ctx.context.sample calls the sample function. It does not ask the client. |
| Spec 2026 with no sample | ctx.context.sample throws an Error. The message names sample. |
On spec 2025, the server can ask the client only when it keeps a session. Without a session, ctx.context.sample calls the sample function. See MCP Server Sessions.