downscoping-mcp
Intercepts GitHub CLI (gh) commands to inject scoped tokens, allowing for least-privilege control over repository, issue, and pull request operations.
Manages credential injection for Google Cloud (gcloud) tools, ensuring that commands are executed with the minimum necessary viewer or editor permissions.
Applies declarative security policies to Kubernetes (kubectl) operations by swapping in the appropriate scoped credentials before command execution.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@downscoping-mcpcheck if gh repo delete is allowed by my current policy"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
downscoping-mcp
Least-privilege credential injection for Claude Code. Intercepts Bash and MCP tool calls before they execute, swapping in the minimum-privilege token required for each operation based on a declarative YAML policy.
Problem
Claude Code runs with whatever credentials are present in your environment. A model that can read files can also call gh repo delete, gcloud projects delete, or aws iam delete-user — using the same token. A single jailbreak, prompt injection, or confused-deputy attack is enough to cause damage.
Solution
Two complementary enforcement modes:
Mode 1 — Bash hook (CLI tools)
A PreToolUse hook intercepts every Bash tool call. If the command starts with a known service binary (gh, gcloud, aws, kubectl), the hook pattern-matches the arguments against your policy rules, selects the appropriate token slot, and rewrites the command to prepend the scoped credential before execution. Claude never sees the rewrite.
Mode 2 — MCP proxy An MCP proxy server wraps an upstream MCP server. Before forwarding each tool call, it injects the scoped token for that specific tool into the subprocess environment. Read-only tools get a read-only token; write tools require an elevated token.
Quick Start
1. Install
pip install -e .2. Configure credentials
Export scoped tokens in your shell profile or CI environment:
export GITHUB_TOKEN_READONLY=ghp_... # fine-grained: contents:read, issues:read
export GITHUB_TOKEN_ORG_WRITE=ghp_... # fine-grained: issues:write, pull_requests:write
export GCLOUD_TOKEN_VIEWER=ya29....
export GCLOUD_TOKEN_EDITOR=ya29....3. Create a policy file
Copy config.example.yaml to .claude/downscoping.yaml in your project root:
cp config.example.yaml .claude/downscoping.yamlEdit the rules to match your org's access model. The file is .gitignore-safe for personal token slot names; the structure itself can be committed.
4. Register the hook
Add to your project's .claude/settings.json:
{
"env": {
"CLAUDE_PLUGIN_ROOT": "/path/to/downscoping-mcp"
},
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/pre_tool_use.py",
"timeout": 5
}
]
}
]
}
}5. (Optional) Enable the MCP proxy
Add to .mcp.json in your project root:
{
"mcpServers": {
"credential-downscope-proxy": {
"command": "python3",
"args": ["-m", "credential_downscope.mcp_proxy"],
"env": {
"PYTHONPATH": "${CLAUDE_PLUGIN_ROOT}/src",
"GITHUB_INTEGRATION_SRC": "/path/to/upstream-mcp-server/src"
}
}
}
}Policy File Reference
version: 1
services:
gh:
token_slots:
readonly:
env_var: GITHUB_TOKEN_READONLY # read from process env
inject_as: GITHUB_TOKEN # injected into subprocess
org-write:
env_var: GITHUB_TOKEN_ORG_WRITE
inject_as: GITHUB_TOKEN
default_slot: readonly # used when no rule matches
rules:
- name: "writes need elevated token"
match:
args_pattern: "pr (create|merge|edit)|issue (create|edit)|push"
slot: org-writeToken resolution order:
Read
env_varfrom the current process environmentIf unset, fall back to the
inject_asvariable (uses the ambient credential)If neither is set, pass the command through unmodified
Architecture
Claude Code
│
├─ Bash tool call ──► PreToolUse hook (hooks/pre_tool_use.py)
│ │
│ ├─ load .claude/downscoping.yaml
│ ├─ detect service binary
│ ├─ match args against rules
│ ├─ resolve token slot
│ └─ rewrite command: TOKEN=value <original command>
│
└─ MCP tool call ──► credential-downscope-proxy (mcp_proxy.py)
│
├─ receive tool call from Claude
├─ match tool name against MCP rules
├─ inject scoped token into env
└─ forward to upstream MCP serverSupported Services
Service | Binary | Token env var pattern |
GitHub CLI |
|
|
Google Cloud |
|
|
AWS CLI |
|
|
Kubernetes |
|
|
MCP servers | via proxy | configurable per server |
Additional services can be added by extending config.yaml — no code changes required.
Security Notes
Token values are
shlex.quote-escaped before shell injection to prevent command injection via crafted token values.Prepending
TOKEN=valuebefore a command makes the token visible in process listings (ps aux). For higher-security environments, use a credential helper that injects tokens via a file descriptor or secrets manager.The hook never blocks commands (exit 0 always); it only rewrites them. Blocking logic can be added by returning
{"continue": false}from the hook..claude/settings.jsoncontaining local paths should be gitignored — see.gitignorein this repo for an example.
Development
pip install -e ".[dev]"
pytest tests/License
MIT
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/kbroughton/downscoping-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server