Skip to main content

VoltAgent MCP Server

Follow these steps to expose your VoltAgent project over MCP so you can browse tools, prompts, and resources from VoltOps Console (https://console.voltagent.dev/mcp) or an MCP-compatible IDE.

1. Install the MCP server package

pnpm add @voltagent/mcp-server

2. Create an MCP server instance

src/mcp/server.ts
import { MCPServer } from "@voltagent/mcp-server";

export const mcpServer = new MCPServer({
name: "voltagent-example",
version: "0.1.0",
description: "VoltAgent MCP example",
});

📘 Tip: When you expose agents through MCP, their purpose field becomes the tool description shown in clients. Keep it short and user-facing (fallback is the agent instructions if purpose is empty).

This minimal configuration:

  • Names the server voltagent-example (used in URLs and IDE listings).
  • Ships a static prompt so clients immediately see helpful metadata even before wiring runtime adapters.
  • Enables all transports (stdio, http, sse) by default. Override protocols to disable transports you do not need.
src/mcp/server.ts
export const mcpServer = new MCPServer({
name: "voltagent-example",
version: "0.1.0",
description: "VoltAgent MCP stdio example",
protocols: {
stdio: true,
http: false,
sse: false,
},
});

The snippet above shows how to run in stdio-only mode (ideal for IDE integrations or command-line tooling).

3. Register the server with VoltAgent

src/voltagent.ts
import { VoltAgent } from "@voltagent/core";
import { honoServer } from "@voltagent/server-hono";
import { mcpServer } from "./mcp/server";
import { assistant } from "./agents/assistant";
import { expenseApprovalWorkflow } from "./workflows/expense";
import { logger } from "./logger";

export const voltAgent = new VoltAgent({
agents: {
assistant,
},
workflows: {
expenseApprovalWorkflow,
},
mcpServers: {
mcpServer,
},
server: honoServer({ port: 3141 }),
logger,
});
  • mcpServers registers your MCP server alongside the agent/workflow registries.
  • Passing server: honoServer(...) makes VoltAgent expose MCP HTTP and SSE routes automatically. With the server running, visit https://console.voltagent.dev/mcp to browse, invoke, and debug tools.

4. Optional: add MCP-only entries

Sometimes you want MCP clients to see helpers that are not (yet) registered with VoltAgent. Provide them as keyed objects (just like the main VoltAgent config) via the agents, workflows, or tools fields to append entries that live only on the MCP side:

src/mcp/server.ts
import { openai } from "@ai-sdk/openai";
import { Agent, createTool, createWorkflowChain } from "@voltagent/core";
import { MCPServer } from "@voltagent/mcp-server";
import { z } from "zod";

const statusTool = createTool({
name: "status",
description: "Return the current time",
parameters: z.object({}),
async execute() {
return { status: "ok", time: new Date().toISOString() };
},
});

const supportAgent = new Agent({
name: "Support Agent",
purpose: "Route customer tickets to the correct queue.",
instructions:
"Use internal knowledge to triage customer tickets and respond with routing guidance.",
model: openai("gpt-4o-mini"),
tools: [statusTool],
});

const incidentWorkflow = createWorkflowChain({
id: "incident-triage",
name: "Incident Triage",
purpose: "Placeholder entry for an external workflow.",
input: z.object({ ticketId: z.string() }),
}).andThen({
id: "acknowledge",
execute: async ({ data }) => ({ ...data, acknowledged: true }),
});

export const mcpServer = new MCPServer({
name: "voltagent-example",
version: "0.1.0",
description: "VoltAgent MCP stdio example",
tools: {
statusTool,
},
agents: {
supportAgent,
},
workflows: {
incidentWorkflow,
},
});

These configured entries behave like regular VoltAgent components for MCP clients, they appear in listings and can be invoked-yet they are not registered with the main VoltAgent instance.

5. Optional: filter exposed agents/workflows/tools

By default, every agent, workflow, and tool registered with VoltAgent is visible to MCP clients. Provide filter functions when you need to hide or reorder the registry output for a specific transport:

src/mcp/server.ts
export const mcpServer = new MCPServer({
name: "voltagent-example",
version: "0.1.0",
description: "VoltAgent MCP stdio example",
filterAgents: ({ items }) => items.filter((agent) => agent.id !== "internal"),
filterWorkflows: ({ items }) => items,
filterTools: ({ items }) => items,
});

Filters receive the list of components sourced from the VoltAgent registries (plus any configured additions) and must return the array you want to expose. They are intended for pruning or sorting, use the agents/workflows/tools fields when you need to introduce brand-new entries.

6. Optional: stream prompts and resources

MCP clients can ask a server for structured prompt templates (prompts/list, prompts/get) and arbitrary resources (resources/list, resources/read). VoltAgent lets you seed static content and/or forward to a dynamic source via the new adapters field:

src/mcp/server.ts
import { MCPServer } from "@voltagent/mcp-server";

// Replace these placeholders with your own services or data sources
const voltOps = {
prompts: {
list: async () => [
{
name: "triage",
description: "Short ticket triage message",
arguments: [],
},
],
get: async (name: string, version?: string) => ({
description: `Prompt ${name}`,
messages: [{ role: "user", content: { type: "text", text: "Summarise ticket {{id}}" } }],
version,
}),
},
};

const knowledgeBase = {
list: async () => [
{
uri: "volt://docs/runbook",
name: "On-call runbook",
description: "Operational checklist",
mimeType: "text/markdown",
},
],
read: async (uri: string) => ({
uri,
mimeType: "text/markdown",
text: "# On-call runbook\n...",
}),
};

export const mcpServer = new MCPServer({
name: "voltagent-example",
version: "0.1.0",
description: "VoltAgent MCP with prompts/resources",
adapters: {
prompts: {
listPrompts: async () => voltOps.prompts.list(),
getPrompt: async (params) => voltOps.prompts.get(params.name, params.version),
},
resources: {
listResources: async () => knowledgeBase.list(),
readResource: async (uri) => knowledgeBase.read(uri),
},
},
});
  • The adapters block forwards MCP requests to any backend (VoltOps Prompt Manager, a documentation service, your own REST API).
  • When you change external data, call await mcpServer.notifyPromptListChanged() or await mcpServer.notifyResourceListChanged() so connected IDEs receive the standard list_changed notifications. If you update a specific resource at runtime, invoke await mcpServer.notifyResourceUpdated("volt://docs/runbook") to push an incremental update only to subscribers.
  • If an adapter provides a sendRequest method, MCP clients can make elicitation/create calls. VoltAgent forwards these requests to the adapter so you can collect data from the user and return an ElicitResult. Tools can consume the bridge via operationContext.elicitation:
const confirmAction = createTool({
name: "confirm-action",
description: "Ask the operator to approve a risky step",
parameters: z.object({ description: z.string() }),
async execute(args, operationContext) {
const handler = operationContext?.elicitation;

if (!handler) {
throw new Error("Elicitation bridge unavailable");
}

return handler({
schema: {
type: "object",
properties: {
confirmed: { type: "boolean" },
},
required: ["confirmed"],
},
message: `Approve the following action: ${args.description}`,
});
},
});

That’s it! Your VoltAgent stack now speaks MCP. Start the agent, open VoltOps Console (or your preferred MCP client), and you’ll see the server listed with its tools, prompts, resources, and workflows ready to debug.

Table of Contents