Skip to content

fix(mcp): defer impl construction so Start's writeEnabled controls readonly#3730

Closed
SarthakB11 wants to merge 1 commit into
knative:mainfrom
SarthakB11:sarth/mcp-readonly-instructions
Closed

fix(mcp): defer impl construction so Start's writeEnabled controls readonly#3730
SarthakB11 wants to merge 1 commit into
knative:mainfrom
SarthakB11:sarth/mcp-readonly-instructions

Conversation

@SarthakB11
Copy link
Copy Markdown

@SarthakB11 SarthakB11 commented May 14, 2026

Problem

mcp.New eagerly constructs the underlying *mcp.Server with
Instructions: instructions(s.readonly). At that point s.readonly
is whatever WithReadonly set it to (default false). Start later
reassigns s.readonly = !writeEnabled, but the Instructions string
is already baked into the impl.

cmd/mcp.go calls mcp.New(mcp.WithPrefix(cmdPrefix)) with no
WithReadonly, then client.StartMCPServer(cmd.Context(), writeEnabled).
writeEnabled defaults to false and only flips when FUNC_ENABLE_MCP_WRITE=1
is set. The default func mcp invocation therefore runs in readonly mode
but ships the non-readonly system prompt. instructions_warning.md is
silently dropped and the agent assumes it can deploy and delete.

TestInstructions did not catch this because newTestPairWithReadonly
threads WithReadonly into New, which already produces the correct
baked Instructions for that call path.

Fix

Move the mcp.NewServer call and the AddTool / AddResource
registration out of New into a buildImpl method. Start invokes
it after s.readonly = !writeEnabled, so the resolved value is the
one baked into Instructions. New's public surface and Options
behavior are unchanged.

Tests

TestInstructionsStartArgDrivesReadonly mirrors the cmd/mcp.go flow:
mcp.New is called without WithReadonly, then Start receives a
concrete writeEnabled. The two subtests (readonly / write)
assert that the readonly warning appears or is absent based on the
Start argument, not on what New saw at construction time.

make check and make test clean.

/kind bug

fix: default `func mcp` invocation now ships the readonly system prompt instead of the write-mode one

@knative-prow knative-prow Bot requested review from gauron99 and lkingland May 14, 2026 19:23
@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented May 14, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: SarthakB11
Once this PR has been reviewed and has the lgtm label, please assign dsimansk for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 14, 2026

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: SarthakB11 / name: SarthakB11 (075aafe)

@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented May 14, 2026

Welcome @SarthakB11! It looks like this is your first PR to knative/func 🎉

@knative-prow knative-prow Bot added needs-ok-to-test 🤖 Needs an org member to approve testing size/M 🤖 PR changes 30-99 lines, ignoring generated files. labels May 14, 2026
@knative-prow
Copy link
Copy Markdown

knative-prow Bot commented May 14, 2026

Hi @SarthakB11. 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 /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions 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.

…adonly

mcp.New eagerly constructed the underlying *mcp.Server with
Instructions: instructions(s.readonly). At that point s.readonly is
whatever WithReadonly set it to, defaulting to false. Start then
reassigns s.readonly = !writeEnabled, but the Instructions string is
already baked into the impl by then.

cmd/mcp.go invokes mcp.New(mcp.WithPrefix(cmdPrefix)) without
WithReadonly, then client.StartMCPServer(cmd.Context(), writeEnabled).
writeEnabled defaults to false; FUNC_ENABLE_MCP_WRITE=1 flips it. The
default invocation therefore runs in readonly mode but ships the
non-readonly system prompt to the connected agent. instructions_warning.md
is silently dropped and the agent assumes it can deploy and delete.

Move the mcp.NewServer call and the AddTool / AddResource registration
out of New and into a buildImpl method invoked from Start after
s.readonly is resolved. New keeps its public surface and Options
behavior unchanged. The existing TestInstructions test still passes
because newTestPairWithReadonly threads WithReadonly into New, which
already produced the correct baked Instructions; the test was unaware
of the default flow.

Add TestInstructions_StartArgDrivesReadonly which mirrors cmd/mcp.go:
mcp.New is called without WithReadonly, then Start receives a concrete
writeEnabled value. Verifies the readonly warning appears or is absent
based on the Start argument, not on what New saw at construction time.

Signed-off-by: SarthakB11 <sarthak.bhardwaj21b@iiitg.ac.in>
@SarthakB11 SarthakB11 force-pushed the sarth/mcp-readonly-instructions branch from 075aafe to ae019ee Compare May 14, 2026 19:32
@gauron99
Copy link
Copy Markdown
Contributor

This seems to be superseded by #3707 which addresses the same issue with a simpler approach.

@lkingland
Copy link
Copy Markdown
Member

lkingland commented May 16, 2026

Thanks for the contribution, but closing this one as a duplicate

@lkingland lkingland closed this May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-ok-to-test 🤖 Needs an org member to approve testing size/M 🤖 PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants