Skip to content

feat(devframe): add MCP resource providers, templates, and subscriptions - #292

Draft
dvcolomban wants to merge 5 commits into
devframes:mainfrom
dvcolomban:dvcol/mpc-ressource
Draft

feat(devframe): add MCP resource providers, templates, and subscriptions#292
dvcolomban wants to merge 5 commits into
devframes:mainfrom
dvcolomban:dvcol/mpc-ressource

Conversation

@dvcolomban

@dvcolomban dvcolomban commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Why

Devframe already distinguishes agent actions from readable context. Actions are exposed as tools through ctx.agent.registerTool, while snapshots are exposed as resources through ctx.agent.registerResource.

The resource side currently supports one concrete URI and pull-based reads. MCP has two useful resource features that Devframe cannot express yet:

  • Resource templates describe URI families such as logs://{process} without registering every possible URI up front. A template may still list the concrete resources that currently exist.
  • Resource subscriptions let a client ask for update notifications. Devframe pushes only an invalidation through resources/updated; the client then reads the latest snapshot. This keeps values current without polling or pushing resource contents through a separate event format.

Resource providers mirror tool providers. They let an existing catalog remain the source of truth while Devframe projects its current resources on demand.

How it fits Devframe

The existing agent host remains the seam between a devtool and protocol adapters:

registerResource / registerResourceProvider
  -> agent host manifest, reads, and update events
  -> MCP resources/list, resources/templates/list, resources/read
  -> MCP subscribe/unsubscribe and resources/updated

The agent host owns registration order, duplicate handling, provider precedence, reads, and lifecycle callbacks. The MCP adapter owns URI-template matching and connection-local subscriptions because those are MCP concerns.

Tools and resources keep separate roles. Tools invoke behavior. Resources expose current context through stable URIs.

Interface

  • registerResource accepts either an AgentResourceInput or an AgentResourceTemplateInput.
  • Resource readers receive the requested URL. Existing zero-argument readers remain valid.
  • Registration handles expose notifyUpdated(). Template handles identify the concrete URI that changed.
  • registerResourceProvider adds lazy discovery with notifyChanged() and notifyUpdated(uri).
  • The agent manifest includes resource templates alongside concrete resources.

MCP behavior

  • A resource without uri keeps the generated devframe://resource/<encoded-id> URI.
  • Exact resource URIs win before URI templates.
  • Direct registrations win before providers, and earlier providers win before later providers.
  • resources/templates/list advertises templates. Template list() results also appear in resources/list.
  • The server advertises resources.subscribe because it implements resources/subscribe and resources/unsubscribe. MCP clients use this capability to decide whether subscriptions are supported.
  • Repeated subscriptions are idempotent per connection.
  • resources/updated is sent only to connections subscribed to that URI.
  • Implicit devframe://state/... resources use their SharedState update event to notify subscribed clients.
  • Active subscriptions are released when the client unsubscribes, the resource disappears, or the MCP connection closes.
  • MCP disposal is asynchronous because resource unsubscribe callbacks may be asynchronous, and session teardown must wait for them.
  • Resource membership changes emit resources/list_changed. Content changes emit resources/updated.
  • Route-based MCP servers accept exposeSharedState: false or a key predicate. The default remains true.

Compatibility

This change keeps the existing defaults and behavior for:

  • implicit devframe://state/... resources and the exposeSharedState default
  • the devframe_state_read tool
  • existing tools and tool providers
  • the agent resource content format

Existing resource registrations retain their generated URI and default JSON MIME type.

@vercel

vercel Bot commented Aug 25, 2026

Copy link
Copy Markdown

@dvcolomban is attempting to deploy a commit to the NuxtLabs Team on Vercel.

A member of the Team first needs to authorize it.

