Skip to main content
Glama
MithrynMarious

Agent Keyring

Agent Keyring

An MCP server that holds secrets and makes authenticated API calls on behalf of AI agents — so API keys never enter conversation context.

Agent → Keyring MCP → retrieve secret → make API call → return data only

The agent says what to do ("query GA4 for sessions"). The keyring handles how to authenticate. Keys stay on the keyring, never in the agent's mouth.

Quickstart

# 1. Clone
git clone https://github.com/MithrynMarious/agent-keyring.git
cd agent-keyring

# 2. Create a virtual environment and install
python3 -m venv .venv
source .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install .

# 3. Copy the skeleton and fill in your keys
cp .secrets.skeleton.json .secrets.json
# Edit .secrets.json — replace placeholders with real values

# 4. Add to your MCP config (.mcp.json or Claude Desktop settings)

Add to your MCP config file:

Claude Code.mcp.json in your project root:

{
  "mcpServers": {
    "keyring": {
      "command": "python",
      "args": ["server.py"],
      "cwd": "/path/to/agent-keyring"
    }
  }
}

Claude Desktop — config file location varies by OS:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

  • Linux: ~/.config/Claude/claude_desktop_config.json

Same JSON format — add the keyring entry to your existing mcpServers block.

# 5. Verify
python -c "from secret_store import LocalFileStore; s = LocalFileStore('.secrets.json'); print(f'{len(s.list_names())} secrets loaded')"

Related MCP server: keyvault

What's Working

Component

Status

Notes

Local file store

Active

.secrets.json backend, PASTE_FROM references

GCP Secret Manager store

Active

Multi-machine, 3 auth paths (SA key, ADC, GCE metadata)

GA4 adapter

Active

OAuth + service account JWT, report formatting

AgentMail adapter

Active

Bearer token auth, inbox/thread operations

Stripe adapter

Active

Charges, customers, subscriptions (read-only)

Supabase adapter

Active

Table queries via PostgREST, auth admin

Anthropic adapter

Active

Messages API, model listing

GitHub adapter

Active

Repos, issues, PRs via REST API

Discord adapter

Active

Channel messages, webhooks

Identity verification

Active

DID primary, AgentMail fallback

Checkout ledger

Active

Append-only JSONL, agent affinity analysis

Key health monitor

Active

Connectivity checks, rotation tracking, HTML dashboard

Service taxonomy

Active

6 archetypes, 60+ ecosystem entries

Permissions

Active

Per-agent, per-secret access control

MCP Tools

Tool

What It Does

keyring_list_available

List secrets the agent can access (names only, never values)

keyring_authenticated_request

Make an API call using a managed secret

keyring_checkout_history

Query who accessed what, when, and why

keyring_agent_affinity

Analyze agent-service usage patterns

Security Model (DC-1)

Secret values never appear in:

  • MCP tool results

  • Conversation context

  • Log output

  • EAM entries or session records

The keyring makes the authenticated API call and returns only the response data. The checkout ledger logs every access (who, what, when, why) without recording the secret value.

Docs

  • SETUP.md — Full setup guide with GCP migration, troubleshooting, and embedded lessons from prior setups

  • FRICTION_JOURNAL.md — GCP console gotchas (training-data-vs-reality deltas)

  • AGENTS.md — Engineering posture and conventions

Populating Secrets

Scan a machine for scattered credentials, collect them, and populate the keyring:

python consolidate.py bootstrap ~/projects ~/.config ~/keys
# Scans → migrates → ingests → validates. Values stay on disk, never in stdout.

Add --dry-run to preview without changing anything. DC-1 safe: the bootstrap prints filenames and counts, never secret values.

Manual paths

# Interactive (value from stdin, never CLI args)
python add_secret.py my-api-key

# From files
mkdir -p .secrets
# Place key files in .secrets/
python consolidate.py ingest

# Bulk discovery
python consolidate.py scan ~/projects    # find scattered creds
python consolidate.py migrate ~/projects --target .secrets/

GCP Backend (Multi-Machine)

For shared secrets across machines, use GCP Secret Manager as the backend:

