MCP Credentials Broker

MCP Credentials Broker

Provides secure OAuth2-based credential management for MCP servers, allowing agents to obtain short-lived token references without exposing raw secrets.

Category
访问服务器

README

MCP Credentials Broker

A secure credential management layer for Model Context Protocol (MCP) servers. Authenticate providers via browser — no hardcoded API keys, no tokens pasted into chat.

Why Use This?

If you're building MCP servers that need to access external APIs (GitHub, Google, Azure, etc.), you've probably hardcoded API keys in environment variables or pasted tokens into chat. This broker solves that by:

  • Authenticating providers via browser OAuth2 — you just log in, the broker handles the rest
  • Issuing short-lived references instead of exposing raw tokens to the agent
  • Centralizing credential management across all MCP servers in a single session

How It Works

You say: "List my GitHub repos"

Agent:
  1. Checks if github-token is already stored
  2. If not → triggers browser OAuth flow → you log in → token stored
  3. Gets a short-lived reference to the token
  4. Resolves the reference to the actual value (never shown to you)
  5. Passes the token to your GitHub MCP tool

The agent handles all of this automatically via the included rules file — you never paste a token.

Installation

npm install @ars-system/mcp-credentials-broker

Or clone and build from source:

git clone https://github.com/ars-system/mcp-credentials-broker.git
cd mcp-credentials-broker
npm install
npm run build

Configuration

Step 1 — Get provider credentials (one-time)

The broker needs a client_id and client_secret for each provider you want to use. These are set once as environment variables — the agent never sees or asks for them.

GitHub

  1. Go to github.com/settings/developers
  2. Click OAuth Apps → New OAuth App
  3. Fill in:
    • Application name: MCP Credentials Broker (or anything)
    • Homepage URL: http://localhost
    • Authorization callback URL: http://localhost:9876/oauth/callback
  4. Click Register application
  5. Copy the Client ID
  6. Click Generate a new client secret and copy it
GITHUB_CLIENT_ID=your-client-id
GITHUB_CLIENT_SECRET=your-client-secret

Google

  1. Go to console.cloud.google.com/apis/credentials
  2. Click Create Credentials → OAuth client ID
  3. Application type: Web application
  4. Add to Authorized redirect URIs: http://localhost:9876/oauth/callback
  5. Copy the Client ID and Client Secret
GCP_CLIENT_ID=your-client-id
GCP_CLIENT_SECRET=your-client-secret

Azure

  1. Go to portal.azure.com → Azure Active Directory → App registrations
  2. Click New registration
  3. Name it anything, select Accounts in any organizational directory and personal Microsoft accounts
  4. Set redirect URI to: http://localhost:9876/oauth/callback (type: Web)
  5. After creation, go to Certificates & secrets → New client secret
  6. Copy the Application (client) ID and the secret value
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret

Okta

  1. Go to your Okta Admin Console → Applications → Create App Integration
  2. Select OIDC - OpenID Connect → Web Application
  3. Add http://localhost:9876/oauth/callback to Sign-in redirect URIs
  4. Copy the Client ID and Client Secret
  5. Also set your Okta domain:
OKTA_CLIENT_ID=your-client-id
OKTA_CLIENT_SECRET=your-client-secret
OKTA_DOMAIN=your-org.okta.com

Step 2 — Configure your MCP client

Add the broker alongside your other MCP servers. Pass the provider env vars in the env block:

{
  "mcpServers": {
    "credentials-broker": {
      "command": "node",
      "args": ["/path/to/mcp-credentials-broker/dist/index.js"],
      "env": {
        "GITHUB_CLIENT_ID": "your-github-client-id",
        "GITHUB_CLIENT_SECRET": "your-github-client-secret",
        "GCP_CLIENT_ID": "your-gcp-client-id",
        "GCP_CLIENT_SECRET": "your-gcp-client-secret"
      }
    },
    "your-github-mcp": {
      "command": "node",
      "args": ["/path/to/your-github-mcp/dist/index.js"]
    }
  }
}

Only configure the providers you actually use. You don't need all of them.


Step 3 — Add the agent rules (for Amazon Q / Claude / Cursor)

