feat(mcp): MCP resources projection — the AI read side#44
Merged
Conversation
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
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.
What & why
Extends
acture-mcp-serverwith 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
buildToolsListprojects 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. TheViewRegistryprimitive 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-boundacture-e2e-playwrightearned a package. Full rationale:docs/v1_15-reflection.md.Changes
resources.ts, SDK-free):buildResourcesList(views, opts),readResource(views, uri),viewIdToUri, and theViewSourceinterface (thelist/read/onStateChangedsubset of the hand-writtenViewRegistry). Tier-filtered (internalnever projected);app://state/<id>JSON resources. The app supplies theViewSource, so acture-mcp stays state-library-agnostic.server.ts):createMcpServer(registry, { views, resourceUriPrefix? })wiresresources/list+resources/read+resources/subscribe, advertises theresourcescapability, and firesnotifications/resources/updatedfromviews.onStateChanged. Omitviews→ tools-only, fully backward-compatible.resources.test.ts); typecheck + build + full workspace test green.Two-layer discipline held
resources.tsimports nothing from the MCP SDK. The one SDK leak — theresources/readhandler's return must satisfy the SDK's broadServerResultunion — is resolved by an upcast toReadResourceResultinserver.ts(the glue layer), not by importing SDK types into the pure layer.Docs / skills
acture-mcpskill gained a "read side" section and dropped resources from "What NOT to build"; README +hand-written-view-registry+acture-ai-assistantnote 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 thesideEffect/requiresConfirmationclosed-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