Repository navigation
Conversation
The MCP production guard only rejected deployment selectors of kind `prod`. A selector that names the production deployment another way, like `--deployment-name <name>`, `--deployment prod` or a production deploy key, passed it. So `run`, the env tools, `data`, `logs` and `runOneoffQuery` worked against production without `--dangerously-enable-production-deployments`, and `status` reported `readOnly: false` for those selectors. The guarded tools now also check the type of the deployment the selector resolved to, and `status` marks deployments read-only by that type. Selectors of kind `prod` are still rejected before they're resolved, since resolving one can provision a production deployment. Fixes convex#544 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
All reported issues were addressed across 9 files
Reply to a comment to ask cubic a question or push back. It learns from your replies.
Re-trigger cubic
The mock of `loadSelectedDeploymentCredentials` returned production credentials for any selection, so a tool that resolved the wrong selection still passed. The mock now resolves each selection to its own deployment and throws for any other. The tests now also cover development deployments. Each guarded tool must get past the guard for them, and `status` must not mark them read-only. Reading the admin key of the mocked credentials throws, so no request leaves the tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Fixes #544
Problem
The MCP production guard checks the deployment selector's
kind, and only rejectskind: "prod". A selector can name the production deployment in other ways:mcp start --deployment-name <prod deployment>giveskind: "deploymentName".mcp start --deployment prod(orteam:project:prod) giveskind: "deploymentSelector".CONVEX_DEPLOY_KEYkeepskind: "unspecified".None of these is caught. So
run,envList,envGet,envSet,envRemove,data,logsandrunOneoffQuerywork against production without--dangerously-enable-production-deployments.statusalso reportsreadOnly: falsefor these selectors, which tells agents that every tool is allowed.Fix
loadSelectedDeploymentCredentials, they callctx.checkResolvedDeployment(credentials)orctx.checkResolvedDeploymentReadOnly(credentials). The check isdeploymentFields.deploymentType === "prod", the same testconvex runuses.kind === "prod"check indecodeDeploymentSelectorstays. It rejectsprodselectors before they're resolved, because resolving one can provision a production deployment.statussetsreadOnlyfrom the resolved deployment type instead of the selector's kind.Self-hosted deployments (
--url/--admin-key) have no deployment type, so they behave as before.Behavior change
Starting the server with
--deployment-name <prod deployment>and no production flag now gives the same errors as--prod. The docs already describe this behavior, but anyone who relied on the gap will notice.This also matters for #545. Once deploy keys work with the MCP server, the guard will cover a production deploy key too.
Tests
There were no MCP tests, so I added two files:
requestContext.test.tscovers the new checks for each deployment type and flag combination.tools/index.test.tsmocks deployment resolution. The mock resolves each selector to its own deployment and throws for any other selector.prod, andteam:project:prod. Each tool must reject them before it reads the admin key.readOnlyflag fromstatus.Without the fix, 26 of the 44 tool tests fail: all 24 production tool tests and 2
statustests. With the fix, all 63 tests pass.tsc,eslintandprettier --checkpass on the changed files.Notes
--deployment-name), with--deployment prod, or with a production deploy key."By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.
🤖 Generated with Claude Code