跳到正文

DOCS

MCP

Backend 与 frontend tools 在同一回合。Host MCP 为 mint 后的 Bearer HTTP。

MCP

Backend 与 frontend tools 在同一回合。Host MCP 为 mint 后的 Bearer HTTP。

Builtin tools、客户端注册、通过 embed 握手的 host MCP。

Builtin tools

Names and descriptions from ToolSpec in the agent runtime. search_code and read_code_file are advertised when a workspace index is attached. spawn_tasks fans independent work; it needs a host MCP (or in-memory) backend to resolve subagents.

search_code

Search the local workspace code index with keyword and embedding ranking. Use this before read_code_file.

read_code_file

Read a file from the local workspace index. First call without offset to get the start of the file. If has_more is true, call again with offset.

spawn_tasks

Run multiple independent background tasks in parallel.

search_agent_tools

Semantic search over the agent tool catalog.

Runtime MCP servers

Shared servers for every visitor go under mcp.mcpServers in sveda.yaml. Each entry needs a url and optional headers. That is separate from host MCP: the app's own tools are still host_mcp_url and host_mcp_token on the embed token.

mcp:
  mcpServers:
    docs:
      url: https://mcp.example.com/mcp
      headers:
        Authorization: Bearer token

Frontend registry.register

Register tools on SvedaToolRegistry before constructing SvedaClient, or pass the registry as tools. Specs go out as stream body clientTools. A tool.call with target: "frontend" runs handler(input, { chatId, toolCallId }). With autoSubmitFrontendToolResults (default true) the session posts results back on the stream.

import { SvedaClient, SvedaToolRegistry } from '@sveda-ai/core'

const tools = new SvedaToolRegistry()
tools.register({
  name: 'get_selection',
  description: 'Return the current UI selection',
  parameters: { type: 'object', properties: {} },
  handler: async (_input, { chatId, toolCallId }) => ({
    chatId,
    toolCallId,
    selection: window.getSelection()?.toString() ?? '',
  }),
})

const client = new SvedaClient({
  endpoints: { stream: '/sveda/stream' },
  headers: { 'x-sveda-embed-token': token },
  tools,
})

Chat confirmation (opt-in)

Host tools publish _meta.confirmation: "required" on tools/list when the integrator opts in. Frontend tools set confirmation: 'required' on register() so it appears in clientTools. The runtime emits tool.call with the same flag and waits for toolDecisions before calling the host or running the handler. Full flow: tool confirmation.

Policy filters

When the embed token carries a named policy (or tighten-only grants), the runtime filters host MCP tools and client tools on every turn from that capability set. Host resolveToolsUsing is a second check: the host can expose a narrower list before mint, but it cannot widen past the token policy. Builtin web / code surfaces follow the same document. Details and JSON shape: embed policies.

Host MCP handshake

Host MCP is not a second client you wire by hand. Pass host_mcp_url and host_mcp_token together on POST /sveda/embed/token. Rules:

  • URL and token must both be present or both absent. Mismatch returns 422 host_mcp_url and host_mcp_token are required together.
  • URL must be http:// or https:// (no whitespace, max 2048 chars).
  • Credentials are stored per visitor_id only when a host API key is configured ( SVEDA_EMBED_HOST_API_KEY / x-sveda-host-key ).
  • On a turn the runtime builds HostMcpClient, calls initialize then tools/list, and executes tools/call with Authorization: Bearer <host_mcp_token>.

Token mint details: embed token. Product: MCP and tools.

curl -s http://127.0.0.1:8787/sveda/embed/token \
  -H 'content-type: application/json' \
  -H 'x-sveda-host-key: $SVEDA_EMBED_HOST_API_KEY' \
  -d '{
    "visitor_id": "visitor-123",
    "host_mcp_url": "https://app.example.com/mcp",
    "host_mcp_token": "host-mcp-secret"
  }'

Catalog ids, not nicknames.

ChatGPT, Claude, or a custom Responses / Anthropic URL. DeepSeek is one wrapper.

Models