UNPKG

mcp-use

Version:

Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents, Clients and Servers with support for ChatGPT Apps, Code Mode, OAuth, Notifications, Sampling, Observability and more.

367 lines 13.5 kB
/** * Tool Context Types * * Defines the context object and related types passed to tool callbacks. * Provides access to sampling, elicitation, and progress reporting capabilities. */ import type { CreateMessageRequest, CreateMessageResult, ElicitResult } from "@modelcontextprotocol/sdk/types.js"; import type { z } from "zod"; /** * Options for the sample() function in tool context. */ export interface SampleOptions { /** * Timeout in milliseconds for the sampling request. * Default: no timeout (Infinity) - waits indefinitely for the LLM response. * Set this if you want to limit how long to wait for sampling. */ timeout?: number; /** * Interval in milliseconds between progress notifications. * Default: 5000 (5 seconds). * Progress notifications are sent to the client to prevent timeout * when the client has resetTimeoutOnProgress enabled. */ progressIntervalMs?: number; /** * Optional callback called each time a progress notification is sent. * Useful for logging or custom progress handling. */ onProgress?: (progress: { progress: number; total?: number; message: string; }) => void; /** * Maximum number of tokens to generate. * Default: 1000 (when using string prompt shorthand). * Only used when calling sample() with a string prompt. */ maxTokens?: number; /** * Model preferences for sampling. * Allows specifying which models to use via hints. */ modelPreferences?: { hints?: Array<{ name?: string; }>; costPriority?: number; speedPriority?: number; intelligencePriority?: number; }; /** * System prompt to prepend to the conversation. */ systemPrompt?: string; /** * Temperature for sampling (0.0 to 1.0). * Controls randomness in the response. */ temperature?: number; /** * Stop sequences to end generation. */ stopSequences?: string[]; /** * Additional metadata to pass with the request. */ metadata?: Record<string, unknown>; } /** * Options for the elicit() function in tool context. */ export interface ElicitOptions { /** * Timeout in milliseconds for the elicitation request. * Default: no timeout (Infinity) - waits indefinitely for user response. * Set this if you want to limit how long to wait for user input. * * @example * ```typescript * // Wait indefinitely (default) * await ctx.elicit(message, schema); * * // With 2 minute timeout * await ctx.elicit(message, schema, { timeout: 120000 }); * ``` */ timeout?: number; } /** * Parameters for form mode elicitation. * Used to request structured data from users with optional JSON schema validation. */ export interface ElicitFormParams { /** Human-readable message explaining why the information is needed */ message: string; /** JSON Schema defining the structure of the expected response */ requestedSchema: Record<string, any>; /** Mode specifier (optional for backwards compatibility, defaults to "form") */ mode?: "form"; } /** * Parameters for URL mode elicitation. * Used to direct users to external URLs for sensitive interactions. * MUST be used for interactions involving sensitive information like credentials. */ export interface ElicitUrlParams { /** Human-readable message explaining why the interaction is needed */ message: string; /** URL for the user to navigate to */ url: string; /** Mode specifier (required for URL mode) */ mode: "url"; } /** * Context object passed to tool callbacks. * Provides access to sampling, elicitation, and progress reporting capabilities. */ export interface ToolContext { /** * Request sampling from the client's LLM with automatic progress notifications. * * Supports two calling patterns: * 1. **Simplified string API**: Pass a prompt string with optional options * 2. **Full control API**: Pass complete CreateMessageRequest params * * Progress notifications are sent every 5 seconds (configurable) while waiting * for the sampling response. This prevents client-side timeouts when the client * has `resetTimeoutOnProgress: true` enabled. * * By default, there is no timeout - the function waits indefinitely for the * LLM response. Set `options.timeout` to limit the wait time. * * @param promptOrParams - Either a string prompt or complete sampling parameters * @param options - Optional configuration for timeout, progress, maxTokens, etc. * @returns The sampling result from the client's LLM * * @example * ```typescript * // Simplified API - just pass a string prompt * const result = await ctx.sample("What is the capital of France?"); * * // With options (maxTokens, temperature, etc.) * const result = await ctx.sample( * "Analyze this code...", * { maxTokens: 2000, temperature: 0.7 } * ); * * // Full control API - complete params object * const result = await ctx.sample({ * messages: [ * { role: 'system', content: { type: 'text', text: 'You are helpful' } }, * { role: 'user', content: { type: 'text', text: 'Hello' } } * ], * maxTokens: 1500, * modelPreferences: { hints: [{ name: 'claude-3-5-sonnet' }] } * }); * * // With timeout and custom progress handling * const result = await ctx.sample( * "Complex task...", * { * timeout: 120000, // 2 minute timeout * progressIntervalMs: 3000, // Report progress every 3 seconds * onProgress: ({ progress, message }) => console.log(message), * } * ); * ``` */ sample: { (prompt: string, options?: SampleOptions): Promise<CreateMessageResult>; (params: CreateMessageRequest["params"], options?: SampleOptions): Promise<CreateMessageResult>; }; /** * Request user input via the client through elicitation. * * Supports two modes with automatic mode detection: * - **Form mode**: Pass a Zod schema as second parameter - collects structured data * - **URL mode**: Pass a URL string as second parameter - directs to external URL * - **Verbose mode**: Pass an object with explicit mode for backwards compatibility * * By default, there is no timeout - waits indefinitely for user response. * Set `options.timeout` to limit the wait time. * * @example * ```typescript * // Form mode (simplified) - automatically inferred from Zod schema * const result = await ctx.elicit( * "Please provide your information", * z.object({ * name: z.string().default("Anonymous"), * age: z.number().default(0) * }) * ); * // result.data is typed as { name: string, age: number } * * // With timeout * const result = await ctx.elicit( * "Enter info", * z.object({ name: z.string() }), * { timeout: 60000 } // 1 minute timeout * ); * * // URL mode (simplified) - automatically inferred from URL string * const authResult = await ctx.elicit( * "Please authorize access", * "https://example.com/oauth/authorize" * ); * * // Verbose API (backwards compatible) * const verboseResult = await ctx.elicit({ * message: "Please provide your information", * requestedSchema: { type: "object", properties: {...} }, * mode: "form" * }); * ``` */ elicit: { <T extends z.ZodObject<any>>(message: string, schema: T, options?: ElicitOptions): Promise<ElicitResult & { data: z.infer<T>; }>; (message: string, url: string, options?: ElicitOptions): Promise<ElicitResult>; (params: ElicitFormParams | ElicitUrlParams, options?: ElicitOptions): Promise<ElicitResult>; }; /** * Send a progress notification to the client. * Only available if the client requested progress updates for this tool call. * * @param progress - Current progress value (should increase with each call) * @param total - Total progress value if known * @param message - Optional message describing current progress */ reportProgress?: (progress: number, total?: number, message?: string) => Promise<void>; /** * Send a log notification to the client. * Always available - will send notifications if the client supports them. * * @param level - Log level (debug, info, notice, warning, error, critical, alert, emergency) * @param message - Log message content * @param logger - Optional logger name (defaults to 'tool') * * @example * ```typescript * await ctx.log('info', 'Processing started'); * await ctx.log('debug', 'Debug details', 'my-tool'); * await ctx.log('error', 'Something went wrong'); * ``` */ log: (level: "debug" | "info" | "notice" | "warning" | "error" | "critical" | "alert" | "emergency", message: string, logger?: string) => Promise<void>; /** * Client capability interface * Provides access to client capabilities advertised during initialization */ client: { /** * Check if client supports a specific capability * @param capability - Capability name (e.g., "sampling", "elicitation", "roots") * @returns true if client advertised this capability, false otherwise * * @example * ```typescript * if (ctx.client.can('sampling')) { * const result = await ctx.sample('Analyze this'); * } else { * // Fallback to non-sampling logic * } * ``` */ can(capability: string): boolean; /** * Get all client capabilities * @returns Object containing all capabilities advertised by the client, or empty object if none * * @example * ```typescript * const caps = ctx.client.capabilities(); * console.log(caps); * // { sampling: {}, roots: { listChanged: true }, elicitation: { form: {}, url: {} } } * ``` */ capabilities(): Record<string, any>; }; /** * Session information for the current tool execution * Provides access to the session ID and other metadata */ session: { /** * Unique identifier for the current session * Can be used with ctx.sendNotificationToSession() to target this session from other tools */ sessionId: string; }; /** * Send a notification to the current session (the client that called this tool) * * This is a convenience method that sends a notification only to the session * that initiated the current tool execution. For broadcasting to all sessions, * use server.sendNotification() instead. * * @param method - The notification method name (e.g., "custom/my-notification") * @param params - Optional parameters to include in the notification * @returns Promise that resolves when the notification is sent * * @example * ```typescript * server.tool({ * name: 'process_data', * cb: async (params, ctx) => { * // Send progress update to the current session * await ctx.sendNotification('custom/processing', { * status: 'started', * timestamp: Date.now() * }); * * // Do work... * * await ctx.sendNotification('custom/processing', { * status: 'completed' * }); * * return { content: [{ type: 'text', text: 'Done' }] }; * } * }); * ``` */ sendNotification: (method: string, params?: Record<string, unknown>) => Promise<void>; /** * Send a notification to a specific session by ID * * This allows sending notifications to any connected session, not just the * current one. Useful for cross-session communication or coordinating between * multiple clients. * * @param sessionId - The target session ID (can get from ctx.session.sessionId or server.getActiveSessions()) * @param method - The notification method name (e.g., "custom/my-notification") * @param params - Optional parameters to include in the notification * @returns Promise<boolean> - true if notification was sent, false if session not found * * @example * ```typescript * server.tool({ * name: 'notify_others', * cb: async (params, ctx) => { * const mySessionId = ctx.session.sessionId; * * // Notify another specific session * const success = await ctx.sendNotificationToSession( * params.targetSessionId, * 'custom/message', * { from: mySessionId, text: 'Hello!' } * ); * * return { * content: [{ * type: 'text', * text: success ? 'Notification sent' : 'Session not found' * }] * }; * } * }); * ``` */ sendNotificationToSession: (sessionId: string, method: string, params?: Record<string, unknown>) => Promise<boolean>; } //# sourceMappingURL=tool-context.d.ts.map