{
  "mcpServers": {
    "keyring": {
      "command": "python",
      "args": ["server.py"],
      "env": { "KEYRING_GCP_PROJECT": "your-project-id" }
    }
  }
}

See SETUP.md Option B for the full GCP walkthrough.

Registering Agents

New agents are denied access by default (DC-1). To grant an agent access to secrets, add an entry to permissions.json:

{
  "agent-name@agentmail.to": ["secret-name-1", "secret-name-2"],
  "admin-agent@agentmail.to": ["*"],
  "_default": []
}
  • Each key is an agent identifier (AgentMail address or DID)

  • Values list the secret names the agent can check out

  • "*" grants access to all secrets

  • "_default": [] means unregistered agents get nothing — this is the DC-1 structural default

When an unregistered agent calls keyring_list_available, it sees an empty list. The checkout ledger still records the attempt.

Environment Variables

See .env.example for the complete list. Key variables:

Variable

Required

Default

Purpose

KEYRING_GCP_PROJECT

For GCP backend

Selects GCP Secret Manager over local file

KEYRING_SECRET_STORE

No

.secrets.json

Local store file path

KEYRING_SECRETS_ROOT

No

3 dirs up

Root for PASTE_FROM: path resolution

GOOGLE_APPLICATION_CREDENTIALS

For GCP SA auth

GCP service account key file

Logging

The server uses Python's logging module. Set the log level via environment:

# See all keyring activity
LOGLEVEL=DEBUG python server.py

# Quiet mode (errors only)
LOGLEVEL=ERROR python server.py

Default level is WARNING. The keyring.store and keyring.ledger loggers are the most useful for debugging auth and access issues.

Troubleshooting

Symptom

Cause

Fix

0 secrets loaded

.secrets.json missing or empty

Copy .secrets.skeleton.json to .secrets.json and fill in values

PASTE_FROM file not found

KEYRING_SECRETS_ROOT not set or wrong

Set it to the parent directory of your .secrets/ folder

No adapter registered for service

Service name doesn't match a registered adapter

Check keyring_list_available output for exact service names

Agent sees empty list

Agent not in permissions.json

Add the agent's identifier to permissions.json with allowed secrets

GCP 403 Permission denied

Service account lacks Secret Manager access

Grant roles/secretmanager.secretAccessor to the SA in GCP console

GCP 404 Secret not found

Wrong prefix or secret name

Check KEYRING_GCP_PREFIX — secret is stored as {prefix}{name} in GCP

Stale secret value from GCP

Cache TTL hasn't expired

Set KEYRING_GCP_CACHE_TTL=0 or restart the server

401 from adapter API call

Secret value is expired or invalid

Rotate the key in .secrets.json or GCP, then restart

For GCP-specific setup issues, see SETUP.md and FRICTION_JOURNAL.md.

Docker

# Local file store
docker compose up keyring

# GCP backend
KEYRING_GCP_PROJECT=your-project docker compose --profile gcp up keyring-gcp

Mount your .secrets.json and permissions.json as volumes. See docker-compose.yml for the full configuration.

CI

Tests run on push and PR via GitHub Actions across Python 3.12–3.13 on Linux, Windows, and macOS. See .github/workflows/test.yml.

License

Proprietary — CoreForged LLC. See LICENSE for terms.

Available Tools

4 tools
keyring_agent_affinityA

Analyze agent-service affinity patterns from the checkout ledger.

Returns which agents use which services most — the raw data for workstation specialization analysis and context overload detection.

Args: days: How far back to analyze (default 30).

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden. It indicates a read-only analysis operation through 'Returns,' and states the data source, but it does not explicitly confirm lack of side effects, permissions, or any output limits/pagination behavior. This is acceptable but not thorough.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured: two purposeful sentences followed by an args line. The core purpose is front-loaded, with no filler or redundant information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter analysis tool with no output schema and no annotations, the description covers the input, source, and high-level output. Minor details like exact output shape or aggregation semantics are missing, but these are not essential for a correct call.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The only parameter 'days' is clearly explained as 'How far back to analyze (default 30)' despite 0% schema description coverage. This fully compensates for the schema gap by giving the parameter meaning and default context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Analyze') and a clear resource ('agent-service affinity patterns from the checkout ledger'), and explains the output: 'which agents use which services most.' It implicitly distinguishes from siblings like list_available and checkout_history by focusing on affinity analysis, but it does not explicitly name alternatives.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states intended use cases: 'workstation specialization analysis and context overload detection.' However, it does not explicitly say when to prefer this tool over its siblings or provide exclusion conditions, leaving usage guidance partly implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

