Advanced
MCP tools
Connect external MCP servers and adapt MCP tools for agents.
MCP connects external tool servers to Anvia agents. Use it when tools are provided by an MCP server rather than local application code.
Core can connect to stdio, HTTP, or SSE MCP servers, list their tools, adapt them to Anvia Tool objects, and register them on an agent.
Connect A Server
import { AgentBuilder } from "@anvia/core";
import { connectMcp, mcp } from "@anvia/core/mcp";
const filesystem = await connectMcp(
mcp.stdio({
name: "filesystem",
command: "npx",
args: ["@modelcontextprotocol/server-filesystem", "/workspace/docs"],
}),
);
The returned server has a name, a list of adapted tools, and a close() method.
try {
const agent = new AgentBuilder("docs-operator", model)
.instructions("Use filesystem tools only for documentation files.")
.mcp([filesystem])
.build();
const response = await agent.prompt("List the docs files.").send();
} finally {
await filesystem.close();
}
Keep server lifecycle explicit. Long-running apps can connect during startup and close during shutdown. Short-lived jobs can connect inside the job and close in finally.
The lower-level MCP contracts are also exported for adapters and tests:
McpConnectiondescribes something that can connect and return a clientMcpClientexposeslistTools(),callTool(...), andclose()McpServeris the connected Anvia-facing server with adapted toolsMcpStdioOptions,McpHttpOptions, andMcpSseOptionstype the built-in connection helpers
HTTP And SSE
Use HTTP or SSE when the server is remote:
const crm = await connectMcp(
mcp.http({
name: "crm",
url: "https://internal.example.com/mcp",
}),
);
const events = await connectMcp(
mcp.sse({
name: "events",
url: "https://internal.example.com/mcp/sse",
}),
);
Remote MCP servers are privileged dependencies. Keep credentials, network access, and tenant routing on the server side.
Result Mapping
MCP text results become text tool results. MCP image results become data URLs. MCP resources are serialized with their URI and content. MCP isError results throw an error with the returned text when available.
If a server returns { toolResult }, core serializes that value to a string unless it is already a string.
MCP tool arguments must be JSON objects. If a model or wrapper passes null, undefined, or a non-object argument payload, core maps it before calling the MCP client or throws before the remote server is invoked.
Trust Boundaries
Treat MCP tools like any other tool:
- the agent can request them when their definitions are exposed
- the MCP server owns its own permission checks
- your runner still owns user and tenant authorization
- browser code should not connect directly to privileged MCP servers
- tool results should be filtered before reaching users
If an MCP server exposes broad file, shell, database, or network access, wrap it in application policy or run it in a constrained environment.
MCP With Local Tools
MCP tools can be combined with local tools:
const agent = new AgentBuilder("ops", model)
.tools([createIncidentTool(scope)])
.mcp([filesystem, crm])
.build();
Use local tools for product-specific permissions and side effects. Use MCP tools for external capabilities that are already provided by an MCP server.
Observability
MCP-adapted tools carry server metadata internally. Observers can see the MCP server name in tool metadata. This helps distinguish local tools from tools imported from external MCP servers.
MCP Checklist
Before shipping MCP tools, check:
- server credentials stay server-side
- server lifecycle is closed on shutdown or job completion
- exposed tools are appropriate for the agent role
- MCP results are safe for model context
- product permissions are enforced outside prompt text
- remote MCP failures are mapped to safe user-facing errors
