mcp-delegate

mcp-delegate

Enables delegating tasks to a separate, full agentic loop running on a different model, with its own tool access, returning only the final result.

Category
访问服务器

README

mcp-delegate

An MCP server that gives Claude Code (as orchestrator) a tool to delegate a task to a separate, full agentic loop running on a different model (local via Ollama, or remote via OpenRouter), with its own tool access (files, bash, etc.), returning only a final result — functionally equivalent to a native subagent, but model-agnostic.

See mcp-subagent-delegation-plan.md for the full build plan, phased as separate commits/checkpoints.

Status

Phase 1, 2, 3, and 4 complete.

  • delegate_task — single-shot chat completion against a configured OpenAI-compatible endpoint (Ollama, LM Studio, vLLM, OpenRouter, ...).
  • delegate_agentic_task — gives the delegated model its own tool-use loop (read_file, write_file, run_bash) scoped to a caller-specified working directory, running until it stops calling tools, hits max_iterations, or exceeds timeout_seconds.
  • list_recent_delegations — inspect what past delegations (either tool) actually did, without digging through logs or re-running anything.
  • get_delegation_transcript — full message/tool-call transcript for one delegation, when it was run with capture_transcript=True (e.g. for model comparison/eval runs).

Deviation from the original plan: Phase 2 called for wrapping agent-loop as a subprocess. agent-loop only supports Linux/macOS/WSL, and this server needs to run natively on Windows, so we built the in-process loop described as Phase 5's alternative instead — same tool interface, no subprocess/ANSI-stripping complexity, and it sidesteps agent-loop's AGPL/no-commercial license entirely. See delegate/agentic.py.

Safety note: working_dir is caller-specified, not a fixed sandbox — the delegated model gets unattended file/bash access to whatever directory it's pointed at. File tools (read_file/write_file) are scoped to stay within working_dir; run_bash runs with that directory as cwd but shell commands are not fully sandboxed and could escape it (e.g. cd ..). Point this at a directory you're comfortable an unattended model can read, write, and execute commands in.

Guardrail note: the original plan's Phase 4 asked to confirm agent-loop's own guardrails (iteration cap, repetition detection) were active. Since we're not using agent-loop, that doesn't apply directly — our loop has its own max_iterations and timeout_seconds caps (verified in testing), but no repetition detection. A model that gets stuck alternating between two tool calls will run until it hits max_iterations rather than being caught early. Worth adding if that turns out to happen in practice.

Setup

uv sync
cp .env.example .env             # fill in DELEGATE_BASE_URL / DELEGATE_API_KEY / DELEGATE_MODEL
cp models.json.example models.json   # optional: named backends, see below

Multiple backends

Both tools take an optional backend param that looks up base_url/model/api_key from models.json instead of the default DELEGATE_* env vars — e.g. backend="ollama-local" for one call and backend="openrouter-free" for another in the same turn, each running concurrently. model, if also given, overrides just the model string within that backend.

Reference an env var for a key instead of writing it into models.json directly:

{
  "openrouter-free": {
    "base_url": "https://openrouter.ai/api/v1",
    "model": "nvidia/nemotron-nano-9b-v2:free",
    "api_key_env": "OPENROUTER_API_KEY"
  }
}

models.json is gitignored, same as .env.

Concurrency

MCP tool calls already run on separate worker threads, so concurrent delegations run in parallel with no extra plumbing. DELEGATE_MAX_CONCURRENCY (default 4, see .env.example) caps how many delegations — across both tools, any backend — run at once, to avoid a large fan-out overwhelming a local model server or a paid API's rate limits.

Run the server directly (mostly useful to check it starts without error — it then waits on stdio for an MCP client):

uv run server.py

Logging

Every delegate_task/delegate_agentic_task call — success or failure — is logged to a local SQLite file, delegations.db (gitignored, created on first use): tool, backend, model, task text, start/end time, iteration count, success/failure, a truncated result/error preview, and token usage if the backend returned it. Query it via the list_recent_delegations tool, or directly with sqlite3 delegations.db "select * from delegations order by id desc limit 20". Logging is best-effort — a logging failure won't take down an otherwise-successful delegation.

Both tools also append a trailing [tokens: N prompt / N completion / N total ($cost)] line to their own return value when the backend reports usage, so the calling agent sees it immediately without a separate list_recent_delegations call.

Cost tracking

pricing.json maps model string → {input_per_million, output_per_million} USD rates. When a call's resolved model has an entry, cost is computed from actual token usage, logged to delegations.db (cost_usd column), and included in the [tokens: ...] suffix. A model with no entry logs cost_usd = NULL — unknown, not assumed free — so a missing entry can't silently under-report spend. Local models generally won't have entries for that reason; genuinely free models (e.g. OpenRouter :free models) get an explicit {"input_per_million": 0, "output_per_million": 0} entry instead of being omitted.

Unlike .env/models.json, pricing.json isn't a secret or environment-specific, so it's committed directly rather than gitignored. Prices drift — the shipped file was fetched from OpenRouter's /api/v1/models on 2026-08-21 for the models named in a model-comparison bake-off this was built for; re-fetch and edit it to add/update models as needed.

Transcript capture (model comparison / eval runs)

Both tools take capture_transcript: bool = False. When set, the full message exchange — every model message, tool call, and tool result, not just the final answer — is logged, and the return value gets a [delegation_id: N] suffix. Fetch it with get_delegation_transcript(delegation_id).

This exists for running the same task through several different models/backends and comparing not just the final answer but how each one got there (tool selection, malformed tool calls, retries) — e.g. a bake-off across candidate models before picking one for production use. Off by default since it's extra logging overhead you don't want for routine delegation.

Register with Claude Code

A project-scoped .mcp.json is already checked in (uv run server.py). Restart Claude Code in this directory, or run claude mcp list to confirm it picked up the delegate server, then ask it to call delegate_task with a trivial prompt to confirm the round trip.

Tools

  • delegate_task(prompt, model=None, system_prompt=None, backend=None, capture_transcript=False) -> str — single-shot chat completion against the configured backend.
  • delegate_agentic_task(task, working_dir, model=None, max_iterations=20, timeout_seconds=600, backend=None, capture_transcript=False) -> str — multi-step delegation with read_file/write_file/run_bash tools scoped to working_dir. Returns only the final answer, not the full transcript, unless capture_transcript=True.
  • list_recent_delegations(limit=20) -> list[dict] — most recent logged delegations, newest first.
  • get_delegation_transcript(delegation_id) -> list[dict] — full transcript for one delegation logged with capture_transcript=True.

delegate_task/delegate_agentic_task return errors (bad config, unreachable endpoint, timeout, iteration cap) as "Error: ..." strings rather than raising, so a calling agent can see what went wrong.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选