Permissions and access

Scope each MCP tool's token before you launch its server

You'll create dedicated least-privilege tokens for each MCP server and wire them into launch config, so a leaked token is limited to what that tool really needs and is not committed to disk.

  1. List tool operationsOnly actions the server actually needs
  2. Create scoped tokenDedicated credential per tool
  3. Wire via input prompts${input:...} / password: true in VS Code
  4. Launch MCP serverUse scoped credential, not remote bearer
  5. Run a normal requestWiden only missing scope if needed

Why it matters

The Sentry thread is a good warning: the remote endpoint is OAuth-only, token auth has not been prioritized, and people in sandboxed environments ended up reimplementing tools instead of using a bearer token (thread (opens external site)). If you paste a broad personal token into an MCP config anyway, you have created a long-lived credential that can reach far beyond the one tool. You want each MCP server to run with a dedicated token whose scopes match only the operations that tool performs, and to keep that token out of committed config.

Steps

  1. List the operations each MCP tool actually needs, then create one dedicated credential per tool with only those scopes. Don't reuse a full-access personal token; a leak in one server should not become a key to everything.

  2. Prefer OAuth for interactive clients when the provider supports it. If you use MCP Inspector, be careful: it is designed as a public client. A proposed fix for issue #683 would let the guided OAuth flow use a manually entered client ID, but it does not support a client secret. The thread says it should be fixed by PR #684 but does not confirm the PR was merged or verified, so check your build before relying on that behavior.

  3. Wire the credential into the server config without writing it to disk. In VS Code, the team's tracking issue proposed configuring MCP servers in .vscode/mcp.json or an mcp section in settings.json. Its base example follows Claude Desktop's shape:

json
{
  "mcpServers": {
    "postgres-server": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"],
      "env": {}
    }
  }
}

The same thread's second sample uses a top-level servers key, so the key name is not settled in the thread. For secrets, it proposed reusing the inputs mechanism with ${input:...} references and password: true, so the secret is prompted and not committed.

  1. For headless service accounts that cannot finish an OAuth redirect, bind the access token to the stdio binary rather than a remote HTTP endpoint. For Sentry, a maintainer suggested executing npx @sentry/mcp-server; the remote endpoint remains OAuth-only, and the Authorization: Bearer <token> header was only a proposal, not tested or confirmed.

  2. Rotate tokens that have already been pasted into chats, logs, or config files, and create a fresh scoped token before launching. If you don't know whether a token leaked, treat it as exposed.

  3. Launch the server and run one normal request. If the scoped token is too narrow, widen only the missing scope and test again. Avoid starting with a broad token and trying to shrink it later.

Common mistakes

  • Committing a real token in .vscode/mcp.json, .mcp.json, or an env block; use the input-prompt or secret-storage route instead.
  • Assuming the remote Sentry endpoint accepts Authorization: Bearer <token>; the thread shows that was only a proposal and the endpoint is OAuth-only.
  • Reusing one broad access token across every MCP tool; a single incident then exposes everything that token can reach.
  • Trying to configure MCP Inspector with a client secret; the proposed change supports only a manually entered client ID because Inspector acts as a public client.

Checklist

0 of 8 done

Sources

  1. MCP Inspector OAuth: how to use a manually entered client ID instead of dynamic client registration?
  2. Where are MCP servers configured in VS Code and how do I pass secrets?
  3. Does the remote Sentry MCP endpoint support a bearer access token instead of OAuth?
Was this guide useful?