mcp-use
Version:
Opinionated MCP Framework for TypeScript (@modelcontextprotocol/sdk compatible) - Build MCP Agents and Clients + MCP Servers with support for MCP-UI.
556 lines • 23.1 kB
TypeScript
import type { PromptDefinition, ResourceDefinition, ResourceTemplateDefinition, ServerConfig, ToolDefinition, UIResourceDefinition } from "./types/index.js";
import { type Express } from "express";
export declare class McpServer {
private server;
private config;
private app;
private mcpMounted;
private inspectorMounted;
private serverPort?;
private serverHost;
private serverBaseUrl?;
/**
* Creates a new MCP server instance with Express integration
*
* Initializes the server with the provided configuration, sets up CORS headers,
* configures widget serving routes, and creates a proxy that allows direct
* access to Express methods while preserving MCP server functionality.
*
* @param config - Server configuration including name, version, and description
* @returns A proxied McpServer instance that supports both MCP and Express methods
*/
constructor(config: ServerConfig);
/**
* Define a static resource that can be accessed by clients
*
* Registers a resource with the MCP server that clients can access via HTTP.
* Resources are static content like files, data, or pre-computed results that
* can be retrieved by clients without requiring parameters.
*
* @param resourceDefinition - Configuration object containing resource metadata and handler function
* @param resourceDefinition.name - Unique identifier for the resource
* @param resourceDefinition.uri - URI pattern for accessing the resource
* @param resourceDefinition.title - Optional human-readable title for the resource
* @param resourceDefinition.description - Optional description of the resource
* @param resourceDefinition.mimeType - MIME type of the resource content
* @param resourceDefinition.annotations - Optional annotations (audience, priority, lastModified)
* @param resourceDefinition.readCallback - Async callback function that returns the resource content
* @returns The server instance for method chaining
*
* @example
* ```typescript
* server.resource({
* name: 'config',
* uri: 'config://app-settings',
* title: 'Application Settings',
* mimeType: 'application/json',
* description: 'Current application configuration',
* annotations: {
* audience: ['user'],
* priority: 0.8
* },
* readCallback: async () => ({
* contents: [{
* uri: 'config://app-settings',
* mimeType: 'application/json',
* text: JSON.stringify({ theme: 'dark', language: 'en' })
* }]
* })
* })
* ```
*/
resource(resourceDefinition: ResourceDefinition): this;
/**
* Define a dynamic resource template with parameters
*
* Registers a parameterized resource template with the MCP server. Templates use URI
* patterns with placeholders that can be filled in at request time, allowing dynamic
* resource generation based on parameters.
*
* @param resourceTemplateDefinition - Configuration object for the resource template
* @param resourceTemplateDefinition.name - Unique identifier for the template
* @param resourceTemplateDefinition.resourceTemplate - ResourceTemplate object with uriTemplate and metadata
* @param resourceTemplateDefinition.readCallback - Async callback function that generates resource content from URI and params
* @returns The server instance for method chaining
*
* @example
* ```typescript
* server.resourceTemplate({
* name: 'user-profile',
* resourceTemplate: {
* uriTemplate: 'user://{userId}/profile',
* name: 'User Profile',
* mimeType: 'application/json'
* },
* readCallback: async (uri, params) => ({
* contents: [{
* uri: uri.toString(),
* mimeType: 'application/json',
* text: JSON.stringify({ userId: params.userId, name: 'John Doe' })
* }]
* })
* })
* ```
*/
resourceTemplate(resourceTemplateDefinition: ResourceTemplateDefinition): this;
/**
* Define a tool that can be called by clients
*
* Registers a tool with the MCP server that clients can invoke with parameters.
* Tools are functions that perform actions, computations, or operations and
* return results. They accept structured input parameters and return structured output.
*
* Supports Apps SDK metadata for ChatGPT integration via the _meta field.
*
* @param toolDefinition - Configuration object containing tool metadata and handler function
* @param toolDefinition.name - Unique identifier for the tool
* @param toolDefinition.description - Human-readable description of what the tool does
* @param toolDefinition.inputs - Array of input parameter definitions with types and validation
* @param toolDefinition.cb - Async callback function that executes the tool logic with provided parameters
* @param toolDefinition._meta - Optional metadata for the tool (e.g. Apps SDK metadata)
* @returns The server instance for method chaining
*
* @example
* ```typescript
* server.tool({
* name: 'calculate',
* description: 'Performs mathematical calculations',
* inputs: [
* { name: 'expression', type: 'string', required: true },
* { name: 'precision', type: 'number', required: false }
* ],
* cb: async ({ expression, precision = 2 }) => {
* const result = eval(expression)
* return { result: Number(result.toFixed(precision)) }
* },
* _meta: {
* 'openai/outputTemplate': 'ui://widgets/calculator',
* 'openai/toolInvocation/invoking': 'Calculating...',
* 'openai/toolInvocation/invoked': 'Calculation complete'
* }
* })
* ```
*/
tool(toolDefinition: ToolDefinition): this;
/**
* Define a prompt template
*
* Registers a prompt template with the MCP server that clients can use to generate
* structured prompts for AI models. Prompt templates accept parameters and return
* formatted text that can be used as input to language models or other AI systems.
*
* @param promptDefinition - Configuration object containing prompt metadata and handler function
* @param promptDefinition.name - Unique identifier for the prompt template
* @param promptDefinition.description - Human-readable description of the prompt's purpose
* @param promptDefinition.args - Array of argument definitions with types and validation
* @param promptDefinition.cb - Async callback function that generates the prompt from provided arguments
* @returns The server instance for method chaining
*
* @example
* ```typescript
* server.prompt({
* name: 'code-review',
* description: 'Generates a code review prompt',
* args: [
* { name: 'language', type: 'string', required: true },
* { name: 'focus', type: 'string', required: false }
* ],
* cb: async ({ language, focus = 'general' }) => {
* return {
* messages: [{
* role: 'user',
* content: `Please review this ${language} code with focus on ${focus}...`
* }]
* }
* }
* })
* ```
*/
prompt(promptDefinition: PromptDefinition): this;
/**
* Register a UI widget as both a tool and a resource
*
* Creates a unified interface for MCP-UI compatible widgets that can be accessed
* either as tools (with parameters) or as resources (static access). The tool
* allows dynamic parameter passing while the resource provides discoverable access.
*
* Supports multiple UI resource types:
* - externalUrl: Legacy MCP-UI iframe-based widgets
* - rawHtml: Legacy MCP-UI raw HTML content
* - remoteDom: Legacy MCP-UI Remote DOM scripting
* - appsSdk: OpenAI Apps SDK compatible widgets (text/html+skybridge)
*
* @param widgetNameOrDefinition - Widget name (string) for auto-loading schema, or full configuration object
* @param definition.name - Unique identifier for the resource
* @param definition.type - Type of UI resource (externalUrl, rawHtml, remoteDom, appsSdk)
* @param definition.title - Human-readable title for the widget
* @param definition.description - Description of the widget's functionality
* @param definition.props - Widget properties configuration with types and defaults
* @param definition.size - Preferred iframe size [width, height] (e.g., ['900px', '600px'])
* @param definition.annotations - Resource annotations for discovery
* @param definition.appsSdkMetadata - Apps SDK specific metadata (CSP, widget description, etc.)
* @returns The server instance for method chaining
*
* @example
* ```typescript
* // Simple usage - auto-loads from generated schema
* server.uiResource('display-weather')
*
* // Legacy MCP-UI widget
* server.uiResource({
* type: 'externalUrl',
* name: 'kanban-board',
* widget: 'kanban-board',
* title: 'Kanban Board',
* description: 'Interactive task management board',
* props: {
* initialTasks: {
* type: 'array',
* description: 'Initial tasks to display',
* required: false
* }
* },
* size: ['900px', '600px']
* })
*
* // Apps SDK widget
* server.uiResource({
* type: 'appsSdk',
* name: 'kanban-board',
* title: 'Kanban Board',
* description: 'Interactive task management board',
* htmlTemplate: `
* <div id="kanban-root"></div>
* <style>${kanbanCSS}</style>
* <script type="module">${kanbanJS}</script>
* `,
* appsSdkMetadata: {
* 'openai/widgetDescription': 'Displays an interactive kanban board',
* 'openai/widgetCSP': {
* connect_domains: [],
* resource_domains: ['https://cdn.example.com']
* }
* }
* })
* ```
*/
uiResource(definition: UIResourceDefinition): this;
/**
* Create a UIResource object for a widget with the given parameters
*
* This method is shared between tool and resource handlers to avoid duplication.
* It creates a consistent UIResource structure that can be rendered by MCP-UI
* compatible clients.
*
* @private
* @param definition - UIResource definition
* @param params - Parameters to pass to the widget via URL
* @returns UIResource object compatible with MCP-UI
*/
private createWidgetUIResource;
/**
* Build a complete URL for a widget including query parameters
*
* Constructs the full URL to access a widget's iframe, encoding any provided
* parameters as query string parameters. Complex objects are JSON-stringified
* for transmission.
*
* @private
* @param widget - Widget name/identifier
* @param params - Parameters to encode in the URL
* @returns Complete URL with encoded parameters
*/
private buildWidgetUrl;
/**
* Convert widget props definition to tool input schema
*
* Transforms the widget props configuration into the format expected by
* the tool registration system, mapping types and handling defaults.
*
* @private
* @param props - Widget props configuration
* @returns Array of InputDefinition objects for tool registration
*/
private convertPropsToInputs;
/**
* Apply default values to widget props
*
* Extracts default values from the props configuration to use when
* the resource is accessed without parameters.
*
* @private
* @param props - Widget props configuration
* @returns Object with default values for each prop
*/
private applyDefaultProps;
/**
* Check if server is running in production mode
*
* @private
* @returns true if in production mode, false otherwise
*/
private isProductionMode;
/**
* Read build manifest file
*
* @private
* @returns Build manifest or null if not found
*/
private readBuildManifest;
/**
* Mount widget files - automatically chooses between dev and production mode
*
* In development mode: creates Vite dev servers with HMR support
* In production mode: serves pre-built static widgets
*
* @param options - Configuration options
* @param options.baseRoute - Base route for widgets (defaults to '/mcp-use/widgets')
* @param options.resourcesDir - Directory containing widget files (defaults to 'resources')
* @returns Promise that resolves when all widgets are mounted
*/
mountWidgets(options?: {
baseRoute?: string;
resourcesDir?: string;
}): Promise<void>;
/**
* Mount individual widget files from resources/ directory in development mode
*
* Scans the resources/ directory for .tsx/.ts widget files and creates individual
* Vite dev servers for each widget with HMR support. Each widget is served at its
* own route: /mcp-use/widgets/{widget-name}
*
* @private
* @param options - Configuration options
* @param options.baseRoute - Base route for widgets (defaults to '/mcp-use/widgets')
* @param options.resourcesDir - Directory containing widget files (defaults to 'resources')
* @returns Promise that resolves when all widgets are mounted
*/
private mountWidgetsDev;
/**
* Mount pre-built widgets from dist/resources/widgets/ directory in production mode
*
* Serves static widget bundles that were built using the build command.
* Sets up Express routes to serve the HTML and asset files, then registers
* tools and resources for each widget.
*
* @private
* @param options - Configuration options
* @param options.baseRoute - Base route for widgets (defaults to '/mcp-use/widgets')
* @returns Promise that resolves when all widgets are mounted
*/
private mountWidgetsProduction;
/**
* Mount MCP server endpoints at /mcp
*
* Sets up the HTTP transport layer for the MCP server, creating endpoints for
* Server-Sent Events (SSE) streaming, POST message handling, and DELETE session cleanup.
* Each request gets its own transport instance to prevent state conflicts between
* concurrent client connections.
*
* This method is called automatically when the server starts listening and ensures
* that MCP clients can communicate with the server over HTTP.
*
* @private
* @returns Promise that resolves when MCP endpoints are successfully mounted
*
* @example
* Endpoints created:
* - GET /mcp - SSE streaming endpoint for real-time communication
* - POST /mcp - Message handling endpoint for MCP protocol messages
* - DELETE /mcp - Session cleanup endpoint
*/
private mountMcp;
/**
* Start the Express server with MCP endpoints
*
* Initiates the server startup process by mounting MCP endpoints, configuring
* the inspector UI (if available), and starting the Express server to listen
* for incoming connections. This is the main entry point for running the server.
*
* The server will be accessible at the specified port with MCP endpoints at /mcp
* and inspector UI at /inspector (if the inspector package is installed).
*
* @param port - Port number to listen on (defaults to 3001 if not specified)
* @returns Promise that resolves when the server is successfully listening
*
* @example
* ```typescript
* await server.listen(8080)
* // Server now running at http://localhost:8080 (or configured host)
* // MCP endpoints: http://localhost:8080/mcp
* // Inspector UI: http://localhost:8080/inspector
* ```
*/
listen(port?: number): Promise<void>;
/**
* Mount MCP Inspector UI at /inspector
*
* Dynamically loads and mounts the MCP Inspector UI package if available, providing
* a web-based interface for testing and debugging MCP servers. The inspector
* automatically connects to the local MCP server endpoints.
*
* This method gracefully handles cases where the inspector package is not installed,
* allowing the server to function without the inspector in production environments.
*
* @private
* @returns void
*
* @example
* If @mcp-use/inspector is installed:
* - Inspector UI available at http://localhost:PORT/inspector
* - Automatically connects to http://localhost:PORT/mcp
*
* If not installed:
* - Server continues to function normally
* - No inspector UI available
*/
private mountInspector;
/**
* Setup default widget serving routes
*
* Configures Express routes to serve MCP UI widgets and their static assets.
* Widgets are served from the dist/resources/widgets directory and can
* be accessed via HTTP endpoints for embedding in web applications.
*
* Routes created:
* - GET /mcp-use/widgets/:widget - Serves widget's index.html
* - GET /mcp-use/widgets/:widget/assets/* - Serves widget-specific assets
* - GET /mcp-use/widgets/assets/* - Fallback asset serving with auto-discovery
*
* @private
* @returns void
*
* @example
* Widget routes:
* - http://localhost:3001/mcp-use/widgets/kanban-board
* - http://localhost:3001/mcp-use/widgets/todo-list/assets/style.css
* - http://localhost:3001/mcp-use/widgets/assets/script.js (auto-discovered)
*/
private setupWidgetRoutes;
/**
* Create input schema for resource templates
*
* Parses a URI template string to extract parameter names and generates a Zod
* validation schema for those parameters. Used internally for validating resource
* template parameters before processing requests.
*
* @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
* @returns Object mapping parameter names to Zod string schemas
*
* @example
* ```typescript
* const schema = this.createInputSchema("/users/{id}/posts/{postId}")
* // Returns: { id: z.string(), postId: z.string() }
* ```
*/
private createInputSchema;
/**
* Create input schema for tools
*
* Converts tool input definitions into Zod validation schemas for runtime validation.
* Supports common data types (string, number, boolean, object, array) and optional
* parameters. Used internally when registering tools with the MCP server.
*
* @param inputs - Array of input parameter definitions with name, type, and optional flag
* @returns Object mapping parameter names to Zod validation schemas
*
* @example
* ```typescript
* const schema = this.createParamsSchema([
* { name: 'query', type: 'string', required: true, description: 'Search query' },
* { name: 'limit', type: 'number', required: false }
* ])
* // Returns: { query: z.string().describe('Search query'), limit: z.number().optional() }
* ```
*/
private createParamsSchema;
/**
* Create arguments schema for prompts
*
* Converts prompt argument definitions into Zod validation schemas for runtime validation.
* Supports common data types (string, number, boolean, object, array) and optional
* parameters. Used internally when registering prompt templates with the MCP server.
*
* @param inputs - Array of argument definitions with name, type, and optional flag
* @returns Object mapping argument names to Zod validation schemas
*
* @example
* ```typescript
* const schema = this.createPromptArgsSchema([
* { name: 'topic', type: 'string', required: true },
* { name: 'style', type: 'string', required: false }
* ])
* // Returns: { topic: z.string(), style: z.string().optional() }
* ```
*/
private createPromptArgsSchema;
/**
* Extract parameter names from URI template
*
* Parses a URI template string to extract parameter names enclosed in curly braces.
* Used internally to identify dynamic parameters in resource templates and generate
* appropriate validation schemas.
*
* @param uriTemplate - URI template string with parameter placeholders (e.g., "/users/{id}/posts/{postId}")
* @returns Array of parameter names found in the template
*
* @example
* ```typescript
* const params = this.extractTemplateParams("/users/{id}/posts/{postId}")
* // Returns: ["id", "postId"]
* ```
*/
private extractTemplateParams;
/**
* Parse parameter values from a URI based on a template
*
* Extracts parameter values from an actual URI by matching it against a URI template.
* The template contains placeholders like {param} which are extracted as key-value pairs.
*
* @param template - URI template with placeholders (e.g., "user://{userId}/posts/{postId}")
* @param uri - Actual URI to parse (e.g., "user://123/posts/456")
* @returns Object mapping parameter names to their values
*
* @example
* ```typescript
* const params = this.parseTemplateUri("user://{userId}/posts/{postId}", "user://123/posts/456")
* // Returns: { userId: "123", postId: "456" }
* ```
*/
private parseTemplateUri;
}
export type McpServerInstance = Omit<McpServer, keyof Express> & Express;
/**
* Create a new MCP server instance
*
* @param name - Server name
* @param config - Optional server configuration
* @param config.version - Server version (defaults to '1.0.0')
* @param config.description - Server description
* @param config.host - Hostname for widget URLs and server endpoints (defaults to 'localhost')
* @param config.baseUrl - Full base URL (e.g., 'https://myserver.com') - overrides host:port for widget URLs
* @returns McpServerInstance with both MCP and Express methods
*
* @example
* ```typescript
* // Basic usage
* const server = createMCPServer('my-server', {
* version: '1.0.0',
* description: 'My MCP server'
* })
*
* // With custom host (e.g., for Docker or remote access)
* const server = createMCPServer('my-server', {
* version: '1.0.0',
* host: '0.0.0.0' // or 'myserver.com'
* })
*
* // With full base URL (e.g., behind a proxy or custom domain)
* const server = createMCPServer('my-server', {
* version: '1.0.0',
* baseUrl: 'https://myserver.com' // or process.env.MCP_URL
* })
* ```
*/
export declare function createMCPServer(name: string, config?: Partial<ServerConfig>): McpServerInstance;
//# sourceMappingURL=mcp-server.d.ts.map