keyring_authenticated_requestA

Make an authenticated API call using a managed secret. The key never appears in the response.

The keyring retrieves the secret, makes the API call, and returns only the response data. Every call is logged to the checkout ledger.

Args: service: Service identifier (e.g. 'agentmail', 'stripe', 'ga4', 'firebase'). For unregistered services, pass any name — the generic adapter handles the request if base_url is in params. secret_name: Name of the secret to use (from keyring_list_available). method: HTTP method (GET, POST, PUT, DELETE). endpoint: API endpoint path (appended to service base URL). params: Query parameters for the request. For unregistered services, include: base_url (required), auth_type ('bearer'|'header'|'basic'|'query', default 'bearer'), auth_header (header name when auth_type='header'). body: JSON body for POST/PUT requests. scope: Optional scope for multi-value keys (e.g. 'fleet', 'mcp'). When set, tries secret_name:scope first, falls back to secret_name. purpose: Why this request is being made (logged to ledger). did: Agent's DID for identity verification. agentmail_token: AgentMail API key for identity fallback. agentmail_inbox: Agent's AgentMail address for identity fallback.

ParametersJSON Schema
NameRequiredDescriptionDefault
didNo
bodyNo
scopeNo
methodNoGET
paramsNo
purposeNo
serviceYes
endpointNo
secret_nameYes
agentmail_inboxNo
agentmail_tokenNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the full burden and meets it: it discloses that the key never appears in the response, that only response data is returned, that every call is logged, and that scope/identity fallback behaviors exist. This is far beyond a generic 'makes a request' statement.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured: a concise summary, security/logging notes, then a complete Args list. It is long because it must document 11 parameters without schema help, but a few sentences ('The keyring retrieves the secret...') restate the opening mechanic.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with 11 parameters, no annotations, and no output schema, the description covers invocation and core behavior thoroughly. It does not specify response/error shape beyond 'response data,' but that is largely service-dependent and does not prevent correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description compensates fully by documenting all 11 parameters with examples, defaults, required conditions (base_url for unregistered services), auth_type options, and fallback semantics. An agent can correctly populate every parameter from this text alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description opens with a specific verb+resource: 'Make an authenticated API call using a managed secret.' It clearly describes the operation and references sibling-adjacent concepts (keyring_list_available, checkout ledger), making it easy for an agent to distinguish this request tool from listing/history/affinity siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: the agent is told to obtain secret_name from keyring_list_available, that calls are logged to the checkout ledger, and that unregistered services need base_url in params. It lacks explicit 'use X instead' exclusions, but the intended selection is unmistakable given tool names and content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

keyring_checkout_historyB

Query the checkout ledger — who accessed what, when, and why.

Args: agent_id: Filter by agent (DID or AM address). service: Filter by service name. secret_name: Filter by secret name. days: How far back to look (default 30).

ParametersJSON Schema
NameRequiredDescriptionDefault
daysNo
serviceNo
agent_idNo
secret_nameNo

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description must carry the full behavioral disclosure burden. It states it is a 'query' but does not explicitly declare read-only behavior, nor does it describe return format, pagination, rate limits, or any side effects. The phrasing 'who accessed what, when, and why' suggests it returns log entries, but the agent is left without concrete behavioral expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is concise and well-structured. The opening line conveys the core purpose immediately, followed by a compact, scannable parameter list. No redundant filler exists; each sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

