Ductor MCP Gateway

Ductor MCP Gateway

An authenticated MCP Streamable HTTP server that exposes Ductor's internal API, enabling agent messaging and task management through MCP tools.

Category
访问服务器

README

Ductor MCP Gateway

An independent Python 3.11+ sidecar that exposes Ductor's loopback internal HTTP API as authenticated MCP Streamable HTTP. It does not import ductor_bot, edit Ductor configuration, or run shell commands.

The default topology is:

MCP client -> Bearer auth -> 127.0.0.1:8798/mcp
                              |
                              +-> policy + validation + audit
                                     |
                                     +-> http://127.0.0.1:8799
                                         Ductor internal API

Security properties

  • Every HTTP route, including /health, requires the gateway bearer token.
  • Tokens come from a named environment variable or a mode-0600 regular file. Token values are never accepted on argv or in TOML.
  • Authentication compares fixed-length SHA-256 digests with hmac.compare_digest.
  • The listener defaults to loopback. A non-loopback bind requires the explicit allow_non_loopback=true safety switch.
  • MCP transport Host/Origin allowlists retain DNS-rebinding protection.
  • The policy independently limits tool names and Ductor agent identities.
  • Task list results are re-filtered by parent_agent; task create/resume/cancel preserve the caller's from ownership field exactly.
  • The official MCP SDK limits request bodies. The edge also limits requests per minute, concurrent HTTP requests, active sessions, session idle time, upstream response size, and upstream request duration.
  • Audit records contain event/result, tool name, request ID, agent/task IDs, and duration. They never contain bearer tokens, messages, prompts, task results, or upstream response bodies.
  • The gateway exposes no raw shell or generic HTTP tool.

Threat model

The bearer token is the MCP caller identity. Anyone holding it can use every tool/agent allowed by that gateway instance, so use separate instances/tokens for different trust domains. Policy is not per-user RBAC.

Ductor's checked source snapshot relies on loopback reachability; the live runtime inspected during development additionally required its internal bearer token. The sidecar supports both modes. A local process holding that upstream credential may call Ductor directly and bypass this sidecar. OS account isolation and host hardening remain required. The gateway does not make an already compromised host safe.

TLS is intentionally left to a local reverse proxy, private overlay, or Cloudflare Tunnel. Do not bind plain HTTP to a public interface. Rate/session limits are in-memory and per process; run one worker unless you add an external coordinating edge.

Tool output necessarily contains requested agent responses and task metadata. Treat MCP clients as trusted data recipients. Prompt-free audit logs do not make tool output non-sensitive.

Install

For the shortest path from an existing Ductor installation to a public, authenticated endpoint, follow the Cloudflare quick start. It includes the service installation, token placement, Tunnel and Access setup, MCP client headers, verification, and troubleshooting.

For local development only:

python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'

If the system Python lacks ensurepip, uv venv .venv followed by uv pip install --python .venv/bin/python -e '.[dev]' is equivalent.

Generate a token without displaying it:

.venv/bin/ductor-mcp-gateway generate-token --output ./gateway.token

Copy config.example.toml to a private deployment location, reduce allowed_agents and allowed_tools, then start:

DUCTOR_MCP_GATEWAY_CONFIG=/absolute/path/config.toml \
  .venv/bin/ductor-mcp-gateway serve

An environment token takes precedence over the token file. The environment variable's name is configured by auth.token_env and defaults to DUCTOR_MCP_GATEWAY_TOKEN.

The upstream Ductor credential is separate. By default the application reads DUCTOR_INTERAGENT_TOKEN, matching current Ductor tool wrappers, and injects it into the typed client. It can instead read a mode-0600 file configured as ductor.token_file; set ductor.token_env = "" if no environment lookup is desired. Neither upstream credential source is passed on argv or logged.

All non-secret settings can also be overridden with environment variables. See src/ductor_mcp_gateway/config.py for the explicit allowlist; common examples are DUCTOR_MCP_GATEWAY_DUCTOR_URL, DUCTOR_MCP_GATEWAY_ALLOWED_AGENTS, and DUCTOR_MCP_GATEWAY_ALLOWED_TOOLS. List values are comma-separated.

MCP tools

  • ductor_agents_list
  • ductor_agent_message
  • ductor_agent_message_async
  • ductor_tasks_create
  • ductor_tasks_list
  • ductor_tasks_resume
  • ductor_tasks_cancel

Message and task tools require an explicit from_agent. This retains Ductor's ownership/routing semantics; both sender and recipient identities must pass allowed_agents. Disabled tools are not advertised by tools/list.

Service deployment

deploy/ductor-mcp-gateway.service is a hardened system-level systemd example. Adjust the service account and paths, ensure that account can reach Ductor's loopback listener, place the token in /etc/ductor-mcp-gateway/ with ownership for that account and mode 0600, and make the current Ductor internal token available through the unit's mode-0600 EnvironmentFile or ductor.token_file. Then install the unit. It intentionally does not share or modify Ductor's installed service.

For public hostname deployment without opening a listener, start with the Cloudflare quick start. The Cloudflare deployment reference covers locally managed tunnels and additional operational detail. Protect the entire hostname in Cloudflare Access so /health cannot become a bypass.

Compatibility

The implementation targets the endpoint schemas documented by Ductor's docs/modules/multiagent.md and implemented by ductor_bot/multiagent/internal_api.py as inspected on 2026-08-12. The internal API is not declared a stable external contract. This repository deliberately copies no Ductor code and imports no Ductor package; schema drift therefore fails closed as a typed upstream protocol error.

The dependency range mcp>=1.29,<2 selects the official maintained Python MCP SDK's stable 1.x line. MCP SDK v2 was still pre-release when this range was chosen. Review the SDK migration guide and this gateway's middleware/lifespan integration before widening the upper bound.

Development checks

.venv/bin/pytest
.venv/bin/ruff check .
.venv/bin/mypy src

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选