feat(opencode): add MCP resource subscriptions#14569
Open
jtippett wants to merge 12 commits intoanomalyco:devfrom
Open
feat(opencode): add MCP resource subscriptions#14569jtippett wants to merge 12 commits intoanomalyco:devfrom
jtippett wants to merge 12 commits intoanomalyco:devfrom
Conversation
- Fix race condition in subscription tracking: use optimistic set population (populate immediately, delete on failure) instead of populating in async .then() callbacks after set is already stored - Add supportsSubscriptions() guard to unsubscribe() to avoid errors against servers that don't support subscriptions - Fix misleading "prompt" log messages in readResource to say "resource" - Remove unnecessary "as const" cast in TUI event handler
Convert try/catch to .catch(), remove destructuring, use functional array methods over for loops, and inline single-use variables.
…config - Auto-subscribe to all listed resources on connect for servers that support subscriptions, not just config-specified URIs - Subscribe to newly listed resources when ResourceListChanged fires - On reconnect, merge previous subs + config + fresh listResources() - Add `autoprompt` config option (default false) to trigger AI when a subscribed resource updates — uses system prompt for instructions and creates a new session if not already in one
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.
Issue for this PR
Closes #12092
Type of change
What does this PR do?
This adds MCP resource subscription support to opencode. It's experimental — my side project sends message updates over MCP and I want the client to react when resources (in this case the user's inbox) change.
What it does in practice: when an MCP server publishes a notifications/resources/updated or notifications/resources/list_changed, opencode intercepts and handles, showing a toast and if configured it kicks the AI with the updated resource. If there's no active session it creates one.
Where the changes live:
mcp/index.ts— the bulk of it. On connect, opencode auto-subscribes to every resource the server lists (plus any explicit URIs from config). Notification handlers publish bus events. On reconnect it merges previous subscription state + config + a fresh listResources() call so nothing gets lost. On disconnect it cleans up.config/config.ts— two new optional fields on both local and remote MCP server configs: subscriptions:string[] (explicit URIs to subscribe to) and autoprompt: boolean (whether to trigger AI on updates).
app.tsx— TUI subscribes to the bus events. Shows toasts. If autoprompt is enabled for that server and the session is idle (or there's no session), it prompts the AI with context about what changed.sdk/js/.../types.gen.ts— regenerated SDK types for the two new event types (mcp.resource.updated,mcp.resource.list.changed).Key decisions and why:
listResources().mcp/index.tspublishes bus events,app.tsxdecides what to do with session context. Keeps the separation clean.context / why this matters beyond my project:
Resource subscriptions are part of the MCP spec but no-one seems to have implemented them yet. Any MCP server that exposes mutable resources (databases, message queues, config files, monitoring dashboards) benefits from this. The autoprompt pattern is more opinionated — it's basically "AI-on-interrupt" — but it's opt-in.
Mainly wanted to show one way it could work!
How did you verify your code works?
Tested locally with my project (llmsg.com) as a remote MCP server (autoprompt: true). Verified:
No automated tests — this is touching the MCP client integration layer and I wasn't sure what test patterns you prefer here.
I've built some test functions on my site to simulate resource updates, which might be helpful if you want to play around. On https://llmsg.com/agents you should see the ability to trigger synthetic updates to any agent with a live connection.
Screenshots / recordings
https://asciinema.org/a/qXsZ8NbiPJnyGznx
Checklist
If you do not follow this template your PR will be automatically rejected.