* feat(mcp): add Streamable HTTP transport Add a modern MCP 2026-07-28 HTTP endpoint for standalone and Web modes, with shared listener configuration, authentication, schema, tests, and bilingual documentation. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): support Python 2 HTTP assertions Normalize response header names and call handler methods through their underlying functions so the HTTP tests behave consistently on Python 2.7 and Python 3. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): harden HTTP request handling Validate mirrored request IDs, align Config Studio listener checks, bound socket reads, and accept the binary wrapper's documented SIGINT exit status. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): align HTTP negotiation validation Reject unavailable Accept media types by quality and keep schema host validation consistent with runtime listener checks. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): validate host schema behavior Assert accepted and rejected host samples instead of comparing Unicode escape representations that differ on Python 2.7. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(tests): avoid cross-engine schema regex Keep the schema pattern contract without executing its ECMA-262 Unicode escape through Python 2's incompatible regex engine. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate HTTP request boundaries Reject empty tokens and malformed JSON-RPC request shapes, and keep Config Studio bracket validation aligned with runtime listener handling. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): tighten HTTP input validation Reject legacy notifications, nested host brackets, and document the required JSON content type so validation remains consistent across runtime, schema, and Config Studio. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate Origin before method errors Apply the existing Origin policy to non-POST MCP requests and return CORS headers for configured allowed origins. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(mcp): clarify proxy Origin allowlist Explain that browser clients behind TLS termination must allowlist the public HTTPS origin even when the public page appears same-origin. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(mcp): add standalone server guide Move MCP client setup, transports, tools, security, and protocol limits into dedicated Chinese and English pages with matching navigation and index links. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): reject duplicate routing headers Reject repeated MCP protocol, method, and name headers before body consistency checks across Python 2 and Python 3. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(mcp): validate named request headers Validate Mcp-Name for tools/call, prompts/get, and resources/read before dispatching unsupported methods. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: NewFuture <6290356+NewFuture@users.noreply.github.com> Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
4.4 KiB
title, description
| title | description |
|---|---|
| DDNS MCP Server | Connect DDNS status and synchronization tools to MCP clients over stdio or Streamable HTTP |
MCP Server
DDNS provides a standard-library-only MCP server so clients such as GitHub Copilot can inspect local cached status or run one complete DDNS synchronization after user approval. Provider credentials are never returned in protocol arguments or results.
Configuration path precedence is -c/--config > DDNS_CONFIG > the conventional local config paths. MCP mode accepts exactly one local file; remote URLs and multiple -c values are rejected.
stdio (default)
ddns mcp -c /etc/ddns/config.json
stdio mode opens no network listener. stdout is reserved for one JSON-RPC message per line, while runtime logs go to stderr.
Add the server directly to GitHub Copilot CLI:
copilot mcp add ddns -- ddns mcp -c /etc/ddns/config.json
Alternatively, add the following to an MCP client configuration:
{
"mcpServers": {
"ddns": {
"command": "ddns",
"args": ["mcp", "-c", "/etc/ddns/config.json"]
}
}
}
Escape Windows path backslashes as \\ in JSON, or replace command with the absolute path to the ddns executable.
Streamable HTTP
Start a standalone HTTP MCP server:
ddns mcp -c /etc/ddns/config.json --transport http
The default endpoint is http://127.0.0.1:9876/mcp. The Web console also exposes /mcp on its listener.
Standalone mode and Web share these options:
| Option | Description |
|---|---|
--host |
Bind host; defaults to 127.0.0.1 and accepts a LAN address or 0.0.0.0 / :: |
--port |
Listener port, default 9876; use 0 to let the OS select one |
--http-token |
Shared Web API and HTTP MCP token; visible ASCII without spaces |
--http-origin ORIGIN |
Exact HTTP(S) origin allowed to access /mcp; repeatable |
Listener precedence is command line > root JSON http > DDNS_HTTP_* environment variables > 127.0.0.1:9876.
When loopback has no token, the Web APIs (including full configuration and provider credentials) and /mcp are unauthenticated. A non-loopback or wildcard listener requires a non-empty token. MCP clients send it as Authorization: Bearer <token>.
DDNS does not provide TLS. Put LAN listeners behind a trusted HTTPS reverse proxy that preserves Authorization, Host, and Origin. Browser access through a TLS-terminating proxy must list the exact public HTTPS origin in http.origins or --http-origin, even when the public page appears same-origin; native MCP clients may omit Origin.
HTTP supports MCP 2026-07-28 only. Each message is a separate POST to /mcp using Content-Type: application/json with MCP-Protocol-Version and Mcp-Method; tool calls also require Mcp-Name. Accept must list both application/json and text/event-stream.
This tools-only implementation returns plain JSON and does not provide SSE, sessions, legacy HTTP, resources, prompts, or subscriptions.
Available tools
| Tool | Arguments | Behavior |
|---|---|---|
get_ddns_status |
None | Read local configuration, cached addresses and records, provider summaries, and the latest sync time; it does not query providers live |
update_dns_records |
None | Resolve current addresses using the configuration, synchronize every configured record once, and return the resulting status |
update_dns_records changes external DNS state, so clients should retain user confirmation before invoking it. The tool accepts no domain, address, provider, or credential arguments, preventing a model from bypassing the local configuration to write arbitrary records.
Protocol and runtime limits
- stdio supports MCP
2026-07-28and the2025-11-25initializelifecycle. - HTTP supports MCP
2026-07-28only. - When a stdio client cancels an update, the server stops before subsequent IP rules, domain records, or providers.
- HTTP provides no SSE cancellation; work may continue after a client disconnects.
- A provider API request already sent cannot be rolled back.
- Status comes from the local cache. With caching disabled, a later request in another process cannot reconstruct previous sync history, although the update call still returns its own result.
- Do not let multiple Web, MCP, or system-task processes update the same configuration concurrently.