fix: make MCP readonly state immutable after construction#3786
fix: make MCP readonly state immutable after construction#3786SeeyaVhora wants to merge 1 commit into
Conversation
Make the readonly state of the MCP server immutable after New() by removing the writeEnabled parameter from Start() and deleting the runtime readonly mutation. Readonly mode is now configured exclusively via WithReadonly(...) during construction. Add an atomic.Bool idempotency guard so repeated Start() calls are safe no-ops. Register mutating tools (deploy, delete) only in writeable mode so exposed MCP capabilities stay aligned with the effective readonly enforcement state. Update the MCPServer interface, mock, and all call sites to match the parameterless Start(ctx) signature. Replace reflection/unsafe-based tests with behavioral capability verification over in-memory MCP transports. Fixes knative#3785
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: SeeyaVhora The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Welcome @SeeyaVhora! It looks like this is your first PR to knative/func 🎉 |
|
Hi @SeeyaVhora. Thanks for your PR. I'm waiting for a knative member to verify that this patch is reasonable to test. If it is, they should reply with Regular contributors should join the org to skip this step. Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
@gauron99 @lkingland Please review this PR and let me know to make any changes. |
|
Your PR is duplicate Ig #3758 |
|
Thanks for the careful fix and tests, @SeeyaVhora — this is well-shaped work. Closing as a duplicate: PR #3758 (by @Elvand-Lie) targets the same MCP readonly-state desync bug (tracked separately as #3755, which #3785 also duplicates) and has been approved/lgtm'd. I want to avoid splitting maintainer review effort. The test coverage you added here is actually more thorough than #3758's — if you'd like to land that as a follow-up PR after #3758 merges, that'd be a welcome contribution. |
|
Got it, thanks for the clarification and for linking the related work. Appreciate the review and feedback. |
Summary
This PR fixes an MCP readonly-state consistency issue where the server readonly mode could be changed during
Start(), even after MCP instructions and tool capabilities had already been generated duringNew().Previously:
WithReadonly(...)Start(ctx, writeEnabled bool)could later silently override the readonly valueThis created a lifecycle inconsistency where:
Fixes #3785
Root cause
The MCP server generated instructions/tool exposure during construction:
However,
Start()later mutated the readonly state again:This allowed the effective runtime enforcement state and the already-generated MCP instructions to drift apart.
What changed
Single source of truth for readonly state
Readonly state is now immutable after construction.
Changes:
Start(ctx, writeEnabled bool)→Start(ctx)WithReadonly(...)This removes the possibility of instruction/runtime desynchronization entirely.
Deterministic lifecycle behavior
Added a lightweight idempotency guard using
atomic.Boolso repeatedStart()calls become safe no-op operations.MCP capability consistency
Mutating MCP tools (
deploy,delete) are now:This keeps exposed MCP capabilities aligned with effective runtime behavior.
Behavioral invariant tests
Added/refined behavioral MCP tests that:
The tests intentionally avoid:
and instead validate behavior through MCP capability exposure.
Behavior changes
WithReadonly(...)+Start(..., writeEnabled)WithReadonly(...)onlyStart()callsWhy this approach
The goal was to fix the root cause by simplifying the lifecycle model instead of adding runtime validation or synchronization logic.
This change:
Verification
Verified with:
All relevant MCP, CLI, and client tests pass successfully.