Documentation Index
Fetch the complete documentation index at: https://mcpjam-mintlify-docs-update-pr-2287-1779935284061.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
The MCPClientManager class manages connections to one or more MCP servers and provides methods to interact with their tools, resources, and prompts.
Import
import { MCPClientManager } from "@mcpjam/sdk";
Constructor
new MCPClientManager(servers: ServerConfig)
Parameters
servers
Record<string, StdioServerConfig | HttpServerConfig>
required
A map of server IDs to their configurations.
Server Configuration Types
StdioServerConfig
For subprocess-based MCP servers.
| Property | Type | Required | Description |
|---|
command | string | Yes | The command to run (e.g., "node", "python", "npx") |
args | string[] | No | Command arguments |
env | Record<string, string> | No | Environment variables for the subprocess |
{
myServer: {
command: "node",
args: ["./server.js", "--port", "3000"],
env: {
API_KEY: process.env.API_KEY,
DEBUG: "true",
},
},
}
HttpServerConfig
For remote MCP servers via SSE or Streamable HTTP.
| Property | Type | Required | Description |
|---|
url | string | Yes | The server URL (e.g., "https://mcp.example.com/sse") |
accessToken | string | No | Static bearer token added as Authorization: Bearer <token> |
requestInit | RequestInit | No | Fetch options including headers for authentication |
eventSourceInit | EventSourceInit | No | SSE-specific options |
authProvider | OAuthClientProvider | No | Custom MCP SDK OAuth provider |
refreshToken | string | No | Refresh token used for non-interactive OAuth token exchange and automatic token refresh |
clientId | string | No | OAuth client ID. Required when refreshToken is set |
clientSecret | string | No | OAuth client secret for confidential clients |
reconnectionOptions | StreamableHTTPClientTransportOptions["reconnectionOptions"] | No | Streamable HTTP reconnection behavior |
sessionId | string | No | Existing Streamable HTTP session ID |
preferSSE | boolean | No | Forces SSE instead of Streamable HTTP |
{
remoteServer: {
url: "https://mcp.asana.com/sse",
requestInit: {
headers: {
Authorization: "Bearer YOUR_TOKEN",
"X-Custom-Header": "value",
},
},
},
}
Refresh Token Example
{
remoteServer: {
url: "https://mcp.example.com/mcp",
refreshToken: process.env.MCP_REFRESH_TOKEN!,
clientId: process.env.MCP_CLIENT_ID!,
clientSecret: process.env.MCP_CLIENT_SECRET,
},
}
When refreshToken is provided, the SDK will exchange it for an access token during connection and automatically refresh tokens if the server challenges the current token.
refreshToken is mutually exclusive with accessToken, authProvider, and requestInit.headers.Authorization.
Example
const manager = new MCPClientManager({
// STDIO server
local: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-everything"],
},
// HTTP server
remote: {
url: "https://mcp.example.com/sse",
requestInit: {
headers: { Authorization: "Bearer token" },
},
},
});
Methods
connectToServer()
Establishes a connection to a configured server.
connectToServer(serverId: string): Promise<Client>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID from the constructor config |
Returns
Promise<Client> - Resolves with the connected MCP client, rejects on failure.
Example
await manager.connectToServer("myServer");
Throws
- Error if
serverId is not in the configuration
- Error if connection fails (network, subprocess spawn, etc.)
disconnectServer()
Closes the connection to a server and cleans up resources.
disconnectServer(serverId: string): Promise<void>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID to disconnect |
Returns
Promise<void>
Example
await manager.disconnectServer("myServer");
pingServer()
Sends a ping to check if a server is responsive.
pingServer(serverId: string): void
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID to ping |
Returns
void - This method is synchronous and does not return a value.
Throws
- Error if the server is not connected
- Error if the ping fails
Example
try {
manager.pingServer("myServer");
console.log("Server is responsive");
} catch (error) {
console.warn("Server not responding:", error.message);
}
Returns all tools available on a server.
listTools(serverId: string): Promise<{ tools: Tool[] }>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
Returns
Promise<{ tools: Tool[] }> - Tool list response from the server.
| Property | Type | Description |
|---|
name | string | Tool identifier |
description | string | Human-readable description |
inputSchema | object | JSON Schema for tool arguments |
Example
const tools = await manager.listTools("myServer");
for (const tool of tools.tools) {
console.log(`${tool.name}: ${tool.description}`);
}
Executes a tool and returns the result.
executeTool(
serverId: string,
toolName: string,
args: Record<string, unknown>
): Promise<unknown>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
toolName | string | Name of the tool to execute |
args | Record<string, unknown> | Arguments to pass to the tool |
Returns
Promise<unknown> - The tool’s return value (type depends on the tool).
Example
const result = await manager.executeTool("myServer", "add", {
a: 5,
b: 3,
});
console.log(result); // 8
Throws
- Error if tool doesn’t exist
- Error if arguments are invalid
- Error if tool execution fails
listResources()
Returns all resources available on a server.
listResources(serverId: string): Promise<Resource[]>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
Returns
Promise<Resource[]> - Array of resource definitions.
Resource Object
| Property | Type | Description |
|---|
name | string | Resource identifier |
uri | string | Resource URI |
description | string | Human-readable description |
mimeType | string | Content type |
Example
const resources = await manager.listResources("myServer");
for (const resource of resources) {
console.log(`${resource.name}: ${resource.uri}`);
}
readResource()
Reads the content of a resource.
readResource(
serverId: string,
params: { uri: string }
): Promise<ResourceContent>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
params.uri | string | The resource URI to read |
Returns
Promise<ResourceContent> - The resource content.
Example
const content = await manager.readResource("myServer", {
uri: "file://config.json",
});
console.log(content);
listPrompts()
Returns all prompts available on a server.
listPrompts(serverId: string): Promise<Prompt[]>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
Returns
Promise<Prompt[]> - Array of prompt definitions.
Prompt Object
| Property | Type | Description |
|---|
name | string | Prompt identifier |
description | string | Human-readable description |
arguments | PromptArgument[] | Expected arguments |
Example
const prompts = await manager.listPrompts("myServer");
for (const prompt of prompts) {
console.log(`${prompt.name}: ${prompt.description}`);
}
getPrompt()
Gets a prompt with optional arguments.
getPrompt(
serverId: string,
params: { name: string; arguments?: Record<string, string> }
): Promise<PromptResult>
Parameters
| Parameter | Type | Description |
|---|
serverId | string | The server ID |
params.name | string | The prompt name |
params.arguments | Record<string, string> | Optional prompt arguments |
Returns
Promise<PromptResult> - The prompt content with messages.
Example
const prompt = await manager.getPrompt("myServer", {
name: "summarize",
arguments: { length: "short" },
});
console.log(prompt.messages);
Returns all tools from specified servers or all connected servers.
getTools(serverIds?: string[]): Promise<Tool[]>
Parameters
| Parameter | Type | Description |
|---|
serverIds | string[] | Optional. Array of server IDs to fetch tools from. If omitted, returns tools from all connected servers. |
Returns
Promise<Tool[]> - Array of tool definitions from all specified servers.
Each tool in the returned array includes:
| Property | Type | Description |
|---|
name | string | Tool identifier |
description | string | Human-readable description |
inputSchema | object | JSON Schema for tool arguments |
execute | function | Function to execute the tool with arguments |
Example
// Tools from specific servers
const tools = await manager.getTools(["myServer", "anotherServer"]);
// Tools from all connected servers
const allTools = await manager.getTools();
for (const tool of allTools) {
console.log(`${tool.name}: ${tool.description}`);
}
// Use with TestAgent
const agent = new TestAgent({
tools: await manager.getTools(),
model: "anthropic/claude-sonnet-4-20250514",
apiKey: process.env.ANTHROPIC_API_KEY,
});
const result = await agent.prompt("Add 2 and 3");
console.log(result.getText());
getTools() returns all tools including app-only ones. Tools with _meta.ui.visibility = ["app"] are filtered out by getToolsForAiSdk() per SEP-1865 before being passed to the model. These tools remain callable by apps via the MCP bridge.
Returns tools in Vercel AI SDK format, ready to pass directly to generateText() or streamText(). App-only tools are filtered out by default per SEP-1865.
getToolsForAiSdk(
serverIds?: string[] | string,
options?: {
schemas?: ToolSchemaOverrides | "automatic";
needsApproval?: boolean;
includeAppOnly?: boolean;
}
): Promise<ToolSet>
Parameters
| Parameter | Type | Description |
|---|
serverIds | string[] | string | Optional. Server IDs to include. If omitted, uses all connected servers. |
options.schemas | ToolSchemaOverrides | "automatic" | Optional. Control JSON schema conversion. |
options.needsApproval | boolean | Optional. When true, each tool call requires user approval before execution. |
options.includeAppOnly | boolean | Optional. When true, includes tools with _meta.ui.visibility = ["app"] in the returned set. Defaults to false (spec-compliant). Use only when intentionally mirroring a host that does not implement SEP-1865 visibility filtering. |
Returns
Promise<ToolSet> - Tools in Vercel AI SDK format with execution wired up.
Example
// Default: app-only tools are excluded (spec-compliant)
const tools = await manager.getToolsForAiSdk(["myServer"]);
// Include app-only tools (e.g. to mirror a non-filtering host)
const allTools = await manager.getToolsForAiSdk(["myServer"], {
includeAppOnly: true,
});
// Use directly with Vercel AI SDK
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
const response = await generateText({
model: openai("gpt-4o"),
tools: await manager.getToolsForAiSdk(),
messages: [{ role: "user", content: "Add 5 and 7" }],
});
Complete Example
import { MCPClientManager, TestAgent } from "@mcpjam/sdk";
async function main() {
const manager = new MCPClientManager({
math: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-everything"],
},
asana: {
url: "https://mcp.asana.com/sse",
requestInit: {
headers: { Authorization: `Bearer ${process.env.ASANA_TOKEN}` },
},
},
});
try {
// Connect
await manager.connectToServer("math");
await manager.connectToServer("asana");
// Direct tool execution
const sum = await manager.executeTool("math", "add", { a: 10, b: 5 });
console.log("Sum:", sum);
// List capabilities
const mathTools = await manager.listTools("math");
const asanaTools = await manager.listTools("asana");
console.log("Math tools:", mathTools.tools.length);
console.log("Asana tools:", asanaTools.tools.length);
// Create agent with all tools
const agent = new TestAgent({
tools: await manager.getTools(),
model: "anthropic/claude-sonnet-4-20250514",
apiKey: process.env.ANTHROPIC_API_KEY,
});
const result = await agent.prompt("Add 2 and 3");
console.log(result.getText());
} finally {
await manager.disconnectServer("math");
await manager.disconnectServer("asana");
}
}