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
- npm
- yarn
pnpm add @voltagent/mcp-server
npm install @voltagent/mcp-server
yarn add @voltagent/mcp-server
2. Create an MCP server instance
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 ifpurpose
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. Overrideprotocols
to disable transports you do not need.
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
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, visithttps://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:
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:
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:
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()
orawait mcpServer.notifyResourceListChanged()
so connected IDEs receive the standardlist_changed
notifications. If you update a specific resource at runtime, invokeawait mcpServer.notifyResourceUpdated("volt://docs/runbook")
to push an incremental update only to subscribers. - If an adapter provides a
sendRequest
method, MCP clients can makeelicitation/create
calls. VoltAgent forwards these requests to the adapter so you can collect data from the user and return anElicitResult
. Tools can consume the bridge viaoperationContext.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.