Almost every MCP client copied Claude Desktop's configuration shape, which means
almost every client reads its servers out of a mcpServers object.
VS Code does not. It uses servers.
That one word is the single most common reason a VS Code MCP setup silently does nothing: the file parses, the editor starts, and no tools appear, because nothing ever looked at the key you wrote.
The config
{
"servers": {
"spinrun": {
"url": "https://spinrun.ai/mcp",
"headers": {
"x-spinrun-client": "vscode"
}
}
}
}The file lives in your user profile:
macOS ~/Library/Application Support/Code/User/mcp.json
Linux ~/.config/Code/User/mcp.jsonOr run spinrun install vscode and let the CLI merge it in — it knows which key
this client wants, which is exactly the detail worth not remembering.
There is no credential in that block. VS Code opens a browser the first time it connects to the gateway; you choose a workspace there and the tools appear.
What the header does
x-spinrun-client is attribution and carries nothing secret. It is what makes
the activity log able to say a call came from VS Code, which matters the first
time you are trying to work out which of your agents did something. The tools
VS Code then sees are exactly the connections you can see, because it is
authorized as you.
What you get
Your workspace's connected apps, as tools named TOOLKIT_VERB_OBJECT —
GITHUB_CREATE_ISSUE, JIRA_UPDATE_ISSUE, SLACK_SEND_MESSAGE. One HTTP
endpoint, no local processes, no per-vendor OAuth application to register, and
nothing to keep running on your machine.
Rules first, tools second
Set each app's policy before you point an agent at it. Three rows per app — read, write, destructive — each allowed or blocked, enforced at the gateway on every call rather than suggested to the model.
Blocked tools are not offered to VS Code at all, and are refused again if called anyway. The refusal names the rule, which turns "it didn't work" into "that is blocked and here is why".
A worked example
With a tracker and Slack connected:
Read the failing test in this file, open an issue describing it against the
apirepository, and drop the link in #eng.
VS Code reads the test from your working copy, and calls
GITHUB_CREATE_ISSUE and SLACK_SEND_MESSAGE for the rest. The part that used
to require three context switches is now one sentence.
If it still does not work
Three checks, in order:
- The key.
servers, notmcpServers. It is nearly always this. - The file. User profile, not workspace. A
.vscode/mcp.jsonin a project is a different file with different scope. - The restart. VS Code reads this at startup. Reload the window.
Next
- Cursor MCP setup — the same block under the other key
- Agent permissions belong at the gateway
- The toolkit catalogue