Commit Graph
3 Commits
Author SHA1 Message Date
glm-5.3-flash 5ecf6c012b fix(adapters): bound from_mcp tools/list pagination (CON-14)
Replace rmcp's unbounded Peer::list_all_tools with a bounded walk over
list_tools: hard cap of 100 pages (MCP_MAX_TOOLS_LIST_PAGES) plus a 60 s
overall deadline (MCP_TOOLS_LIST_DEADLINE). Tripping either budget fails
loudly with AdapterError::DiscoveryFailed naming pages fetched and tools
accumulated — no silent truncation, no partial registration (import
fails closed, as before). A slow or hung page is cut off by a per-page
tokio timeout sized to the remaining budget.

Bounds are documented in the module doc. Integration test added: a
cycling-cursor server (next_cursor always Some("a")) terminates with
the clean budget error inside an outer 10 s guard; the existing 3-page
pagination test is unchanged and passes.

Verification: cargo test (304 pass), cargo test --features mcp,
cargo test --all-features (412 pass), clippy -D warnings both default
and --all-features --all-targets, cargo fmt --check, cargo doc --no-deps.
2026-08-30 11:46:46 +00:00
glm-5.3-flash 8700ed0fea fix(adapters): consumer adapter hygiene (CON-01, CON-03..CON-13)
- CON-01: from_mcp discovery follows tools/list pagination
  (rmcp list_all_tools); three-page paginating-server test
- CON-03: from_wss refuses ws:// with a Bearer token unless
  FromWss::allow_plaintext() is called explicitly (tests: refusal,
  opt-in, token-less passthrough)
- CON-04: audio variant of content_block_union_schema requires
  ["type","data","mimeType"]; jsonschema-validated audio block
- CON-05/07: import-time credential documented on both adapters;
  dead per-call capability read removed
- CON-06: 401 classification typed-first (downcast to rmcp
  StreamableHttpError<reqwest::Error>; AuthRequired/InsufficientScope/
  Client with status 401); a :40101 URL no longer misclassifies (tested)
- CON-11: transport tools/call failures declare MCP_TRANSPORT_ERROR;
  rmcp JSON-RPC errors preserve code (MCP_JRPC_<code>) and data
- CON-12: tool names validated at import (/, whitespace, empty →
  SchemaParse); unit + integration tests
- CON-13: tokens held as alkcall Secret<String> (zeroize, redacted Debug)
- CON-08/09: no close handles; explicit-limitation notes in from_mcp
  module docs, from_wss module docs, and ADR-070
- CON-10: full_surface [[test]] required-features = ["mcp","test-support"];
  cargo test --features mcp now compiles and passes

Verified: cargo test; cargo test --features mcp; cargo test --all-features;
cargo clippy (--all-features) --all-targets -- -D warnings; cargo fmt --check
2026-08-29 10:54:33 +00:00
glm-5.3-flash 4ac337c3a5 feat(adapters): from_mcp + to_mcp behind the mcp feature (rmcp 1.8)
from_mcp (src/adapters/from_mcp/):
- tools/list discovery over streamable HTTP; per-tool
  HandlerRegistration (Mutation, Once, FromMCP leaf, Internal;
  ADR-015/022)
- structuredContent-preferred output, ContentBlock-union fallback,
  isError -> MCP_TOOL_ERROR with content blocks as details (ADR-023)
- bearer token flows via capabilities key 'mcp' (ADR-014 no-env-vars)
- 19 unit tests + tests/from_mcp_integration.rs (5 tests vs a real
  rmcp streamable-HTTP MCP server)

to_mcp (src/adapters/to_mcp.rs):
- 4 fixed gateway tools (search/schema/call/batch, ADR-041); Sub ops
  excluded from search and uncallable (MCP is request/response)
- identity survives rmcp framing: bearer_auth_middleware stashes
  Option<Identity> in http::request::Parts extensions, call_tool reads
  it back from RequestContext extensions
- StreamableHttpService nested at /mcp in HttpAdapter's router,
  bearer middleware around it (feature-gated)

Streamable HTTP only (ADR-037): rmcp default-features off, no stdio.
Default build compiles without rmcp (cargo tree: 0 hits).

Verified: cargo test (182 lib default / 218 all-features) + 5 MCP
integration + 10 WS, clippy -D warnings (both), fmt.
2026-08-28 14:14:09 +00:00