Skip to content

fix(mcp): SSE transport served only 6 tools — delegate to the canonical dispatch#598

Merged
yogasw merged 2 commits into
yogasw:masterfrom
aguung:fix/mcp-sse-tool-dispatch
Jun 7, 2026
Merged

fix(mcp): SSE transport served only 6 tools — delegate to the canonical dispatch#598
yogasw merged 2 commits into
yogasw:masterfrom
aguung:fix/mcp-sse-tool-dispatch

Conversation

@aguung
Copy link
Copy Markdown
Collaborator

@aguung aguung commented Jun 7, 2026

What

Unifies MCP tool dispatch so the Streamable HTTP/SSE transport serves the same tools as stdio. Fixes wick_info (and 4 other tools) returning unknown tool over the shared loopback MCP.

Why

tools/call had two dispatchers:

  • handleToolsCall (stdio + HTTP-JSON) — the complete switch: 11 tools.
  • handleToolsCallSSE (Streamable HTTP/SSE) — its own switch handling only 6: wick_list/search/get/encrypt/decrypt/execute, with default → "unknown tool".

Clients that speak Streamable HTTP/SSE (e.g. the agent's shared loopback wick MCP) therefore got unknown tool: wick_info even though tools/list advertised it — while the stdio wick-agent served it fine. The tools missing from the SSE path:

  • wick_info, ask_user, wick_list_providers, wick_skill_list, wick_skill_sync

This is exactly the reported symptom: wick_info failed on the shared (SSE) server but worked on the stdio one.

How

Collapse the SSE switch into a single delegation:

if p.Name == "wick_execute" {        // the only tool that needs SSE streaming
    h.sseWickExecute(sess, r, req, p, user, tagIDs)
    return
}
h.sseStaticTool(sess, func(buf *bufferingWriter) {
    h.handleToolsCall(buf, r, req)   // canonical switch → buffered → one SSE frame
})
  • The previously-explicit static cases (wick_list/search/get/encrypt/decrypt) used sseStaticTool (run handler → buffer → one frame) — the delegation does the identical thing through the canonical switch, so they are unchanged.
  • wick_execute keeps its streaming goroutine path (progress events + heartbeats).
  • The tool switch now lives in exactly one place (handleToolsCall). Adding a tool there works on stdio, HTTP-JSON, and HTTP-SSE automatically — no second switch to keep in sync.

This also unblocks any future top-level tools (e.g. a wick_manager_* surface) from silently breaking over SSE.

Testing

  • TestSSEDispatchDelegatesNonStreamingToolswick_info over the SSE path returns its payload, not unknown tool (RED before the fix).
  • TestSSEDispatchStillServesConnectorToolswick_list (a previously-explicit SSE case) still returns the connector through the delegation — proves the collapsed cases aren't lost.
  • Full internal/mcp suite: 78 tests pass. go build ./cmd/lab ., gofmt clean.

aguung added 2 commits June 7, 2026 16:32
…l switch

The Streamable HTTP/SSE path (handleToolsCallSSE) had its own tool switch
that only handled wick_list/search/get/encrypt/decrypt/execute and returned
"unknown tool" for everything else. So over the shared loopback MCP (which
clients reach via SSE), wick_info, ask_user, wick_list_providers, and the
wick_skill_* tools were advertised in tools/list but failed on tools/call —
while the stdio transport (one complete switch in handleToolsCall) served
them fine. That mismatch is why wick_info returned "unknown tool" on the
shared server but worked on the stdio wick-agent.

Collapse the SSE switch: wick_execute keeps its streaming path; every other
tool is buffered through the canonical handleToolsCall dispatcher and framed
as one SSE event. The tool switch now lives in exactly one place, so adding
a tool there works on both transports automatically — no second switch to
keep in sync.
aguung added a commit to aguung/wick that referenced this pull request Jun 7, 2026
…olsCall

Since yogasw#598 the SSE path delegates non-wick_execute tools to the canonical
handleToolsCall, so the plan's top-level wick_manager_* tools must be added
there only (never a second case in handleToolsCallSSE) to work on every
transport. Records the buffered-vs-streaming nuance for long-running ops.
@aguung aguung force-pushed the fix/mcp-sse-tool-dispatch branch from cf3bf3b to 1c8b396 Compare June 7, 2026 09:46
@yogasw yogasw merged commit 009204c into yogasw:master Jun 7, 2026
2 checks passed
yogasw added a commit that referenced this pull request Jun 7, 2026
feat(mcp): expose wickmanager ops as top-level wick_manager_* tools (stacked on #598)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants