Skip to main content
Glama
SarutobiSasuke8

credential-broker-mcp

Credential Broker MCP

A local-first MCP server that lets AI agents use gated APIs without ever holding the keys.

The agent asks the broker to make a request. The broker canonicalises the URL, checks a declarative per-operation policy, verifies any required approval at execution time, injects the secret at the last moment, calls the upstream, redacts and filters the response, and writes a content-free audit record. The secret lives with the broker process and is never relayed to the agent in any representation the broker creates: raw, Base64, base64url, percent-encoded, form-encoded, or Unicode-normalised. An upstream that transforms a secret with a one-way function of its own defeats string matching; scoped operations and metadata-only responses are the defence there, and SECURITY.md states this boundary honestly.

Pre-release. Nothing is published to npm yet. Treat main as a work in progress until a tagged v0.1.0 exists.

Why

Giving an agent an API key gives it everything the key can do, for as long as the key lives, invisibly. Most agent tasks need a fraction of that: read these repos, query this endpoint, GET but never DELETE. This broker turns "here is my key" into "here is a scoped, observable capability":

  • Possession vs use. Agents exercise credentials; they never possess them.

  • Deny-by-default. Authority is an enumerated list of named operations per credential. An absent grant is a denial, not an oversight. Deny rules always beat grants.

  • Nothing widens sideways. A method, path, query parameter, body rule, or approval attached to one credential never widens any other credential.

  • One decision function. The dry-run explainer and the live request path call the same evaluate(). What the broker reports and what it enforces cannot drift apart.

  • Content-free audit. Who reached what, when, with what outcome, and through which lifecycle state. Never what they saw.

Related MCP server: mcp-devtools

Tools

Tool

What it does

broker_whoami

Show the authenticated agent and its per-credential operation grants.

broker_list_credentials

Granted credentials: id, kind, base URL, provisioned or not. Never values.

broker_explain_request

Dry run: would this request be permitted, which rule decides it, and is an approval required or satisfied? No upstream call, no secret touched.

broker_read

GET or HEAD through a granted credential. Honestly annotated read-only.

broker_mutate

POST, PUT, PATCH, or DELETE. Annotated destructive and non-idempotent, because its strongest capability is. May require an approval and an idempotency key.

Policy (version 2)

One YAML file declares credentials and per-credential operation grants:

version: 2
credentials:
  - id: github-readonly
    kind: bearer                 # bearer | header | basic | query
    env_var: GITHUB_READONLY_TOKEN
    base_url: https://api.github.com

agents:
  - id: researcher
    grants:
      - credential: github-readonly
        operations:
          - id: read-repo
            method: GET
            path: /repos/*/*     # literal segments, '*', or trailing '**'
            response_body: true  # default is metadata only
        deny:
          - /repos/*/*/keys

A request must clear every gate: identity provisioned and enabled, credential granted, URL canonical and provably unambiguous, origin exactly the credential's origin, path inside the credential's base path, no deny match, and an operation whose method, path template, query parameter allowlist, and body rule all match. broker_explain_request reports which gate decided any outcome.

Semantics worth knowing:

  • Operation paths are relative to the credential's base path. With base_url: https://api.example.com/v2, the template /weather authorises /v2/weather.

  • Path matching is case-sensitive for operations and case-insensitive for deny rules, because many upstreams treat paths case-insensitively.

  • Query parameters not named in query_params are denied.

  • Operations without a body rule reject any request body. Body rules name allowed content types and a byte cap. Mutations must declare requires_approval explicitly, true or false.

  • Responses default to metadata only. response_body: true relays the body, and only for content types in response_content_types (default application/json).

  • Credentials of kind query must set high_risk: true: URLs are commonly retained by upstream and proxy telemetry, so a query-string secret has a wider blast radius than a header.

Approvals

An operation with requires_approval: true executes only when the request carries an approval_id that exists in the approval store, is bound to exactly this principal, credential, and operation, is unexpired, and is not revoked, checked at execution time, not config-load time. On stdio the store is a JSON file (config/approvals.json by default) that is re-read on every check, so editing it revokes access mid-flight:

[
  {
    "id": "apr-2026-08-13-01",
    "agent_id": "researcher",
    "credential_id": "github-readonly",
    "operation_id": "create-issue",
    "expires_at": "2026-08-14T00:00:00Z",
    "revoked": false
  }
]

Migrating from version 1

