Skip to main content

API Reference

Complete API documentation for mcp-ts.

Server-Side API

createNextMcpHandler(options)

Creates handlers for Next.js App Router API routes.

import { createNextMcpHandler } from '@mcp-ts/sdk/server';

const { GET, POST } = createNextMcpHandler({
getIdentity: (request) => string,
getAuthToken?: (request) => string | null,
authenticate?: (identity, token) => Promise<boolean>,
heartbeatInterval?: number,
});

Options:

  • getIdentity - Function to extract identity from request (required)
  • getAuthToken - Function to extract auth token from request (optional)
  • authenticate - Custom authentication logic (optional)
  • heartbeatInterval - SSE heartbeat interval in ms (default: 30000)
  • clientDefaults - Static OAuth client metadata (optional)
  • getClientMetadata - Dynamic OAuth metadata getter (optional, overrides defaults)

Returns: { GET, POST } - HTTP method handlers


createSSEHandler(options)

Creates an SSE handler for standard Node.js/Express applications.

import { createSSEHandler } from '@mcp-ts/sdk/server';

const handler = createSSEHandler({
identity: string,
onAuth?: (identity) => Promise<boolean>,
heartbeatInterval?: number,
});

Options:

  • identity - User/Client identifier (required)
  • onAuth - Authentication callback (optional)
  • heartbeatInterval - Heartbeat interval in ms (default: 30000)
  • clientDefaults - Static OAuth client metadata (optional)
  • getClientMetadata - Dynamic OAuth metadata getter (optional)

Returns: Request handler function


MCPClient

Direct MCP client class for server-side operations.

import { MCPClient } from '@mcp-ts/sdk/server';

const client = new MCPClient({
identity: string,
sessionId: string,
serverId?: string,
serverUrl?: string,
callbackUrl?: string,
transportType?: 'sse' | 'streamable_http',
onRedirect?: (authUrl: string) => void,
// OAuth Metadata
clientName?: string,
clientUri?: string,
logoUri?: string,
policyUri?: string,
});

Methods

connect(): Promise<void>

Connect to the MCP server. May throw UnauthorizedError if OAuth is required.

await client.connect();

disconnect(): Promise<void>

Disconnect from the MCP server.

await client.disconnect();

listTools(): Promise<ListToolsResult>

List available tools from the MCP server.

const { tools } = await client.listTools();

callTool(name: string, args: object): Promise<CallToolResult>

Call a tool with arguments.

const result = await client.callTool('get_weather', {
location: 'San Francisco',
});

getAITools(): Promise<ToolSet>

Get all MCP tools and convert them to AI SDK compatible tools.

const tools = await client.getAITools();

listPrompts(): Promise<ListPromptsResult>

List available prompts.

const { prompts } = await client.listPrompts();

getPrompt(name: string, args?: object): Promise<GetPromptResult>

Get a prompt with optional arguments.

const prompt = await client.getPrompt('code-review', {
language: 'typescript',
});

listResources(): Promise<ListResourcesResult>

List available resources.

const { resources } = await client.listResources();

readResource(uri: string): Promise<ReadResourceResult>

Read a specific resource by URI.

const resource = await client.readResource('file:///path/to/file');

finishAuth(code: string): Promise<void>

Complete OAuth authorization with authorization code.

await client.finishAuth(authCode);

MultiSessionClient

Manages multiple MCP connections for a single user identity, allowing aggregation of tools from all connected servers.

import { MultiSessionClient } from '@mcp-ts/sdk/server';

const mcp = new MultiSessionClient(identity, {
timeout: 15000,
maxRetries: 2,
retryDelay: 1000,
});

Options:

  • timeout - Connection timeout in milliseconds (default: 15000)
  • maxRetries - Maximum number of retry attempts for each session (default: 2)
  • retryDelay - Delay between retries in milliseconds (default: 1000)

Methods

connect(): Promise<void>

Connects to all active sessions for the user. Skips sessions that fail to connect after retries, but logs errors.

await mcp.connect();

getClients(): MCPClient[]

Returns the array of currently connected clients.

