yao/agent/docs/mcp.md
Max ef00880960 Update Agent Documentation and MCP Tool Configuration
- Revised the API access endpoint in the agent documentation to reflect the new structure.
- Expanded examples for agent hooks, database queries, and MCP tools, providing clearer guidance for users.
- Updated MCP tool configuration to use 'label' instead of 'name' and refined transport types for better clarity.
- Introduced input schema definitions for process transport tools, enhancing the documentation on tool mapping and error handling.
2026-01-01 11:24:29 +08:00

4.9 KiB

MCP Integration

Model Context Protocol (MCP) enables tool integration with external services.

Defining MCP Servers

Create mcps/tools.mcp.yao in the assistant directory:

{
  "label": "Tools",
  "description": "Custom tools for the assistant",
  "transport": "process",
  "tools": {
    "search": "scripts.tools.Search",
    "create": "models.data.Create"
  }
}

Transport Types

Process (Yao Internal)

Map Yao Processes directly to MCP tools:

{
  "transport": "process",
  "tools": {
    "search": "models.data.Paginate",
    "create": "models.data.Create"
  },
  "resources": {
    "detail": "models.data.Find"
  }
}

STDIO (Local Server)

{
  "transport": "stdio",
  "command": "python",
  "arguments": ["mcp_server.py"],
  "env": { "API_KEY": "$ENV.API_KEY" }
}

SSE (Server-Sent Events)

{
  "transport": "sse",
  "url": "https://mcp.example.com/events",
  "authorization_token": "$ENV.TOKEN"
}

Configuring in package.yao

All Tools

{
  "mcp": {
    "servers": ["tools"]
  }
}

Specific Tools

{
  "mcp": {
    "servers": [
      { "server_id": "tools", "tools": ["search", "calculate"] }
    ]
  }
}

With Resources

{
  "mcp": {
    "servers": [
      {
        "server_id": "data",
        "tools": ["query"],
        "resources": ["data://users/*"]
      }
    ]
  }
}

Dynamic Configuration in Hooks

function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
  return {
    messages,
    mcp_servers: [
      { server_id: "tools", tools: ["search"] },
      { server_id: "data", resources: ["data://reports"] }
    ]
  };
}

Using MCP in Hooks

List Available Tools

const tools = ctx.mcp.ListTools("server-id");
// { tools: [{ name: "search", description: "...", inputSchema: {...} }] }

Call Tool

const result = ctx.mcp.CallTool("server-id", "search", {
  query: "example",
  limit: 10
});
// { content: [{ type: "text", text: "..." }] }

Batch Tool Calls

// Sequential
const results = ctx.mcp.CallTools("server-id", [
  { name: "step1", arguments: { input: "a" } },
  { name: "step2", arguments: { input: "b" } }
]);

// Parallel
const results = ctx.mcp.CallToolsParallel("server-id", [
  { name: "api1", arguments: {} },
  { name: "api2", arguments: {} }
]);

Read Resources

const resources = ctx.mcp.ListResources("server-id");
const data = ctx.mcp.ReadResource("server-id", "data://users/123");

Get Prompts

const prompts = ctx.mcp.ListPrompts("server-id");
const prompt = ctx.mcp.GetPrompt("server-id", "system", { role: "helper" });

Tool Schema Mapping

Define input schemas for process transport tools:

mcps/
└── mapping/
    └── <server-id>/
        └── schemes/
            ├── search.in.yao      # Input schema
            └── search.out.yao     # Output schema (optional)

mapping/tools/schemes/search.in.yao

{
  "type": "object",
  "description": "Search data",
  "properties": {
    "keyword": { "type": "string" },
    "page": { "type": "integer" }
  },
  "x-process-args": [":arguments"]
}

The x-process-args maps MCP arguments to Yao Process parameters:

  • ":arguments" - Pass entire arguments object
  • "$args.field" - Extract specific field

Error Handling

function Next(ctx: agent.Context, payload: agent.Payload): agent.Next {
  const { tools } = payload;

  if (tools) {
    for (const tool of tools) {
      if (tool.error) {
        ctx.trace.Error(`Tool ${tool.tool} failed: ${tool.error}`);
        // Handle error
      } else {
        // Process result
        console.log(tool.result);
      }
    }
  }

  return null;
}

Complete Example

mcps/calculator.mcp.yao

{
  "label": "Calculator",
  "description": "Math operations",
  "transport": "process",
  "tools": {
    "add": "scripts.math.Add",
    "multiply": "scripts.math.Multiply"
  }
}

package.yao

{
  "name": "Math Assistant",
  "connector": "gpt-4o",
  "mcp": {
    "servers": [
      { "server_id": "calculator", "tools": ["add", "multiply"] }
    ]
  }
}

src/index.ts

function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create {
  // Check if calculation is needed
  const query = messages[messages.length - 1]?.content || "";
  if (/\d+\s*[\+\-\*\/]\s*\d+/.test(query)) {
    // Enable calculator
    return {
      messages,
      mcp_servers: [{ server_id: "calculator" }]
    };
  }
  return { messages };
}

function Next(ctx: agent.Context, payload: agent.Payload): agent.Next {
  const { tools } = payload;

  if (tools?.length > 0) {
    const calcResult = tools.find(t => t.server === "calculator");
    if (calcResult?.result) {
      return {
        data: {
          answer: calcResult.result,
          expression: calcResult.arguments
        }
      };
    }
  }

  return null;
}