fix(devframe): enforce MCP state exposure policy - #336
Merged
Conversation
◈ PR Lens
Architecture 1 component touched across 1 lane. Data flow No data-flow sequence changed in this PR. Drill down
|
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
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.
Why
MCP resource listing honored
exposeSharedState, but directdevframe://state/<key>reads did not. A caller that knew a filtered key could bypass the exposure policy and read shared state that discovery had hidden. This closes that gap so one predicate governs listing, the built-in read tool, and direct resource reads.Implements
plans/003-enforce-mcp-state-policy.md.What
registerResourceHandlersnow resolves the shared-state predicate once viasharedStateFilterand applies it to bothresources/listandresources/read. A direct read of a key that the policy denies (disabled exposure or a filter that excludes it) is rejected with the existingDF0048diagnostic — before any storage access — so a denied key is indistinguishable from a missing one.bootPairtest helper to accept anexposeSharedStatepolicy, and added regression tests proving direct-URI reads can no longer bypass the policy: exposurefalseomits state resources and rejects direct reads, a predicate lists/reads allowed keys and rejects a known denied key, and the state-read tool and resource path agree for the same policy.Verification
pnpm exec vitest run packages/devframe/src/adapters/mcp/__tests__/mcp-server.test.ts— 16 passedpnpm --filter devframe typecheck— passpnpm lint— passpackages/devframesuite — 590 passedNote: repo-wide
pnpm build/pnpm knipfail on pre-existing, unrelated environment issues (a stray write-only artifact inplugins/git/assets-pkg/dist, andstarter/needing built dist), untouched by this change.This PR was created with the help of an agent.