Skip to content

fix(mcp): thread run-scoped registry through discoverSchemas#577

Merged
sroussey merged 1 commit into
mainfrom
claude/beautiful-mayer-hsxosc
Jun 12, 2026
Merged

fix(mcp): thread run-scoped registry through discoverSchemas#577
sroussey merged 1 commit into
mainfrom
claude/beautiful-mayer-hsxosc

Conversation

@sroussey

Copy link
Copy Markdown
Collaborator

Summary

Commit 07389b9 ("fix(mcp): resolve auth credentials through the run-scoped registry") wired context.registry into mcpClientFactory.create(...) inside McpToolCallTask.execute / McpPromptGetTask.execute. But both tasks' execute() first calls this.discoverSchemas(context.signal, serverConfig), which internally calls mcpList(...) — a fresh new McpListTask(config).run(input) with NO run config. The nested run defaulted TaskRunner.runner.registry to globalServiceRegistry (packages/task-graph/src/task/TaskRunner.ts:94, 629), so in hosts that isolate per-(tenant, project) credential stores on the run-scoped registry, the discovery hop's bearer key never resolved against the right store.

Combined with the resolved ?? value fallback in resolveAuthSecrets (packages/mcp/src/util/McpAuthProvider.ts:388), the discovery listTools / listPrompts request sends the literal credential key name to the remote MCP server as a bearer token — leaking an internal identifier and breaking discovery against any server that gates list endpoints behind auth.

Fix (option a)

Picked option (a) — kept the mcpList(...) call inside discoverSchemas and threaded a registry through it:

  • mcpList(input, config, runConfig) — new optional third arg, forwarded into McpListTask.run(input, runConfig). Keeps the standalone task as the single source of truth for client construction.
  • McpToolCallTask.discoverSchemas(_signal, serverConfig, registry) and McpPromptGetTask.discoverSchemas(_signal, serverConfig, registry) accept the registry and forward it via mcpList(..., { registry }).
  • Both execute() methods pass context.registry into discoverSchemas(...).

Option (b) — open the client inline and skip mcpList entirely — would have moved logic out of the task layer and duplicated the close/error handling. Option (a) is a strictly smaller change.

Test

New packages/test/src/test/mcp/McpDiscoveryRegistry.test.ts exercises the full discovery → list-tools → call-tool chain with a run-scoped credential store. Pattern follows the existing McpClientUtil.test.ts:

  • Creates two scoped ServiceRegistry instances — a global with a WRONG-global-value bearer, a run-scoped with RIGHT-run-value.
  • Stubs mcpClientFactory.create so that every client construction (discovery + main call) calls back into resolveMcpClientAuth(config, registry) and records the bearer header.
  • Runs McpToolCallTask and McpPromptGetTask with task.run({}, { registry: runScoped }) and asserts the discovery hop's recorded bearer equals the run-scoped value, never the literal key.
  • Adds a third case pinning the client_credentials client_secret resolution against the run-scoped registry — the same resolved ?? value fallback applies to that auth type, so the reviewer's coverage-gap concern is closed.

Test plan

  • bun scripts/test.ts mcp vitest — 7 files, 106 tests, all pass (3 new tests in McpDiscoveryRegistry.test.ts).
  • bunx tsgo -b packages/mcp packages/test — clean typecheck.
  • CI green on main-targeted PR.

https://claude.ai/code/session_012goPYgXU4i7BF2k8aDatKP


Generated by Claude Code

Commit 07389b9 added context.registry plumbing into mcpClientFactory.create
for McpToolCallTask and McpPromptGetTask, but the discovery hop those tasks
take *before* the main call (this.discoverSchemas -> mcpList(...)) was still
unconfigured: the nested McpListTask.run() ran with TaskRunner's default
registry, which falls back to globalServiceRegistry. In hosts that isolate
per-(tenant, project) credential stores on the run-scoped registry, the
discovery hop's bearer key never resolved against the right store, and the
auth-resolution fallback in resolveAuthSecrets (resolved ?? value) sent the
literal credential key name to the remote MCP server as the bearer token.
That leaks an internal identifier and breaks discovery against any server
that gates listTools/listPrompts behind auth.

Threads context.registry through discoverSchemas(_signal, serverConfig,
registry) for both tasks, and extends mcpList(input, config, runConfig) to
accept a runConfig so the registry reaches the nested McpListTask.run().
Adds McpDiscoveryRegistry.test.ts with regressions that drive the full
discovery -> list -> call chain through a stub factory and assert the
bearer recorded during discovery comes from the run-scoped store, not the
global one. Also covers the client_credentials secret-slot equivalent so
the resolver fallback for that auth type is pinned.