Version 1 policies shared one method list and path set across every credential an agent held, so authority needed for one credential widened all of them. The broker refuses v1 files. Convert with:

npm run migrate -- config/broker.yaml > config/broker-v2.yaml

The output is deliberately conservative (mutations require approval, query parameters must be enumerated) and flagged for review: it makes the old blast radius visible rather than silently preserving it.

Safety properties

  • Every URL is canonicalised once; policy and the outbound request consume the same canonical value, and the outbound bytes are round-trip checked. Encoded separators, double encoding, control characters, backslashes, userinfo, non-ASCII path segments, repeated or trailing slashes, and trailing-dot segments are rejected, not guessed at.

  • Secrets are injected into exactly one header or query parameter. One redactor covers response bodies, relayed headers, error chains, and audit records, across raw, Base64, base64url, percent-encoded, form-encoded, and NFC/NFD representations, including truncation boundaries.

  • Raw upstream error text is never relayed to agents; they receive a stable error category and a trace id, and the redacted detail goes to the audit log.

  • Redirects are refused: a redirect could point anywhere, and fetch would re-send the injected credential there.

  • A credential can only be exercised against its exact origin and base path; lookalike hosts and string-prefix tricks are refused.

  • Plain-http upstreams are rejected at policy load, except on loopback.

  • Response headers are allowlisted; Set-Cookie and friends are dropped.

  • Responses are size-capped per operation, metadata-only by default.

  • Mutations are a separate, honestly-annotated tool; approval state is checked at execution time; a dispatch failure on a mutation is recorded as indeterminate, never silently retried.

  • Every decision is audited through its full lifecycle without request or response content, and audit records pass through the redactor too.

Identity boundary

On stdio, BROKER_AGENT_ID is a trusted-launcher assertion: the operator starting the process vouches for which agent is connected. It is only a real boundary when the broker runs under the secure-launch profile in SECURITY.md: dedicated OS identity, owner-only policy/approvals/audit files, a fixed identity wrapper the agent cannot edit, and no agent-readable secret environment. The broker loads only its principal's secrets and scrubs every policy credential variable from its environment after loading. One broker process serves one principal; never share a process between agents.

Running

npm install
cp config/broker.example.yaml config/broker.yaml   # then edit
BROKER_AGENT_ID=researcher npm start

Environment:

Variable

Meaning

BROKER_AGENT_ID

Identity this stdio session runs as. Required.

BROKER_POLICY_FILE

Policy path. Default config/broker.yaml.

BROKER_AUDIT_FILE

Audit log path. Default data/audit.jsonl.

BROKER_APPROVALS_FILE

Approval store path. Default config/approvals.json.

(per credential)

Each credential's env_var carries its secret.

Claude Code registration (once published; see the pre-release note above):

{
  "mcpServers": {
    "credential-broker": {
      "command": "npx",
      "args": ["-y", "@sarutobi-sasuke/credential-broker-mcp"],
      "env": { "BROKER_AGENT_ID": "researcher" }
    }
  }
}

What this is not

  • Not an OAuth authorization server. It brokers static secrets you already hold. OAuth token acquisition and refresh are on the roadmap.

  • Not a cloud service. It runs where your agents run, and your secrets stay on your machine. If you want hosted multi-tenant auth for agents, use a platform built for that.

  • Not a bypass. It delegates through existing gates with scoped-down authority; it does not defeat anything.

Roadmap

  • OAuth 2.1 device and refresh flows for credentials that expire

  • HTTP transport with mutually authenticated, audience-bound, expiring principal tokens through the same engine, matching agent-handoff-mcp

  • Per-credential rate limits and spend counters

  • Operator CLI: provision, rotate, revoke, approve

Licence

Apache 2.0. See LICENSE.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
13hResponse time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Open-source MCP proxy that enforces security policies, content scanning, and audit logging between AI agents and tool servers
    25
    AGPL 3.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server that lets AI agents call APIs without ever seeing the credentials, using a local encrypted vault and per-secret allowlist policies for HTTP requests and subprocess environment variables.
    1
    AGPL 3.0
  • A
    license
    Not graded
    quality
    A
    maintenance
    A local-first control plane for AI agent tools, providing policy enforcement, spend caps, rate limiting, and audit trails for MCP servers.
    1
    Apache 2.0

View all related MCP servers

Related MCP Connectors

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • MCP server for secureFlows: token-free URL builders and integration-linting tools for AI agents.

  • Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.

View all MCP Connectors

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/SarutobiSasuke8/credential-broker-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server