Skip to content

Stateless HTTP transport + fix MCP-mode evals for agent-sdk 0.3.x tool search#79

Merged
olaservo merged 2 commits into
mainfrom
feature/http-transport-and-subagent-evals
Jul 5, 2026
Merged

Stateless HTTP transport + fix MCP-mode evals for agent-sdk 0.3.x tool search#79
olaservo merged 2 commits into
mainfrom
feature/http-transport-and-subagent-evals

Conversation

@olaservo

@olaservo olaservo commented Jul 5, 2026

Copy link
Copy Markdown
Owner

What

  1. Stateless HTTP transport for skilljack (--http[=port] / SKILLJACK_HTTP_PORT). Serves the core skill surface at POST /mcp via per-request StreamableHTTPServerTransport({ sessionIdGenerator: undefined }). Default stdio path unchanged. (src/http-transport.ts, tests, docs.)
  2. Fix MCP-mode evals on agent-sdk 0.3.x. Activation had collapsed to ~1/7 due to two independent regressions:
    • A — stdio connect race: the SDK connects stdio MCP servers asynchronously, so a stdio skilljack is pending at the model's first turn (upstream Race between initialize control_request and MCP refresh causes tools to drop from first request anthropics/claude-code#49753). → harness now runs skilljack over HTTP (--http=0), connected on turn 1.
    • B — tool search / deferred tools: MCP tool descriptions are deferred out of context, so the model never sees skilljack's <available_skills> catalog (which lives in the load-skill description) and won't activate. → harness sets ENABLE_TOOL_SEARCH=false.
    • Both needed together. Verified: code-style / template-generator / xlsx-openpyxl now PASS activation+following (were 0/3), across mcp / local / mcp+local.
  3. Product disclaimer (README, CLAUDE.md, skilljack-docs, evals/README): the catalog-in-tool-description method only surfaces with tool search disabled; on modern Claude Code (tool search on) auto-activation is unreliable. Tracking the tool-search-on case in Skill catalog (dynamic, via tool description) is invisible under tool search / deferred tools #78. The catalog is deliberately NOT duplicated into server instructions.

Not done

Subagent delegation was explored and dropped — it's a band-aid that doesn't address regression B (branch name predates that decision).

Verification

  • npm run build + npm test232 green (incl. 2 new HTTP transport tests).
  • Manual: node dist/index.js --http=3000 ./evals/skillsinitialize + tools/list over an MCP client; GET → 405.
  • Evals: MCP-mode activation restored (see commit messages).

Refs: #78 (tool-search product issue), anthropics/claude-code#49753 (stdio race).

🤖 Generated with Claude Code

olaservo and others added 2 commits July 4, 2026 18:39
Serve skilljack over stateless Streamable HTTP at POST /mcp as an alternative
to stdio. Enabled via --http / --http=<port> (single token so it isn't parsed
as a skill dir) or SKILLJACK_HTTP_PORT / SKILLJACK_HTTP; default port 3000.

- src/http-transport.ts: buildCoreServer() (load-skill, skill-resource,
  resources, prompts) + startHttpServer() using a per-request
  StreamableHTTPServerTransport({ sessionIdGenerator: undefined }).
- src/index.ts: getHttpPort() + branch to startHttpServer() right after startup
  discovery; the stdio path (UI config/display tools, polling, watchers,
  dynamic refresh) is unchanged and HTTP-mode skips it.
- Limitation: stateless HTTP has no server->client stream, so listChanged /
  resources/updated notifications are not delivered; skills are read at startup.
- Tests: initialize + tools/list + resources over an MCP client; GET -> 405.
  Full suite 232 green. Docs updated (README, CLAUDE.md, skilljack-docs).

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…claimer

MCP-mode skill activation collapsed to ~1/7 on agent-sdk 0.3.x due to two
independent regressions:
  A) stdio connect race — SDK connects stdio MCP servers async, so a stdio
     skilljack is `pending` at the first turn and its tools are absent
     (upstream anthropics/claude-code#49753).
  B) tool search / deferred tools — MCP tool *descriptions* are deferred out
     of context, so the model never sees skilljack's <available_skills> catalog
     (which lives in the load-skill tool description) and won't activate.

Eval harness now works around both: MCP modes run skilljack over HTTP
(startSkilljackHttp, --http=0 ephemeral, connected on turn 1) and set
ENABLE_TOOL_SEARCH=false so tool descriptions load into context. Verified:
code-style / template-generator / xlsx-openpyxl now PASS activation+following
(were 0/3). Subagent-delegation approach dropped (band-aid, didn't address B).

Also adds getHttpPort() support for --http=0 (ephemeral) and cleanupEvalServers().

Product disclaimer (README, CLAUDE.md, skilljack-docs, evals/README): the
catalog-in-tool-description method only surfaces when tool search is disabled;
on modern Claude Code (tool search on) auto-activation is unreliable. Do not
merge the catalog into server instructions (deliberately independent; going
optional in-spec) — handling tool-search-on is an open product problem.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
@olaservo
olaservo merged commit 5155139 into main Jul 5, 2026
1 check passed
@olaservo
olaservo deleted the feature/http-transport-and-subagent-evals branch July 5, 2026 13:50
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.

1 participant