fix(mcp): only complete the project, and only when nothing was scoped - #1116
Merged
Conversation
Live testing of the injection that #1115 carried onto master found it corrupts explicitly cross-project calls, which is one of the things the remote MCP is for. Reproduced by hand: ask get-logs for another project's service and pass that project's id, but omit the environment. The proxy filled the environment from the directory link, the server checked the linked environment against the caller's project, and denied the request with "You don't have the required role (viewer) on this resource." Supplying the environment explicitly made the same call succeed. Injection, not permissions. A second, quieter shape: a serviceId from elsewhere with no projectId got the linked project stapled on, so the failure came back as "No deployment found for this service and environment" — which reads to a model as "that service does not exist" rather than "you did not say which project". Two changes: - Only projectId is completed. environmentId and serviceId are subordinate to a project; the server defaults the environment where that is safe and requires both explicitly on the destructive tools, where guessing is worse than asking. LinkContext collapses to the one field, so there is no longer a way to pair one project's id with another's resources. - Nothing is completed when the call already names a projectId, environmentId, serviceId or deploymentId. A caller that named a resource has its own intent; it should get a plain "projectId Required" and correct itself, not a project we guessed. This costs nothing measurable. Of ~80,000 successful local MCP calls on 2026-08-19, the project-omitted/service-supplied combination occurred exactly zero times — callers supply full context or none — and the ~39,800 that supply none still get served, which is the population the injection exists for. Requests the proxy completed now carry x-railway-mcp-injected. Injection is otherwise indistinguishable server-side from a caller's own argument, so nothing could measure how often it fires or recognise it in a report of "the agent looked at the wrong project". Co-Authored-By: Claude Opus 5 (1M context) <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 the link-context injection #1115 carried onto master. Not in a published release yet (v5.42.1 predates it, v5.43.0 is a draft).
Problem
Injection breaks explicit cross-project calls. From a directory linked to project A, asking about project B:
get-logs+ B'sprojectId+ B'sserviceId, no environmentYou don't have the required role (viewer)environmentIdThe proxy filled
environmentIdfrom A's link; the server checked it against B's project and denied it.Also: a
serviceIdfrom elsewhere with noprojectIdgets the linked project attached, so the error isNo deployment found for this service and environment— which reads as "that service doesn't exist".Solution
projectId.environmentId/serviceIdare subordinate to a project; the server defaults the environment where safe and requires both on destructive tools.LinkContextdrops to one field.projectId,environmentId,serviceId,deploymentId) — that caller getsprojectId Requiredand self-corrects.x-railway-mcp-injected, so this is measurable. Recording it is a backboard follow-up.Free, per ~80,000 local MCP calls on 2026-08-19:
Verified
Against production from a
railbot-linked directory: no-args → railbot; foreignserviceId→projectId Required; explicit cross-project → works (was broken). 15 link-context tests, 1,203 total, 0 clippy findings inproxy.rs.No cutover —
railway mcpunchanged. #1108 should be closed rather than merged; its content is already on master via #1115.🤖 Generated with Claude Code