Documentation Index
Fetch the complete documentation index at: https://mintlify.com/lvndry/jazz/llms.txt
Use this file to discover all available pages before exploring further.
MCP (Model Context Protocol) tools enable Jazz agents to connect to MCP servers and use their exposed tools seamlessly.
Overview
The MCP integration provides:
- Lazy connection: Servers connect automatically when their tools are first used
- Tool adaptation: MCP tools are automatically adapted to Jazz’s tool interface
- Schema conversion: MCP JSON schemas are converted to Zod for validation
- Error handling: Comprehensive error handling with tagged errors
MCP tools are prefixed with the server name to avoid conflicts:
// MCP server: mongodb
// MCP tool: aggregate
// Jazz tool: mcp_mongodb_aggregate
// MCP server: filesystem
// MCP tool: read_file
// Jazz tool: mcp_filesystem_read_file
Registration
MCP tools are registered using the registerMCPServerTools function:
import { registerMCPServerTools } from "@/core/agent/tools/mcp-tools";
const serverConfig = {
name: "mongodb",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-mongodb"],
env: {
MONGODB_URI: "mongodb://localhost:27017",
},
};
// Get MCP tools from server
const mcpTools = yield* mcpManager.getServerTools("mongodb");
// Register as Jazz tools
const jazzTools = yield* registerMCPServerTools(serverConfig, mcpTools);
for (const tool of jazzTools) {
yield* registerTool(tool);
}
Lazy connection
MCP servers connect lazily when their tools are first used:
// Server not connected yet
const isConnected1 = yield* mcpManager.isConnected("mongodb");
// false
// Use an MCP tool
const result = yield* mcpMongodbAggregate.handler(
{
collection: "users",
pipeline: [{ $match: { active: true } }],
},
context
);
// Server now connected
const isConnected2 = yield* mcpManager.isConnected("mongodb");
// true
The connection process:
- Check if server is connected
- If not, show connection progress to user
- Connect to server
- Show success message
- Execute tool
Schema conversion
MCP JSON schemas are automatically converted to Zod:
// MCP tool schema
{
"inputSchema": {
"type": "object",
"properties": {
"collection": {
"type": "string",
"description": "Collection name"
},
"pipeline": {
"type": "array",
"items": { "type": "object" }
}
},
"required": ["collection", "pipeline"]
}
}
// Converted to Zod
z.object({
collection: z.string().describe("Collection name"),
pipeline: z.array(z.record(z.unknown()))
}).required();
Supported schema types:
string, number, integer, boolean
object, array
null, any
enum, const
oneOf, anyOf, allOf
- Pattern validation
- Min/max constraints
Unsupported schemas:
If a schema cannot be converted, it defaults to an empty object schema to maintain LLM compatibility:
// Invalid/unsupported schema
z.object({})
Error handling
MCP tools use tagged errors for structured error reporting:
Thrown when tool execution fails:
export class MCPToolExecutionError extends Data.TaggedError(
"MCPToolExecutionError"
)<{
readonly serverName: string;
readonly toolName: string;
readonly reason: string;
readonly cause?: unknown;
readonly suggestion?: string;
}> {}
Example:
const result = yield* mcpTool.handler(args, context);
if (!result.success) {
// Error format
{
success: false,
result: null,
error: "MCP tool execution failed: Connection refused"
}
}
{
success: false,
result: null,
error: "Tool aggregate not found in MCP server mongodb. Available tools: find, insert, update"
}
Server connection failed
{
success: false,
result: null,
error: "Failed to connect to MCP server: ENOENT: npx not found"
}
MCP tools execute through the executeMCPToolWithLazyConnection function:
function executeMCPToolWithLazyConnection(
serverConfig: MCPServerConfig,
toolName: string,
args: Record<string, unknown>,
context: ToolExecutionContext
): Effect.Effect<ToolExecutionResult, Error, MCPToolDependencies>
Execution flow:
- Check server connection status
- Connect if needed (lazy connection)
- Get server tools
- Find requested tool
- Execute tool with arguments
- Handle MCP result format
- Return Jazz result
MCP tools return results in a specific format:
{
content: unknown, // Tool result data
isError?: boolean // Whether result is an error
}
Success result:
{
content: { data: [...] }
}
Error result:
{
content: "Database connection failed",
isError: true
}
Configuration
MCP servers are configured in Jazz settings:
{
"mcp": {
"servers": {
"mongodb": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-mongodb"],
"env": {
"MONGODB_URI": "mongodb://localhost:27017"
}
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "~/Documents"]
}
}
}
}
Server lifecycle
Connection
const mcpManager = yield* MCPServerManagerTag;
const result = yield* mcpManager.connectServer(serverConfig);
// Server process started
// Tools registered
Disconnection
yield* mcpManager.disconnectServer("mongodb");
// Server process terminated
// Tools unregistered
Status check
const isConnected = yield* mcpManager.isConnected("mongodb");
// true or false
List servers
const servers = yield* mcpManager.listServers();
// [{ name: "mongodb", connected: true, toolCount: 5 }, ...]
Best practices
Use descriptive server names
// Good: Clear server purpose
{
name: "mongodb_production",
command: "npx",
args: [...]
}
// Bad: Generic name
{
name: "db",
command: "npx",
args: [...]
}
{
name: "mongodb",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-mongodb"],
env: {
MONGODB_URI: process.env.MONGODB_URI,
MONGODB_DB: "myapp",
MONGODB_TIMEOUT: "5000"
}
}
Handle connection errors gracefully
const result = yield* mcpTool.handler(args, context).pipe(
Effect.catchAll((error) =>
Effect.gen(function* () {
yield* logger.error(`MCP tool failed: ${error.message}`);
// Fallback behavior
return { success: false, result: null, error: error.message };
})
)
);
MCP tools use Zod validation automatically:
const result = yield* mcpTool.handler(
{
collection: "users",
pipeline: [{ $match: { active: true } }],
// Invalid argument will be caught by Zod
},
context
);
Monitor server health
const servers = yield* mcpManager.listServers();
for (const server of servers) {
if (!server.connected) {
yield* logger.warn(`MCP server ${server.name} is disconnected`);
// Attempt reconnection
yield* mcpManager.connectServer(serverConfig);
}
}
Common MCP servers
MongoDB
{
"name": "mongodb",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-mongodb"],
"env": {
"MONGODB_URI": "mongodb://localhost:27017"
}
}
Tools: find, insert, update, delete, aggregate
Filesystem
{
"name": "filesystem",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/allowed/dir"]
}
Tools: read_file, write_file, list_directory, move_file, search_files
PostgreSQL
{
"name": "postgres",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"PGHOST": "localhost",
"PGPORT": "5432",
"PGDATABASE": "mydb",
"PGUSER": "user",
"PGPASSWORD": "password"
}
}
Tools: query, list_tables, describe_table, insert, update
GitHub
{
"name": "github",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_TOKEN": "ghp_..."
}
}
Tools: create_issue, list_issues, create_pull_request, search_repositories
Example usage
import { registerMCPServerTools } from "@/core/agent/tools/mcp-tools";
// Configure MongoDB MCP server
const mongoConfig = {
name: "mongodb",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-mongodb"],
env: {
MONGODB_URI: "mongodb://localhost:27017",
},
};
// Register tools
const mcpManager = yield* MCPServerManagerTag;
const mcpTools = yield* mcpManager.getServerTools("mongodb");
const jazzTools = yield* registerMCPServerTools(mongoConfig, mcpTools);
for (const tool of jazzTools) {
yield* registerTool(tool);
}
// Use MCP tool (server connects automatically)
const result = yield* mcpMongodbAggregate.handler(
{
collection: "users",
pipeline: [
{ $match: { active: true } },
{ $group: { _id: "$country", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
],
},
context
);
if (result.success) {
console.log("Aggregation results:", result.result.content);
}