Connect your Vibes agent to Model Context Protocol servers to access external tools, data sources, and services.
The Model Context Protocol (MCP) is an open standard that lets AI agents connect to external tool servers. A Vibes agent can consume any MCP-compatible server - local subprocesses, remote HTTP services, or a fleet of both - without writing any protocol code.
MCPStdioClient and MCPHttpClient both implement the MCPClient interface. MCPToolset wraps one client and bridges it to the agent’s Toolset interface. MCPManager manages multiple MCPToolset instances and is itself a Toolset - pass it directly to an agent.
Use MCPStdioClient to launch a local subprocess that speaks MCP over stdin/stdout. This is the standard pattern for tools like @modelcontextprotocol/server-filesystem.
Copy
Ask AI
import { Agent, MCPStdioClient, MCPToolset } from "npm:@vibesjs/sdk";import { anthropic } from "npm:@ai-sdk/anthropic";const model = anthropic("claude-opus-4-5");const client = new MCPStdioClient({ command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],});await client.connect();const toolset = new MCPToolset(client);const agent = new Agent({ model, toolsets: [toolset] });try { const result = await agent.run("List files in /tmp"); console.log(result.output);} finally { await client.disconnect();}
MCPToolset wraps a single MCPClient and adapts it to the agent Toolset interface. It adds optional caching so the tool list is not re-fetched on every agent turn.
Copy
Ask AI
import { MCPToolset } from "npm:@vibesjs/sdk";const toolset = new MCPToolset(client, { toolCacheTtlMs: 30_000, // cache tool list for 30 seconds (default: 60,000) instructions: true, // pass server instructions to the agent});
When your agent needs tools from more than one MCP server, use MCPManager. It collects multiple MCPToolset instances, connects them all at once, and merges their tool lists. Because MCPManager implements Toolset, you pass it directly to the agent - no extra wrapping needed.
Common mistakes to avoid:
Do NOT pass arguments to the constructor: new MCPManager() takes no arguments.
Do NOT call manager.connectAll() - the method is manager.connect().
Do NOT call manager.toolset() - the manager itself is the toolset; pass manager directly.
Do NOT use MCPManager.fromConfig() - use the standalone createManagerFromConfig(path) function instead.
Copy
Ask AI
import { Agent, MCPHttpClient, MCPManager, MCPStdioClient,} from "npm:@vibesjs/sdk";import { anthropic } from "npm:@ai-sdk/anthropic";const model = anthropic("claude-opus-4-5");const manager = new MCPManager();manager.addServer( new MCPStdioClient({ command: "npx", args: ["-y", "@mcp/filesystem", "/data"] }), { name: "filesystem" },);manager.addServer( new MCPHttpClient({ url: "https://search-mcp.example.com/mcp" }), { name: "search" },);await manager.connect();const agent = new Agent({ model, toolsets: [manager] });try { const result = await agent.run("Search for docs and list /data/results"); console.log(result.output);} finally { await manager.disconnect();}
For production deployments, store your MCP server configuration in a JSON file and load it at startup using createManagerFromConfig. This returns a fully connected MCPManager ready to pass to your agent.
Copy
Ask AI
import { Agent, createManagerFromConfig } from "npm:@vibesjs/sdk";const manager = await createManagerFromConfig("./mcp.config.json");const agent = new Agent({ model, toolsets: [manager] });try { const result = await agent.run("List available tools and describe them."); console.log(result.output);} finally { await manager.disconnect();}
Environment variable interpolation (${ENV_VAR}) is supported in both formats.For custom setup, use loadMCPConfig and createClientsFromConfig individually:
Copy
Ask AI
import { createClientsFromConfig, loadMCPConfig, MCPManager,} from "npm:@vibesjs/sdk";const configs = await loadMCPConfig("./mcp.config.json");const clients = createClientsFromConfig(configs); // creates clients but does NOT connectconst manager = new MCPManager();for (const client of clients) { manager.addServer(client);}await manager.connect();
Always call connect() before using a client or manager. Failing to connect will cause tool calls to fail silently or throw.Always call disconnect() in a finally block to clean up subprocess-based servers. Without it, orphaned MCP server processes will continue running after your application exits.
Copy
Ask AI
const manager = new MCPManager();manager.addServer(new MCPStdioClient({ command: "npx", args: ["-y", "my-server"] }));// Must connect before useawait manager.connect();try { const agent = new Agent({ model, toolsets: [manager] }); const result = await agent.run("Do something useful"); console.log(result.output);} finally { // Always disconnect in a finally block await manager.disconnect();}