feat(mcp): Add plugin-scoped MCP tool support#93
Merged
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
86d7fef to
23fde36
Compare
Add plugin manifest support for HTTP MCP servers and a turn-local MCP tool manager that progressively exposes plugin tools when matching skills load. Pause turns on MCP auth challenges and resume the same session after the callback instead of failing the turn. Persist loaded skills and active MCP providers across resume, and align the resumed callback path with normal reply delivery and thread-state persistence so Slack state stays consistent. Co-Authored-By: Codex <noreply@openai.com>
Preserve the stored authorization URL when clearing only the code verifier so paused MCP authorization can resume without losing its redirect target. Render the MCP callback page through React's escaping path and add focused regressions for callback HTML escaping and auth-session invalidation behavior. Co-Authored-By: GPT-5 Codex <codex@openai.com>
23fde36 to
14dfb62
Compare
Replace the router slash-trimming regex with deterministic string trimming and redact PEM private key blocks without a broad backtracking pattern. Add focused regression coverage for both behaviors so the CodeQL findings stay fixed on future refactors. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Sync the resumability checkpoint as soon as a plugin skill is loaded so an MCP auth pause cannot drop the newly activated skill. This keeps the resumed turn aligned with the tool state the user asked for before OAuth interrupted execution. Add a focused unit regression that exercises loadSkill, auth-required pause, checkpoint persistence, and resume-time MCP tool restoration. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Keep MCP client shutdown best-effort so one failing client does not prevent the rest of the active providers from closing or leave the manager state populated. Preserve the first close error after cleanup so the caller can still log the teardown failure. Extend the existing tool-manager unit coverage to assert that all active clients are closed and the active provider state is cleared even when one close call throws. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Keep resumed OAuth callback delivery aligned with the normal reply executor by uploading files whenever the delivery plan requests them, even if thread text posting is intentionally suppressed. This avoids silently dropping artifacts in reaction-ack flows and other no-text reply modes. Add callback coverage for the resumed delivery path where files are attached but thread text is skipped. Co-Authored-By: GPT-5 Codex <codex@openai.com>
Replace per-provider Pi tool registration with host-managed searchTools and useTool dispatch so loadSkill can expose MCP tools without replaying the turn. Persist MCP auth and session state at the host boundary, migrate the Notion skill to the new dispatcher contract, and tighten the MCP resume path. Reduce dev noise by shrinking console logging, deduping startup/plugin file-load logs, and making MCP dispatcher status updates more specific in Slack. Co-Authored-By: GPT-5 Codex <openai-codex@openai.com>
Commit the generated Next route types reference so the example app matches the current dev output after the recent routing and handler changes. Co-Authored-By: GPT-5 Codex <openai-codex@openai.com>
Shrink the exported MCP tool descriptor to the fields consumers actually use and keep argument validation inside the manager that owns the live tool registry. This removes duplicated lookup work from useTool and keeps the dispatcher path focused on dispatch. Also collapse repeated state-adapter connection setup in the MCP auth store so the storage operations read directly instead of repeating the same boilerplate in every function. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Return fixed browser copy for MCP OAuth callback success and failure pages instead of reflecting provider error text or exception messages into the HTML response. The Slack-side logging and resume flow still keep the actionable details. Update the callback unit coverage to assert the browser page stays generic for provider and exception failures. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Wrap auth-pause checkpoint persistence so transient state adapter failures do not replace the intended auth resume retry path. Add a regression test to keep this control flow aligned with timeout checkpoint handling. Co-Authored-By: Codex <noreply@openai.com>
Remove enduser.id from the console priority ordering. The key remains hidden in compact console output, so this only changes sorting behavior for console attributes. Co-Authored-By: Codex <codex@openai.com>
Ignore MCP auth-pause requests once the turn has already produced a completed assistant stop reason, while still parking aborted turns for resume. Add focused unit coverage for the tool-call race so completed turns are not discarded when an auth request arrives too late to interrupt them. Co-Authored-By: Codex <codex@openai.com>
Fall back to the latest stored turn checkpoint when an auth pause captures no in-memory messages so resumed turns keep their prior context. Add a focused unit regression covering the empty-capture auth-resume path to keep it aligned with the existing timeout fallback behavior. Co-Authored-By: Codex <codex@openai.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 2 total unresolved issues (including 1 from previous review).
Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Add eval-only OAuth provider fixtures and callback harnesses that drive the real callback routes while only mocking third-party services. This gives the MCP and generic auth-resume flows meaningful conversational coverage in evals without scripting internal commands into the user prompt. Tighten the runtime and test contracts around auth resume so resumed turns preserve prior thread context, successful oauth_started tool results are surfaced correctly, late plugin capability registration works, and callback tests fail if after() work is not actually scheduled. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Replace the heavy mocked respond.ts OAuth-start regression with a small pure parser test and keep the higher-level auth workflow coverage in integration tests and evals. Also merge the duplicate callback-harness guardrail tests and remove the redundant shared eval-plugin discovery check so the suite stays smaller and more focused. Co-Authored-By: GPT-5 Codex <noreply@openai.com>
Persist the base MCP auth session as soon as the client provider is created so raw authorization challenges can patch a real session instead of failing on unknown state. Reuse the same auth session ID when the same provider is retried for the same turn. This keeps pending OAuth links stable across retries instead of minting a fresh state token each time. Co-Authored-By: GPT-5 <noreply@openai.com>
Mark providers as auth-pending after a handled MCP authorization challenge so the same turn does not reconnect or rediscover tools again. Drop the cached client wrapper at that point as well, since the provider is no longer usable until the resumed turn builds a fresh manager. Co-Authored-By: GPT-5 <noreply@openai.com>
Align the Slack MSW integration assertion with the shared unhandled-request message that now covers Slack and eval provider hosts alike. This keeps the test focused on the actual contract enforced by the server instead of a stale Slack-specific string. Co-Authored-By: GPT-5 <noreply@openai.com>
Treat only the SDK UnauthorizedError path as an MCP auth challenge. A bare StreamableHTTPError 401 means the transport still failed after the SDK already attempted auth, so reclassifying it as resumable OAuth could crash later when no authorization URL exists. Co-Authored-By: GPT-5 <noreply@openai.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.

Add plugin-scoped MCP tool support with same-session auth resume.
Plugins can now declare a single HTTP MCP server in their manifest. When the agent loads a skill from that plugin, it progressively activates that plugin's MCP tools, and the turn checkpoint now persists both loaded skills and active MCP providers so resumed turns rebuild the same tool surface.
This also adds the MCP auth path. MCP auth challenges now pause the current turn, send a private auth link, and resume the same session after the callback instead of failing the request. The callback restores the stored turn context and persists the resumed reply back into Slack thread state so delivery and conversation state stay aligned.
I kept this scoped to tools-only MCP over HTTP. There is no sandbox-managed MCP transport here, and provider-specific behavior stays in the plugin manifest rather than leaking into the older capability and broker flows.