Add the following rules to your agent configuration (e.g., in .amazonq/rules/credentials-broker.md or your agent's custom rules file). These rules ensure the agent always uses the broker automatically and never asks you for tokens.

Copy the entire section below:

# Credentials Broker — Agent Rules

You have access to a `credentials-broker` MCP server. Follow these rules strictly.

## Rule 1 — Never ask the user for API tokens, passwords, or secrets

If a task requires a token (GitHub, Google, Azure, AWS, etc.), use the broker to obtain it.
Never ask the user to paste a token into the chat.

## Rule 2 — Check if a token is already stored before authenticating

Before triggering an OAuth flow, always check if the token already exists:

get_secret(name: "<provider>-token", purpose: "check")


If it succeeds, use that reference. Only call `start_oauth_flow` if the secret is missing or expired.

## Rule 3 — OAuth flow requires no credentials from the user

Call `start_oauth_flow` with only `provider`, `scopes`, and `secret_name`.
The broker reads `client_id` and `client_secret` from its own environment — you must NOT ask the user for these.

start_oauth_flow( provider: "github", scopes: ["repo", "read:user"], secret_name: "github-token" )


Tell the user: "A browser window will open for you to log in. Come back here once done."

## Rule 4 — Standard token retrieval pattern

Every time you need a token to pass to another MCP tool, follow this exact sequence:

**Step 1** — Get a short-lived reference:

get_secret(name: "github-token", purpose: "<what you're doing>", ttl_seconds: 3600) → returns { reference: { id: "ref-uuid" } }


**Step 2** — Resolve the reference to the actual value:

resolve_secret(reference_id: "ref-uuid") → returns { value: "gho_actualtoken..." }


**Step 3** — Pass `value` to the target MCP tool's token/auth parameter.

## Rule 5 — Never log or display raw token values

After calling `resolve_secret`, use the value directly in the next tool call.
Do not print it, summarize it, or include it in any response to the user.

## Rule 6 — Naming convention for stored secrets

Use consistent names so tokens can be reused across tool calls in the same session:

| Provider | secret_name        |
|----------|--------------------|
| GitHub   | `github-token`     |
| Google   | `google-token`     |
| Azure    | `azure-token`      |
| Okta     | `okta-token`       |
| Custom   | `<service>-token`  |

## Rule 7 — Provider configuration errors

If `start_oauth_flow` fails with "not configured", tell the user:
> "The broker needs `<PROVIDER>_CLIENT_ID` and `<PROVIDER>_CLIENT_SECRET` set as environment variables where the broker is running. These are set once by you — I won't ask for them again."

## Summary flow

Need a token? └─ get_secret("github-token") → exists? → resolve_secret → use it → missing? → start_oauth_flow → get_secret → resolve_secret → use it



Available Tools

start_oauth_flow

Opens the browser for you to log in. Stores the resulting token under secret_name. No credentials needed from you — the broker reads client_id and client_secret from its environment.

Parameter Required Description
provider yes github, google, azure, okta, oauth2
scopes yes List of OAuth2 scopes to request
secret_name yes Name to store the token under
authorization_endpoint no Custom auth URL (only for okta / oauth2)
token_endpoint no Custom token URL (only for okta / oauth2)
{
  "provider": "github",
  "scopes": ["repo", "read:user"],
  "secret_name": "github-token"
}

get_secret

Issues a short-lived reference to a stored secret. Returns a reference ID, not the raw value.

Parameter Required Description
name yes Name of the stored secret
purpose yes Why you're requesting it (for audit)
ttl_seconds no How long the reference is valid (default: 3600)
{
  "name": "github-token",
  "purpose": "listing repositories",
  "ttl_seconds": 3600
}

Response:

{
  "reference": {
    "id": "ref-uuid",
    "name": "github-token",
    "expiresIn": 3600
  }
}

resolve_secret

Resolves a reference ID to the actual token value. Used by the agent immediately before passing the token to another MCP tool.

Parameter Required Description
reference_id yes The id returned by get_secret
{ "reference_id": "ref-uuid" }

Response:

{ "value": "gho_actualtoken..." }

store_secret

Manually store a secret (e.g. a static API key). Use get_secret + resolve_secret to retrieve it later.

Parameter Required Description
name yes Identifier for the secret
value yes The secret value
tags no Key-value tags for organization

mint_token

Generates a short-lived JWT-based token scoped to a provider. Useful when you want a broker-issued token rather than a raw OAuth token.

Parameter Required Description
provider yes github, aws, gcp, azure, oauth2, okta
scopes yes List of scopes/permissions
resource no Resource identifier
ttl_seconds no Token lifetime (default: provider default)

revoke_token

Immediately invalidates a minted token.

Parameter Required Description
token_id yes ID of the token to revoke

get_broker_stats

Returns counts of active tokens, active references, and stored secrets.


End-to-End Example

You:   "Create a GitHub issue in my repo"

Agent: 1. get_secret("github-token")           → not found
       2. start_oauth_flow(                     → browser opens
            provider: "github",
            scopes: ["repo"],
            secret_name: "github-token"
          )                                     → you log in → token stored
       3. get_secret("github-token",            → { id: "ref-abc" }
            purpose: "create issue")
       4. resolve_secret("ref-abc")             → { value: "gho_..." } ← never shown to you
       5. github-mcp/create_issue(              → issue created ✓
            token: "gho_...",
            title: "..."
          )

Provider TTL Limits

Provider Default TTL Max TTL
GitHub 1 hour 8 hours
AWS 1 hour 12 hours
GCP 1 hour 12 hours
Azure 1 hour 12 hours
Okta 1 hour 12 hours
OAuth2 (generic) 1 hour 24 hours

Architecture

┌──────────────────────────────────────────────────────┐
│                MCP Credentials Broker                │
├──────────────────────────────────────────────────────┤
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │           OAuth Web Flow                    │    │
│  │  - Spins up local HTTP server on :9876      │    │
│  │  - Opens browser to provider auth URL       │    │
│  │  - Receives callback with auth code         │    │
│  │  - Exchanges code for access token          │    │
│  └─────────────────────────────────────────────┘    │
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │           Credentials Manager               │    │
│  │  - In-memory secret storage                 │    │
│  │  - Short-lived reference issuance           │    │
│  │  - Token lifecycle & auto-expiry            │    │
│  │  - Provider config from env vars            │    │
│  └─────────────────────────────────────────────┘    │
│                                                      │
│  ┌─────────────────────────────────────────────┐    │
│  │           MCP Server Interface               │    │
│  │  - Tool definitions & request handling      │    │
│  └─────────────────────────────────────────────┘    │
│                                                      │
└──────────────────────────────────────────────────────┘

Security Notes

  • Tokens are stored in memory only — they are lost when the broker process restarts
  • Raw token values are never returned by get_secret — only reference IDs
  • The agent rule file instructs the agent to never display resolved token values
  • Set JWT_SECRET env var in production to sign broker-issued tokens securely
  • The OAuth callback server only runs during an active start_oauth_flow call, then shuts down

Development

npm run watch   # TypeScript watch mode
npm run build   # Build
npm run dev     # Build + run
npm run lint    # Lint

Contributing

Contributions welcome! Please follow existing TypeScript patterns and maintain proper type definitions.

License

MIT — see LICENSE file for details

Resources


Built by @ars-system • Report Issues

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选