Skip to content

feat(mcp): MCP resources projection — the AI read side#44

Merged
thorwhalen merged 1 commit into
mainfrom
feat/mcp-resources
Jul 6, 2026
Merged

feat(mcp): MCP resources projection — the AI read side#44
thorwhalen merged 1 commit into
mainfrom
feat/mcp-resources

Conversation

@thorwhalen

Copy link
Copy Markdown
Member

What & why

Extends acture-mcp-server with a read-side MCP resources projection — the state-exposure half of an "operate my app" AI assistant. research-11 §3 found the read side is an industry-wide gap acture is placed to close; this is the first of the v1.14-deferred package accelerators, pulled forward on a named need (reelee-web).

Where buildToolsList projects commands (actions) as MCP tools, this projects views (typed selectors over app state) as MCP resources, so a model can see current state before it acts.

Design decision: extend, don't invent

Kept to acture's precedent — extend the already-published package (additive minor), no new npm package, no core-surface change. The ViewRegistry primitive stays the hand-written pattern (docs/hand-written-view-registry.md) until a second projection target justifies extracting it — exactly how macros stayed a pattern while only the tool-bound acture-e2e-playwright earned a package. Full rationale: docs/v1_15-reflection.md.

Changes

  • Pure layer (resources.ts, SDK-free): buildResourcesList(views, opts), readResource(views, uri), viewIdToUri, and the ViewSource interface (the list / read / onStateChanged subset of the hand-written ViewRegistry). Tier-filtered (internal never projected); app://state/<id> JSON resources. The app supplies the ViewSource, so acture-mcp stays state-library-agnostic.
  • Server glue (server.ts): createMcpServer(registry, { views, resourceUriPrefix? }) wires resources/list + resources/read + resources/subscribe, advertises the resources capability, and fires notifications/resources/updated from views.onStateChanged. Omit views → tools-only, fully backward-compatible.
  • +8 tests (resources.test.ts); typecheck + build + full workspace test green.

Two-layer discipline held

resources.ts imports nothing from the MCP SDK. The one SDK leak — the resources/read handler's return must satisfy the SDK's broad ServerResult union — is resolved by an upcast to ReadResourceResult in server.ts (the glue layer), not by importing SDK types into the pure layer.

Docs / skills

acture-mcp skill gained a "read side" section and dropped resources from "What NOT to build"; README + hand-written-view-registry + acture-ai-assistant note the shipped package path. Roadmap v1.15 entry + reflection doc.

Still deferred

The getState-tool hedge for tools-only hosts, the keymap-customization helper, and the sideEffect/requiresConfirmation closed-surface question — each awaits its own named need.

(Issue #34 was verified stale and closed before this work, since it sat in the file this extends.)

https://claude.ai/code/session_016teVFousRsWNhiiPNpG1p9

Extend acture-mcp-server with a read-side MCP resources projection — the
state-exposure half of an "operate my app" AI assistant (research-11 §3: the
read side is the industry-wide gap acture is placed to close). First of the
v1.14-deferred package accelerators, pulled forward on a named need.

Kept to acture's precedent: extend the already-published package (additive
minor), no new npm package, no core-surface change. The ViewRegistry primitive
stays the hand-written pattern (docs/hand-written-view-registry.md) — exactly as
macros stayed a pattern while only the tool-bound acture-e2e-playwright earned a
package. The tool-bound piece here is the MCP projection.

- Pure layer (resources.ts, SDK-free): buildResourcesList / readResource /
  viewIdToUri + the ViewSource interface (list / read / onStateChanged — the
  hand-written ViewRegistry subset). Tier-filtered (internal never projected);
  app://state/<id> JSON resources. The app supplies the ViewSource, so
  acture-mcp stays state-library-agnostic.
- Server glue: createMcpServer(registry, { views, resourceUriPrefix? }) wires
  resources/list + resources/read + resources/subscribe, advertises the
  resources capability, and fires notifications/resources/updated from the
  source's onStateChanged. Omit views → tools-only, fully backward-compatible.
- The pure/glue two-layer discipline held: the SDK's ReadResourceResult upcast
  happens only in server.ts; resources.ts imports nothing from the SDK.
- +8 tests (resources.test.ts); typecheck + build + full workspace test green.

Docs/skills: acture-mcp skill gained a "read side" section and dropped resources
from "What NOT to build"; README + hand-written-view-registry + acture-ai-assistant
note the shipped package path. Roadmap v1.15 entry + docs/v1_15-reflection.md.
minor changeset on acture-mcp-server.

Claude-Session: https://claude.ai/code/session_016teVFousRsWNhiiPNpG1p9
@thorwhalen thorwhalen merged commit a78169a into main Jul 6, 2026
1 check passed
@thorwhalen thorwhalen deleted the feat/mcp-resources branch July 6, 2026 06:09
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.

1 participant