const clients = mcp.getClients();

disconnect(): void

Disconnects all active clients and clears the internal client list.

mcp.disconnect();

Adapters

Adapters convert MCP tools into framework-specific formats for seamless integration with AI frameworks.

AIAdapter

Convert MCP tools to Vercel AI SDK format.

import { AIAdapter } from '@mcp-ts/sdk/adapters/ai';

const adapter = new AIAdapter(client: MCPClient | MultiSessionClient, options?: {
prefix?: string // Tool name prefix (default: serverId)
});

const tools = await adapter.getTools(); // Returns ToolSet

LangChainAdapter

Convert MCP tools to LangChain DynamicStructuredTool format.

import { LangChainAdapter } from '@mcp-ts/sdk/adapters/langchain';

const adapter = new LangChainAdapter(client: MCPClient | MultiSessionClient, options?: {
prefix?: string // Tool name prefix
simplifyErrors?: boolean // Return simple error strings (default: false)
});

const tools = await adapter.getTools(); // Returns DynamicStructuredTool[]

MastraAdapter

Convert MCP tools to Mastra tool format.

import { MastraAdapter } from '@mcp-ts/sdk/adapters/mastra';

const adapter = new MastraAdapter(client: MCPClient | MultiSessionClient, options?: {
prefix?: string // Tool name prefix
});

const tools = await adapter.getTools(); // Returns MastraTool[]

AguiAdapter

Convert MCP tools to AG-UI protocol format.

import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';

const adapter = new AguiAdapter(client: MCPClient | MultiSessionClient, options?: {
prefix?: string // Tool name prefix (default: serverId)
});

// Get tools with handlers for server-side execution
const tools = await adapter.getTools(); // Returns AguiTool[]

// Get tool definitions (JSON Schema) for remote agents
const definitions = await adapter.getToolDefinitions(); // Returns AguiToolDefinition[]

Types:

interface AguiTool {
name: string;
description: string;
parameters?: Record<string, any>;
handler?: (args: any) => any | Promise<any>;
}

interface AguiToolDefinition {
name: string;
description: string;
parameters: Record<string, any>;
}

createMcpMiddleware

Create AG-UI middleware for server-side MCP tool execution.

import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
import { HttpAgent } from '@ag-ui/client';

const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });

agent.use(createMcpMiddleware(client: MCPClient | MultiSessionClient, options?: {
toolPrefix?: string // Prefix to identify MCP tools (default: 'server-')
tools?: AguiTool[] // Pre-loaded tools with handlers
}));

Parameters:

  • client - MCP client or MultiSessionClient for executing tools
  • options.toolPrefix - Prefix to identify MCP tools in the event stream (default: 'server-')
  • options.tools - Pre-loaded tools with handlers. If not provided, tools will be loaded from the client on first use.

Returns: Middleware function compatible with AG-UI agent.use()

Example:

import { HttpAgent } from '@ag-ui/client';
import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';
import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';

// Setup
const client = new MultiSessionClient('user_123');
await client.connect();

const adapter = new AguiAdapter(client);
const mcpTools = await adapter.getTools();

// Create agent with middleware
const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
agent.use(createMcpMiddleware(client, {
toolPrefix: 'server-',
tools: mcpTools,
}));

Storage Backend API

storage

Global storage instance that automatically selects the appropriate backend based on environment configuration.

import { storage } from '@mcp-ts/sdk/server';

Configuration

The storage backend is selected automatically:

# Redis (Production)
MCP_TS_STORAGE_TYPE=redis
REDIS_URL=redis://localhost:6379

# File System (Development)
MCP_TS_STORAGE_TYPE=file
MCP_TS_STORAGE_FILE=./sessions.json

# In-Memory (Testing - Default)
MCP_TS_STORAGE_TYPE=memory

Storage Methods

generateSessionId(): string

Generate a unique session ID.

const sessionId = storage.generateSessionId();

createSession(session: SessionData): Promise<void>

Create a new session. Throws if session already exists.