Comment thread packages/devframe/src/adapters/mcp/build-server.ts
Comment thread docs/content/1.guide/14.agent-native.md Outdated
Comment thread packages/devframe/src/adapters/mcp/build-server.ts
Comment thread packages/devframe/src/node/host-agent.ts Outdated
@dvcolomban
dvcolomban marked this pull request as ready for review August 25, 2026 16:44
Copilot AI lite review requested due to automatic review settings August 25, 2026 16:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class MCP resource capabilities to Devframe’s agent surface by introducing resource templates, lazy resource providers, and per-connection resource subscriptions. This extends the existing “tools vs readable context” model so adapters (notably MCP) can advertise URI families, list concrete instances, and push invalidation updates to subscribed clients without polling.

Changes:

  • Extend the agent API/types to support concrete resources, URI templates, resource providers, and subscription lifecycle hooks (read/list/subscribe/unsubscribe + updated notifications).
  • Implement MCP server support for resources/templates/list, template-backed resources/list, resources/subscribe/resources/unsubscribe, and filtered resources/updated notifications with async disposal.
  • Add/expand tests (in-memory + stdio + HTTP) and update docs to describe the new resource model and events.

Reviewed changes

Copilot reviewed 12 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/snapshots/tsnapi/devframe/types.snapshot.d.ts Snapshot updates for newly exported agent resource/provider/template types.
tests/snapshots/tsnapi/devframe/internal.snapshot.d.ts Snapshot updates for DevframeAgentHost’s updated private fields and new resource APIs.
tests/snapshots/tsnapi/devframe/index.snapshot.d.ts Snapshot updates for public agent interfaces (templates/providers/subscriptions).
tests/snapshots/tsnapi/devframe/constants.snapshot.d.ts Snapshot update for the new agent:resource:updated event constant.
skills/devframe/SKILL.md Update skill docs/examples to include templates/providers/subscriptions usage.
packages/devframe/src/types/agent.ts Core type additions for templates, providers, variables, handles, and new agent host methods/events.
packages/devframe/src/node/host-agent.ts Agent host implementation for registering templates/providers and forwarding reads/subscriptions + update notifications.
packages/devframe/src/node/tests/host-agent.test.ts Unit tests covering custom URIs, templates, variables, subscriptions, handles, and providers.
packages/devframe/src/events.ts Add the agent:resource:updated event name to the central event map.
packages/devframe/src/adapters/mcp/fetch.ts Ensure MCP session disposal awaits async resource cleanup.
packages/devframe/src/adapters/mcp/build-server.ts MCP resources: list/read/templates + subscribe/unsubscribe + subscription reconciliation/disposal.
packages/devframe/src/adapters/mcp/tests/mcp-server.test.ts In-memory MCP tests for explicit URIs, templates, subscription behavior, provider churn, and stdio coverage.
packages/devframe/src/adapters/mcp/tests/mcp-http.test.ts HTTP transport test verifying session-local subscriptions and cleanup on disconnect.
packages/devframe/src/adapters/mcp/tests/fixtures/resource-stdio-server.ts Stdio fixture server wiring resources + template and emitting updates.
docs/content/1.guide/20.events.md Document agent:resource:updated and clarify registered payload types.
docs/content/1.guide/14.agent-native.md Document resource URIs, templates, subscriptions, and providers for native agent usage.
Suppressed comments (1)

packages/devframe/src/adapters/mcp/build-server.ts:430

  • During manifest reconciliation, the code removes each subscription from the subscriptions map before awaiting its cleanup. If a cleanup throws/rejects, the outer .catch() swallows the error and the subscription is permanently lost (not tracked for later disposal/retry), causing leaks and inconsistent subscription state. Keep the subscription tracked until cleanup succeeds, and handle cleanup errors per-URI so one failure doesn’t abort the entire reconciliation pass.
      for (const [uri, cleanup] of [...subscriptions]) {
        subscriptions.delete(uri)
        await cleanup()
        const resource = resolveAgentResource(ctx, uri)
        if (!resource)

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/devframe/src/adapters/mcp/build-server.ts Outdated
Comment thread packages/devframe/src/adapters/mcp/build-server.ts Outdated
@dvcolomban
dvcolomban marked this pull request as draft August 25, 2026 17:30
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