Commit graph

2 commits

Author SHA1 Message Date
104f49c441 clients/mcp: apply audit findings — release-blocker fix on upload (093021c → new)
HIGH:
- S1: upload_file allow-root + symlink-resolve + size-cap. Env: CLAWDFORGE_UPLOAD_ROOT (default cwd), CLAWDFORGE_UPLOAD_MAX_BYTES (default 100MiB). README updated with threat-model paragraph.

LOW:
- S2: logger.propagate = False (stdout discipline defense-in-depth)
- S3: catch-all error message no longer echoes str(e) (host paths)
- S4: whitelist healthz/upload tool response fields
- S5: pattern-validate ff_* file tokens in run schema
- C1: strict-bool guard on timeout_secs/ttl_secs
- C2: coerce empty-string model/system to None

Deps:
- requests>=2.32 (CVE-2024-35195)
- urllib3>=2.2.2 (CVE-2024-37891)
- mcp>=1.2.0

Audit: memory/clawdforge-audits/mcp-093021c.md
2026-04-28 23:10:33 -07:00
093021cb36 clients/mcp: initial MCP server for clawdforge
Drops a Model Context Protocol server into clients/mcp/ that wraps the
clawdforge HTTP surface so MCP-aware clients (Claude Desktop, Claude Code,
Cursor, Zed, custom agents) can call it as a native tool — claude talking
to claude through the LAN bridge.

Three tools exposed:

  - clawdforge_healthz     -> GET /healthz
  - clawdforge_run         -> POST /run
  - clawdforge_upload_file -> POST /files

Admin endpoints intentionally NOT exposed; token minting stays human-gated.

Implementation notes:

  - Built on the official `mcp` Python SDK (>=1.0). asyncio-native server,
    stdio transport, low-level Server class with @list_tools / @call_tool
    handlers.
  - Self-contained `requests` HTTP wrapper rather than depending on the
    sibling clients/python SDK — keeps clawdforge-mcp installable
    standalone. Same error taxonomy (ForgeError / ForgeAPIError /
    ForgeAuthError / ForgeTransportError).
  - Sync HTTP calls offloaded via asyncio.to_thread so a slow `claude -p`
    can't stall the MCP event loop.
  - Errors are formatted into a single 'clawdforge error: ...' text block
    with isError=True; tracebacks never leak through the JSON-RPC pipe.
  - Logging goes to stderr (CLAWDFORGE_MCP_LOG=DEBUG to enable). stdout
    is reserved for JSON-RPC framing.
  - Config via env: CLAWDFORGE_URL (default http://localhost:8800) and
    CLAWDFORGE_TOKEN (required). MCP clients pass these via their `env`
    config block.

Tests: 12 unit tests covering tool discovery, healthz, run-success,
run-with-files, run-empty-prompt, run-subprocess-502, run-auth-401,
upload happy path, upload missing file, unknown tool, server factory.
HTTP layer mocked via `responses`. Plus a manual end-to-end stdio
smoke (initialize + tools/list round-trip) verified during build.

Includes ready-to-paste Claude Desktop and Claude Code config examples,
and a README documenting install, env, all three tools, and operational
notes (stdout-is-sacred, error wrapping, no streaming).
2026-04-28 22:37:08 -07:00