await storage.createSession({
sessionId: 'abc123',
identity: 'user-123',
serverId: 'server-id',
serverName: 'My Server',
serverUrl: 'https://mcp.example.com',
callbackUrl: 'https://myapp.com/callback',
transportType: 'sse',
active: true,
createdAt: Date.now(),
});

updateSession(identity: string, sessionId: string, data: Partial<SessionData>): Promise<void>

Update an existing session with partial data. Throws if session doesn't exist.

await storage.updateSession('user-123', 'abc123', {
active: false,
tokens: {
access_token: 'new-token',
token_type: 'Bearer',
},
});

getSession(identity: string, sessionId: string): Promise<SessionData | null>

Retrieve session data.

const session = await storage.getSession('user-123', 'abc123');

getIdentitySessionsData(identity: string): Promise<SessionData[]>

Get all session data for an identity.

const sessions = await storage.getIdentitySessionsData('user-123');

getIdentityMcpSessions(identity: string): Promise<string[]>

Get all session IDs for an identity.

const sessionIds = await storage.getIdentityMcpSessions('user-123');

removeSession(identity: string, sessionId: string): Promise<void>

Delete a session.

await storage.removeSession('user-123', 'abc123');

getAllSessionIds(): Promise<string[]>

Get all session IDs across all users (admin operation).

const allSessions = await storage.getAllSessionIds();

clearAll(): Promise<void>

Clear all sessions (admin operation).

await storage.clearAll();

cleanupExpiredSessions(): Promise<void>

Clean up expired sessions (Redis only, no-op for others).

await storage.cleanupExpiredSessions();

disconnect(): Promise<void>

Disconnect from storage backend.

await storage.disconnect();

Custom Storage Backends

You can also use specific storage backends directly:

import { 
RedisStorageBackend,
MemoryStorageBackend,
FileStorageBackend
} from '@mcp-ts/sdk/server';
import { Redis } from 'ioredis';

// Redis
const redis = new Redis(process.env.REDIS_URL);
const redisStorage = new RedisStorageBackend(redis);

// File System
const fileStorage = new FileStorageBackend({ path: './sessions.json' });
await fileStorage.init();

// In-Memory
const memoryStorage = new MemoryStorageBackend();

Client-Side API

useMcp(options)

React hook for managing MCP connections.

import { useMcp } from '@mcp-ts/sdk/client';

const {
connections,
status,
isInitializing,
connect,
disconnect,
refresh,
connectSSE,
disconnectSSE,
finishAuth,
callTool,
listTools,
listPrompts,
getPrompt,
listResources,
readResource,
getConnection,
getConnectionByServerId,
isServerConnected,
getTools,
} = useMcp({
url: string,
identity: string,
authToken?: string,
autoConnect?: boolean,
autoInitialize?: boolean,
onConnectionEvent?: (event) => void,
onLog?: (level, message, metadata) => void,
});

Options:

  • url - SSE endpoint URL (required)
  • identity - User/Client identifier (required)
  • authToken - Authentication token (optional)
  • autoConnect - Auto-connect SSE on mount (default: true)
  • autoInitialize - Auto-load sessions on mount (default: true)
  • onConnectionEvent - Connection event handler (optional)
  • onLog - Debug log handler (optional)

Returns: Object with state and methods


useMcpApps(mcpClient)

React hook for rendering MCP Apps - interactive UI components from MCP servers.

import { useMcpApps } from '@mcp-ts/sdk/client/react';

const { getAppMetadata, McpAppRenderer } = useMcpApps(mcpClient);

Parameters:

  • mcpClient - The MCP client from useMcp() or context (required)

Returns:

  • getAppMetadata(toolName: string) - Function to look up MCP app metadata by tool name
  • McpAppRenderer - React component for rendering MCP apps

getAppMetadata(toolName: string)

Looks up MCP app metadata for a given tool name. Automatically handles tool name prefixes (e.g., tool_abc123_get-timeget-time).

Returns: McpAppMetadata | undefined

interface McpAppMetadata {
toolName: string; // Base tool name
resourceUri: string; // MCP resource URI for the app UI
sessionId: string; // Session ID for the MCP connection
}

McpAppRenderer Component

