* 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>
18 KiB
DDNS Agent Development Guide
Portable project instructions for coding agents. The closest
AGENTS.mdtakes precedence.
Table of Contents
Project Overview
What is DDNS?
DDNS is a Python-based Dynamic DNS client that automatically updates DNS records to match the current IP address. It supports:
- Multiple DNS Providers: 15+ providers including Cloudflare, DNSPod, AliDNS, etc.
- Dual Stack: IPv4 and IPv6 support
- Multiple Platforms: Docker, binary executables, pip installation, and source code
- Flexible Configuration: Command-line arguments, JSON files, and environment variables
- Advanced Features: Multi-domain support, HTTP proxy, caching, scheduled tasks
Key Technologies
- Language: Python (2.7+ and 3.x compatible)
- Testing: unittest (default) and pytest (optional)
- Linting/Formatting: ruff
- CI/CD: GitHub Actions
- Containerization: Docker (multi-architecture support)
- Packaging: PyPI, Nuitka (for binaries)
Portable Agent Definitions
AGENTS.mdfiles contain project and directory rules..agents/skills/*/SKILL.mdcontains reusable, client-neutral workflows..github/agents/*.agent.mdis a thin GitHub Copilot adapter for tool boundaries and role selection.- Do not duplicate a Skill in client-specific directories.
- The default coding agent owns general project work; use a domain agent only when its narrower context is useful.
Project Status
- License: MIT
- Python Versions: 2.7, 3.6, 3.7, 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14
- Platforms: Windows, Linux, macOS
- Architectures: amd64, arm64, arm/v7, arm/v6, 386, ppc64le, riscv64, s390x
Project Architecture
Directory Structure
Here is the folder and file structure for the DDNS project.
Format: <TAB depth>{filename}:<TAB>{description}
.github/: GitHub configuration
workflows/: CI/CD workflows (build, publish, test)
instructions/: Agent instructions (python.instructions.md)
agents/: Thin GitHub Copilot agent profiles
copilot-instructions.md: GitHub Copilot instructions
.agents/: Portable agent workflows
skills/: Agent Skills specification directories
ddns/: Main application code
__init__.py: Package initialization and version info
__main__.py: Entry point for module execution
cache.py: Cache management
http_config.py: Shared Web and MCP HTTP listener settings
ip.py: IP address detection logic
mcp.py: Model Context Protocol helper utilities
mcp_http.py: MCP Streamable HTTP transport
config/: Configuration management
__init__.py
cli.py: Command-line argument parsing
config.py: Configuration loading and merging
env.py: Environment variable parsing
file.py: JSON file configuration
provider/: DNS provider implementations
__init__.py: Provider registry
_base.py: Abstract base classes (SimpleProvider, BaseProvider)
_signature.py: HMAC signature utilities
alidns.py: Alibaba Cloud DNS
aliesa.py: Alibaba Cloud ESA
callback.py: Custom webhook callbacks
cloudflare.py: Cloudflare DNS
cloudns.py: ClouDNS
debug.py: Debug provider
dnscom.py: DNS.COM
dnspod.py: DNSPod (China)
dnspod_com.py: DNSPod International
edgeone.py: Tencent EdgeOne
edgeone_dns.py: Tencent EdgeOne DNS
he.py: Hurricane Electric
huaweidns.py: Huawei Cloud DNS
namesilo.py: NameSilo
noip.py: No-IP
tencentcloud.py: Tencent Cloud DNS
west.py: West.cn DNS
scheduler/: Task scheduling implementations
__init__.py
_base.py: Base scheduler class
cron.py: Cron-based scheduler (Linux/macOS)
launchd.py: macOS launchd scheduler
schtasks.py: Windows Task Scheduler
systemd.py: Linux systemd timer
util/: Utility modules
__init__.py
comment.py: Comment handling
fileio.py: File I/O operations
http.py: HTTP client with proxy support
try_run.py: Safe command execution
web/: Embedded management dashboard
__init__.py: Dashboard package exports
scheduler.py: In-process dashboard synchronization scheduler
server.py: Local-only embedded dashboard HTTP server
service.py: Dashboard data and configuration services
tests/: Unit tests
__init__.py: Test initialization (path setup)
base_test.py: Shared test utilities and base classes
README.md: Testing documentation
config/: Test configuration files
scripts/: Test helper scripts
test_cache.py: Cache tests
test_config_*.py: Configuration tests
test_ip.py: IP detection tests
test_mcp_http.py: MCP Streamable HTTP tests
test_provider_*.py: Provider-specific tests
test_scheduler_*.py: Scheduler tests
test_util_*.py: Utility tests
docs/: Documentation (VitePress-based)
AGENTS.md: Documentation-specific agent rules
.vitepress/: VitePress configuration and theme
config/: Configuration documentation (Chinese)
cli.md: CLI usage guide
env.md: Environment variables guide
json.md: JSON configuration guide
mcp.md: MCP server guide
dev/: Developer guides (Chinese)
provider.md: Provider development guide
config.md: Configuration system design
providers/: Provider-specific documentation (Chinese)
README.md: Provider list and overview
51dns.md: 51DNS provider guide
alidns.md: Alibaba Cloud DNS guide
aliesa.md: Alibaba Cloud ESA guide
callback.md: Custom webhook callbacks guide
cloudflare.md: Cloudflare DNS guide
cloudns.md: ClouDNS guide
debug.md: Debug provider guide
dnscom.md: DNS.COM provider guide
dnspod.md: DNSPod (China) guide
dnspod_com.md: DNSPod International guide
edgeone.md: Tencent EdgeOne guide
edgeone_dns.md: Tencent EdgeOne DNS guide
he.md: Hurricane Electric guide
huaweidns.md: Huawei Cloud DNS guide
namesilo.md: NameSilo guide
noip.md: No-IP guide
tencentcloud.md: Tencent Cloud DNS guide
west.md: West.cn DNS guide
en/: English documentation
config/: English configuration guides (mirrors config/)
dev/: English developer guides (mirrors dev/)
providers/: English provider guides (mirrors providers/)
docker.md: Docker documentation
install.md: Installation guide
public/: Public static assets
img/: Images and diagrams
schema/: JSON schema files (symlink)
tests/: Test configuration examples
docker.md: Docker documentation (Chinese)
install.md: Installation guide (Chinese)
release.md: Release notes (Chinese)
docker/: Docker configuration
Dockerfile: Main Dockerfile
glibc.Dockerfile: glibc-based build
musl.Dockerfile: musl-based build
entrypoint.sh: Container entrypoint script
schema/: JSON schemas
v2.json: Legacy schema v2
v2.8.json: Legacy schema v2.8
v4.0.json: Previous schema v4.0
v4.1.json: Latest schema v4.1
tools/: Python 3.12+ repository maintenance tools
run.py: Direct run script
pyproject.toml: Python project configuration
setup.cfg: Setup configuration
.gitignore: Git ignore rules
LICENSE: MIT License
README.md: Main README (Chinese)
README.en.md: Main README (English)
Module Dependencies
ddns/__main__.py
├── ddns.config.* # Configuration loading
│ ├── cli # Command-line parsing
│ ├── env # Environment variables
│ ├── file # JSON file loading
│ └── config # Config merging and validation
│
├── ddns.ip # IP address detection
│ └── ddns.util.http # HTTP client for public IP APIs
│
├── ddns.provider.* # DNS provider implementations
│ ├── _base # Base classes (SimpleProvider, BaseProvider)
│ ├── _signature # HMAC signature for cloud APIs
│ └── ddns.util.http # HTTP client for API requests
│
├── ddns.cache # Caching to reduce API calls
│ └── ddns.util.fileio # File operations
│
└── ddns.scheduler.* # Task scheduling
└── ddns.util.try_run # Safe command execution
Core Components
1. Provider System
-
BaseProvider: Full CRUD DNS provider (query, create, update records)
- Used by: Cloudflare, AliDNS, DNSPod, TencentCloud, EdgeOne, etc.
- Features: Automatic zone detection, record management, caching support
-
SimpleProvider: Simple update-only DNS provider
- Used by: HE.net, No-IP, Debug, Callback
- Features: Direct record updates without querying
2. Configuration System
Three-layer priority system:
- Command-line arguments (highest priority) - via
ddns.config.cli - JSON configuration files - via
ddns.config.file - Environment variables (lowest priority) - via
ddns.config.env
3. IP Detection System
Multiple methods supported (via ddns.ip):
- Network interface (by index number)
- Default route IP
- Public IP (via external APIs)
- URL-based (custom API endpoint)
- Regex matching (from ifconfig/ipconfig output)
- Command execution (custom script)
- Shell execution (system shell command)
4. Scheduler System
Platform-specific implementations:
- Linux: systemd timers or cron
- macOS: launchd or cron
- Windows: Task Scheduler (schtasks)
- Docker: Built-in cron with configurable intervals
Agent Development Model
Agent Quick Start
Classify the task first, then read only the nearest code, tests, docs, and schema for that lane.
- Provider:
ddns/provider/,tests/test_provider_*.py,docs/providers/,docs/en/providers/ - Config/schema:
ddns/config/,schema/,tests/test_config_*.py,docs/config/,docs/en/config/ - IP/HTTP:
ddns/ip.py,ddns/util/http.py,tests/test_ip.py,tests/test_util_http*.py - Scheduler:
ddns/scheduler/,tests/test_scheduler_*.py - Web/MCP:
ddns/web/,web/,ddns/mcp.py,tests/test_web.py,tests/test_mcp.py - Docs:
README*.md,docs/,docs/AGENTS.md - Build/release:
pyproject.toml,run.py,.github/patch.py,docker/,.github/workflows/ - Agent control plane:
AGENTS.md,.agents/skills/,.github/agents/,.github/instructions/
Use rg / rg --files for discovery, make narrow edits, validate the touched behavior, and report any command that could not run. A task is complete only when code, tests, schemas, docs, and generated metadata affected by the behavior are consistent.
Useful Commands
python -m ddns --help
python run.py --help
pip install ddns
ddns --help
docker run --rm newfuture/ddns:latest --help
curl -fsSL https://ddns.newfuture.cc/install.sh | sh
python -m ddns -c config.json
python -m ddns --dns=cloudflare --id=EMAIL --token=TOKEN --ipv4=domain.com
python -m ddns --debug
python -m ddns --dns=debug --ipv4=test.com --debug
ddns task --install 5
ddns task --enable
Linux/macOS scheduled tasks use systemd, cron, or launchd; Windows uses the release binary and ddns task --install 5.
Development Rules
Hard Rules
Follow .github/instructions/python.instructions.md for shipped Python and tests. Follow tools/AGENTS.md for maintenance tooling.
- Use only standard-library runtime dependencies.
- Preserve Python 2.7 and 3.x compatibility: no f-strings, annotations, async/await, or Python 3-only syntax.
- Use type comments, for example
# type: (...) -> ReturnType. - Keep CLI flags, provider names, config keys, schemas, and cache behavior backward compatible unless explicitly asked otherwise.
- Do not reformat unrelated files or modernize stable code for style alone.
Change Flow
- Start from an approved issue, feature, or maintenance goal.
- Read the closest implementation, tests, docs, schema, and
AGENTS.md. - State the implementation plan, compatibility impact, and acceptance checks.
- Mirror established patterns instead of inventing new abstractions.
- Change code, tests, schemas, bilingual docs, and metadata together.
- Run focused validation first, then the full affected suite.
- Self-review the diff for unrelated edits, secrets, compatibility, and missing artifacts.
- Continue through CI and review feedback until merge-ready or escalate with evidence.
Definition of Done by Lane
| Lane | Required artifacts | Required evidence |
|---|---|---|
| Core IP/HTTP/cache | implementation, regression tests, offline fixtures, behavior docs | focused unit tests, offline E2E, Python matrix |
| Config/schema/CLI | parser behavior, field model, latest schema, Chinese/English docs | config tests, schema checks, docs build |
| Provider | implementation, registry/aliases, field model, tests, schema, bilingual docs, navigation | provider/base tests, provider consistency check, docs build |
| Web | service/API, static assets, auth/scheduler behavior, package resources | Web tests, Web E2E, wheel/sdist install |
| Scheduler/install | OS implementation, CLI, lifecycle scripts, install docs | platform and install matrices |
| MCP | protocol behavior, schemas/annotations, lifecycle, redaction, docs | MCP tests, modern/legacy E2E, package/binary tests |
| Docs/site | Chinese/English parity, links, navigation, examples, llms.txt |
documentation contracts and VitePress build |
| Build/release | transformations, artifacts, matrices, release notes | package/binary/container checks and protected rehearsal |
| Agent/workflow | instructions, permissions, validation logic | agent contracts and human review |
Provider Changes
- Use
BaseProviderfor query/create/update APIs andSimpleProviderfor update-only APIs. - Register new providers in
ddns/provider/__init__.py. - Update canonical metadata in
ddns/config/field-model.json. - Add mocked tests in
tests/test_provider_<provider>.py; never require real credentials or live provider APIs. - Update both
docs/providers/<provider>.mdanddocs/en/providers/<provider>.md. - Update both latest schema enums, CLI choices, provider indexes, navigation, and
docs/llms.txt. - See
docs/dev/provider.mdanddocs/en/dev/provider.mdfor full provider method signatures. - Follow
ddns/provider/AGENTS.mdand.agents/skills/provider-development/SKILL.md.
Documentation
Keep Chinese and English docs aligned. Preserve code blocks, option names, JSON keys, CLI flags, and provider IDs exactly across translations. Link Chinese docs to Chinese pages and English docs to docs/en/ pages.
Follow docs/AGENTS.md and .agents/skills/documentation-maintenance/SKILL.md. Treat docs/public/install.sh and docs/esa.js as executable, high-risk files rather than ordinary prose.
Build and Release
Read the current workflows and Dockerfiles instead of relying on remembered versions or matrices. Do not publish, access release credentials, weaken required checks, disable caches, or remove platform coverage. Follow .agents/skills/build-release-maintenance/SKILL.md.
Testing & Validation
Run the smallest useful test first, then broaden when shared behavior changed.
python -m unittest tests.test_provider_cloudflare -v
python -m unittest tests.test_config_config -v
python -m unittest tests.test_ip -v
python -m unittest discover tests -v
python -m pytest tests/ -v # optional, when pytest is installed
ruff check --fix --unsafe-fixes .
ruff format .
Use these focused targets as a guide:
- Provider:
python -m unittest tests.test_provider_<provider> -v - Config/schema:
python -m unittest discover tests -p "test_config*.py" -v - IP/HTTP:
python -m unittest tests.test_ip tests.test_util_http tests.test_util_http_retry tests.test_util_http_proxy_list -v - Scheduler:
python -m unittest tests.test_scheduler_<name> -v - Broad shared change:
python -m unittest discover tests -v
For touched files or examples:
python -m py_compile ddns/provider/myprovider.py
python -m json.tool config.json
Provider tests should import from base_test; other tests should import from tests/__init__.py. Mock HTTP calls and assert request details, response parsing, and error handling.
Troubleshooting
- Reproduce with the smallest command, fixture, or unit test.
- Locate the layer: config parsing, IP detection, provider mapping, HTTP transport, cache, or scheduler.
- Read the nearest passing test and nearest similar implementation.
- Fix root cause, add a regression test when behavior changed, and re-run focused validation.
Common checks:
- Import error: file exists, provider registered, test path setup uses
tests/__init__.pyortests/base_test.py. - Syntax error: remove Python 3-only syntax and keep Python 2.7 compatibility.
- Auth/signature issue: verify credential shape and signing with mocked tests; never print real tokens.
- Record not updated: inspect cache, record type, line, TTL, domain split, and provider response parsing.
- Proxy/network issue: compare with
ddns/util/http.py; use--proxy=DIRECTor--ssl=falseonly as diagnostics. - Schema mismatch: update
schema/v4.1.jsonand matching config tests together. - Test failure: inspect mock return values and
mock_http.call_args. - Linting issue: run
ruff check --fix --unsafe-fixes .andruff format ..
python -m ddns --debug --dns=myprovider --ipv4=test.com
python -m ddns --debug --log_file=debug.log
python -m ddns --dns=debug --ipv4=test.com --debug
rm -f /tmp/ddns.cache
Use cache removal only when debugging stale local state. Avoid destructive git recovery unless the user explicitly requests it.
Safety and Escalation
- Prefer small, reviewable changes that follow existing patterns.
- Fix root causes and add tests for regressions.
- Preserve user changes in the working tree; never reset or reformat unrelated files.
- Treat configs, logs, environment variables, API tokens, and provider credentials as sensitive.
- Prefer mocked or dry-run validation; ask before using real credentials, provider APIs, or scheduler installation on a host.
- Use structured parsers for JSON, URLs, and HTTP data.
- Refactor only when it directly supports the task or removes clear local duplication.
- Require human direction for file/provider/config-key renames, compatibility breaks, security policy, workflow permissions, credentials, and publication.
- For large changes, explain goal, alternatives, impact, validation plan, and rollback before implementation.
- When asked to commit or draft PR text, use conventional commits such as
fix(util.http): handle proxy errors.
Version: 1.1.0 Last Updated: 2026-08-21 Maintained by: DDNS Project Contributors