TanStack
MCP

Draft Text from a Tool

You want the tool to return a draft. The tool has no model result yet.

Call ctx.context.sample inside the tool. Pass a sample function to createMCPServer. Give .server() the type MCPToolContext, so ctx.context.sample type-checks.

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)
}

ctx.context.sample is a method on the context of the tool. The sample function is (request) => Promise<unknown>.

Spec 2025 and spec 2026

SpecResult
Spec 2025ctx.context.sample asks the MCP client. It does not call the sample function.
Spec 2026ctx.context.sample calls the sample function. It does not ask the client.
Spec 2026 with no samplectx.context.sample throws an Error. The message names sample.

Call draft_note with a topic. The tool result is the draft text.