While the parameter descriptions are helpful, the tool lacks an output schema and the description does not explain the return type or structure. For a query tool, an agent would benefit from knowing whether it returns a list, a count, or a summary, and whether results are paginated. This missing context leaves the definition partially incomplete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It does so thoroughly: each parameter (agent_id, service, secret_name, days) is given a clear meaning and default behavior. This adds substantial value beyond the bare schema types and defaults, enabling correct filter usage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action and resource: 'Query the checkout ledger — who accessed what, when, and why.' This distinguishes it from the sibling tools listed (which suggest listing, requests, and affinity), though it does not explicitly contrast with them. The purpose is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this tool versus the siblings. The description does not mention contexts where this should be preferred, nor does it list any exclusions or alternatives. An agent would have to infer usage from the tool's name and purpose alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

keyring_list_availableA

List secrets the calling agent can access. Returns names and descriptions only — never values.

Args: did: Agent's DID (did:key:...) for identity verification. agentmail_inbox: Agent's AgentMail address (e.g. sofer@agentmail.to) as fallback identity.

ParametersJSON Schema
NameRequiredDescriptionDefault
didNo
agentmail_inboxNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden and adds important behavioral context: it is a listing operation, and it explicitly guarantees 'never values,' which is critical for security-sensitive tool use. It also notes that the parameters are used for identity verification, clarifying why an agent would provide them. It does not describe response format or error behavior, but the main behavioral guarantee is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The main behavior is front-loaded in the first sentence, followed by a compact two-parameter list with examples. There is no filler; every sentence contributes either to purpose, safety, or parameter semantics.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple list operation with two optional parameters and no output schema or annotations, the description covers the key points: what it lists, what it returns, and the identity parameters. It is missing explicit usage routing relative to siblings, error conditions, and a clear statement of whether at least one identity argument is expected, leaving some gaps in an otherwise adequate definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Scheema description coverage is 0%, so the description must add paramter meaning, and it does. did is explained as 'Agent's DID (did:key:...) for identity verification,' and agentmail_inbox as 'Agent's AgentMail address as fallback identity,' giving the agent a basis for choosing between them. It stops short of specifying whether one is required or how precedence works.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states a specific action—list secrets the calling agent can access—and specifies the resource and a key distinction: it returns names and descriptions only, never values. This naturally separates it from sibling tools like keyring_authenticated_request, which imply performing some other keyring operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool: when an agent needs to discover which secrets it can access. However, it does not explicitly name alternatives or state when not to use it, leaving the routing decision to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 4 tool updatesv0.1.0
    • First observedkeyring_agent_affinity
    • First observedkeyring_authenticated_request
    • First observedkeyring_checkout_history
    • First observedkeyring_list_available

TDQS

A4/5.0
Disambiguation5/5

Each tool has a clearly distinct role: listing available secrets, making an authenticated request, querying the audit ledger, and analyzing ledger patterns. The closest pair, checkout_history and agent_affinity, are separated by raw logging versus aggregate analysis.

Naming Consistency3/5

The shared keyring_ prefix provides some consistency, but the suffixes are grammatically mixed: list_available is verb-like, while authenticated_request, checkout_history, and agent_affinity are noun phrases. A consistent verb_noun pattern would make the tool names more predictable.

Tool Count5/5

Four tools is well-scoped for an agent-facing keyring: discovery, usage, audit, and analytics. Each tool serves a distinct purpose without redundancy or unnecessary bloat.

Completeness5/5

The surface covers the full agent-facing workflow: see what secrets are available, use them without exposing values, review the audit trail, and analyze usage patterns. Secret lifecycle management tools are absent but appear intentionally reserved for administrators rather than agents.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

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

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables secure credential storage for AI agents by encrypting secrets and providing agent-invisible references, ensuring sensitive data never leaks to the model.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to securely manage API keys and secrets via the MCP protocol, with encrypted storage at rest and a simple CLI and Python SDK.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to securely access authenticated services (HTTP, SSH, SMTP) without exposing secrets, by acting as a server-side proxy that injects authentication.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to securely use API keys by storing them in an encrypted vault and injecting them on demand with user approval, without exposing the key values to the model.
    1
    MIT

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/MithrynMarious/agent-keyring'

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