feat(sdk): wire MCP servers into the in-process runtime; share gateway-auth builder#25
Merged
Conversation
…teway-auth builder
The flexibility follow-up from the native-vs-hand-rolled audit. The sdk (and
sdk-k8s) runtime ran with NO MCP servers — only claude-cli wired them — so
sdk-mode roles silently lost github/linear/etc. and couldn't run the github-MCP
commit flow, making the sdk transport a degraded, second-class option. This
closes the gap and removes a duplicated gateway-auth code path.
─── Shared HTTP MCP builder (src/mcp.ts) ───
buildHttpMcpServers(serverNames, env) resolves a role's MCP servers into the
{type:'http', url, headers} map that BOTH Claude Code's --mcp-config JSON and
the Agent SDK's `mcpServers` query option accept. It owns the gateway-bearer
injection (MCP_GATEWAY_TOKEN) plus the FAB_MCP_STRICT throw / skip-with-warning
policy, and the GATEWAY_HOSTED set — previously duplicated in claude-cli.
─── sdk runtime now wires MCP (src/runtimes/sdk.ts) ───
runRoleSession builds the role's MCP map and passes it to query() as
`mcpServers` with `strictMcpConfig: true` (fab's servers only, not the user's
ambient ~/.claude config), mirroring claude-cli's --strict-mcp-config. sdk and
sdk-k8s roles now get their declared MCP tools.
─── claude-cli de-duplicated (src/runtimes/claude-cli.ts) ───
buildMcpConfigJson is now a thin wrapper over buildHttpMcpServers: identical
output, one source of gateway-auth truth. Removed its private GATEWAY_HOSTED set
and McpHttpEntry / McpConfigShape interfaces.
─── Tests ───
mcp.test.ts covers buildHttpMcpServers: direct servers (no bearer), gateway
bearer injection, non-strict skip on a missing token, and the FAB_MCP_STRICT
throw. Existing claude-cli tests are unchanged (behavior preserved).
Verified: npm run lint / build / format:check clean; npm test 300/300.
Co-authored-by: stxkxsbot <275011021+stxkxsbot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The "more flexible" follow-up from the native-vs-hand-rolled audit. See the commit message for full detail.
Why
The
sdk/sdk-k8sruntime wired no MCP servers at all — onlyclaude-clidid. So sdk-mode roles silently lost github/linear/etc. and couldn't run the github-MCP commit flow, makingsdka degraded transport. This makes it first-class.What
src/mcp.tsbuildHttpMcpServers— single source for the{type:'http',url,headers}MCP map that both Claude Code's--mcp-configand the Agent SDK'smcpServersoption accept; owns the gateway-bearer injection +FAB_MCP_STRICTpolicy + theGATEWAY_HOSTEDset (previously duplicated in claude-cli).sdkruntime passes the role's servers toquery()asmcpServers+strictMcpConfig: true(fab's servers only).Verification
npm run lint/build/format:checkclean ·npm test300/300 (+4buildHttpMcpServerstests).