https://claude.ai/code/session_012goPYgXU4i7BF2k8aDatKP
@github-actions

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 62.25% 24967 / 40104
🔵 Statements 62.09% 25825 / 41588
🔵 Functions 63.23% 4721 / 7466
🔵 Branches 50.87% 12240 / 24058
File CoverageNo changed files found.
Generated in workflow #2555 for commit 9d9e0f2 by the Vitest Coverage Report Action

@sroussey sroussey merged commit 838f3e1 into main Jun 12, 2026
14 checks passed
@sroussey sroussey deleted the claude/beautiful-mayer-hsxosc branch June 12, 2026 18:41
sroussey added a commit that referenced this pull request Jun 12, 2026
## @workglow/browser-control

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/task-graph

### Features

- add bugs URL to package.json files across all packages and providers

### Bug Fixes

#### task-graph,storage

- cache restart-resume + SharedInMemory sync barrier (#552)

### Documentation

#### task-graph

- fix TaskOutputTabularRepository README examples for new constructor signature

## @workglow/javascript

### Features

- add bugs URL to package.json files across all packages and providers

### Bug Fixes

- tsgo issue

## @workglow/ai

### Features

- add typecheck budget guard to catch type-instantiation regressions (#555)
- add bugs URL to package.json files across all packages and providers

### Bug Fixes

#### ai

- export ChunkRetrievalInputSchema + nightly schema-vs-type drift guard (#565)

## @workglow/knowledge-base

### Features

- add bugs URL to package.json files across all packages and providers

## workglow

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/storage

### Features

- add bugs URL to package.json files across all packages and providers

### Bug Fixes

#### task-graph,storage

- cache restart-resume + SharedInMemory sync barrier (#552)

## @workglow/mcp

### Features

- add bugs URL to package.json files across all packages and providers

### Bug Fixes

#### mcp

- thread run-scoped registry through discoverSchemas (#577)
- resolve auth credentials through the run-scoped registry

## @workglow/util

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/test

### Features

- add bugs URL to package.json files across all packages and providers

#### supabase

- add Supabase vector storage with pgvector support (#578)

### Bug Fixes

#### mcp

- thread run-scoped registry through discoverSchemas (#577)
- resolve auth credentials through the run-scoped registry

#### task-graph,storage

- cache restart-resume + SharedInMemory sync barrier (#552)

### Tests

- pin HF router provider for tool-calling conformance tests (#564)

### Chores

- update deps

### Updated Dependencies

- `@aws-sdk/client-sqs`: ^3.1068.0
- `@cloudflare/workers-types`: ^4.20260612.1
- `@types/dom-chromium-ai`: ^0.0.17
- `miniflare`: ^4.20260611.0

## @workglow/tasks

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/job-queue

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/indexeddb

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/openai

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/llamacpp-server

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/mlx

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/electron

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/ollama

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/node-llama-cpp

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/aws

### Features

- add bugs URL to package.json files across all packages and providers

### Chores

- update deps

### Updated Dependencies

- `@aws-sdk/client-sqs`: ^3.1068.0

## @workglow/anthropic

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/google-gemini

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/postgres

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/stable-diffusion-server

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/supabase

### Features

- add bugs URL to package.json files across all packages and providers

#### supabase

- add Supabase vector storage with pgvector support (#578)

## @workglow/playwright

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/sqlite

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/cloudflare

### Features

- add bugs URL to package.json files across all packages and providers

### Chores

- update deps

### Updated Dependencies

- `@cloudflare/workers-types`: ^4.20260612.1

## @workglow/huggingface-transformers

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/tf-mediapipe

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/chrome-ai

### Features

- add bugs URL to package.json files across all packages and providers

### Chores

- update deps

### Updated Dependencies

- `@types/dom-chromium-ai`: ^0.0.17

## @workglow/huggingface-inference

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/cactus

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/bun-webview

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/cli

### Features

- add bugs URL to package.json files across all packages and providers

## @workglow/web

### Features

- add bugs URL to package.json files across all packages and providers

### Chores

- update deps

### Updated Dependencies

- `@tailwindcss/vite`: ^4.3.1
- `tailwindcss`: ^4.3.1
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