Stable, memoized component for rendering MCP apps. Prevents iframe flickering by maintaining component identity across renders.

Props:

interface McpAppRendererProps {
metadata: McpAppMetadata; // Stable metadata from getAppMetadata
input?: Record<string, unknown>; // Tool arguments
result?: unknown; // Tool execution result
status: 'executing' | 'inProgress' | 'complete' | 'idle';
className?: string; // Custom CSS classes for container
}

Example:

import { useMcpApps } from '@mcp-ts/sdk/client/react';

function ToolCallRenderer({ name, args, result, status }) {
const { mcpClient } = useMcpContext();
const { getAppMetadata, McpAppRenderer } = useMcpApps(mcpClient);

const metadata = getAppMetadata(name);

if (!metadata) return null;

return (
<McpAppRenderer
metadata={metadata}
input={args}
result={result}
status={status}
className="my-custom-class"
/>
);
}

SSEClient

Lower-level SSE client for custom implementations.

import { SSEClient } from '@mcp-ts/sdk/client';

const client = new SSEClient({
url: string,
identity: string,
authToken?: string,
onConnectionEvent?: (event) => void,
onStatusChange?: (status) => void,
onLog?: (level, message, metadata) => void,
});

Methods

connect(): void

Connect to the SSE endpoint.

client.connect();

disconnect(): void

Disconnect from the SSE endpoint.

client.disconnect();

getSessions(): Promise<Session[]>

Get all user sessions.

const sessions = await client.getSessions();

connectToServer(config): Promise<{ sessionId: string }>

Connect to an MCP server.

const { sessionId } = await client.connectToServer({
serverId: 'server-id',
serverName: 'My Server',
serverUrl: 'https://mcp.example.com',
callbackUrl: window.location.origin + '/callback',
});

disconnectFromServer(sessionId: string): Promise<void>

Disconnect from an MCP server.

await client.disconnectFromServer(sessionId);

callTool(sessionId, name, args): Promise<any>

Call a tool on a connected server.

const result = await client.callTool(sessionId, 'tool_name', {
arg1: 'value',
});

listTools(sessionId): Promise<Tool[]>

List tools for a session.

const tools = await client.listTools(sessionId);

Types

Connection Types

import type {
McpConnectionState,
McpConnectionEvent,
} from '@mcp-ts/sdk/shared';

type McpConnectionState =
| 'DISCONNECTED'
| 'CONNECTING'
| 'AUTHENTICATING'
| 'AUTHENTICATED'
| 'DISCOVERING'
| 'CONNECTED'
| 'VALIDATING'
| 'RECONNECTING'
| 'FAILED';

type McpConnectionEvent =
| { type: 'state_changed'; sessionId: string; state: McpConnectionState; ... }
| { type: 'tools_discovered'; sessionId: string; tools: Tool[]; ... }
| { type: 'auth_required'; sessionId: string; authUrl: string; ... }
| { type: 'error'; sessionId: string; error: string; ... }
| { type: 'disconnected'; sessionId: string; reason?: string; ... }
| { type: 'progress'; sessionId: string; message: string; ... };

Tool Types

import type { ToolInfo } from '@mcp-ts/sdk/shared';

interface ToolInfo {
name: string;
description?: string;
inputSchema: {
type: 'object';
properties?: Record<string, any>;
required?: string[];
};
}

Session Types

interface SessionData {
sessionId: string;
identity?: string;
serverId?: string;
serverName?: string;
serverUrl: string;
callbackUrl: string;
transportType: 'sse' | 'streamable_http';
active: boolean;
createdAt: number;
headers?: Record<string, string>;
// OAuth data
tokens?: OAuthTokens;
clientInformation?: OAuthClientInformation;
codeVerifier?: string;
clientId?: string;
}

Error Handling

UnauthorizedError

Thrown when OAuth authorization is required.

import { UnauthorizedError } from '@mcp-ts/sdk/server';

try {
await client.connect();
} catch (error) {
if (error instanceof UnauthorizedError) {
console.log('Redirect to:', error.authUrl);
}
}

Next Steps