Skip to main content
Glama
Gonzih

agent-keys

by Gonzih
README.md
# agent-keys

[![npm version](https://img.shields.io/npm/v/@gonzih/agent-keys.svg)](https://www.npmjs.com/package/@gonzih/agent-keys)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**MCP server that lets AI agents autonomously acquire and manage API keys.**

## The Problem

AI agents frequently need API keys to accomplish tasks — sending emails, making calls, running models, storing data. Today this requires a human to manually create accounts, navigate dashboards, and paste keys into configs. `agent-keys` gives agents a structured, secure interface to discover services, get provisioning instructions, store retrieved keys, verify they work, and export them as environment variables — all without human intervention after initial setup.

## Quick Start

### Via npx (no install required)

```bash
npx @gonzih/agent-keys
```

### MCP Configuration

Add to your MCP config file (e.g. `~/.claude/claude_desktop_config.json` or `~/.config/claude-code/config.json`):

```json
{
  "mcpServers": {
    "agent-keys": {
      "command": "npx",
      "args": ["@gonzih/agent-keys"],
      "env": {
        "AGENT_KEYS_SECRET": "your-strong-encryption-secret"
      }
    }
  }
}
```

### Claude Code Config

Add to your Claude Code settings:

```json
{
  "mcpServers": {
    "agent-keys": {
      "command": "npx",
      "args": ["@gonzih/agent-keys"],
      "env": {
        "AGENT_KEYS_SECRET": "your-strong-encryption-secret"
      }
    }
  }
}
```

## Tools

### `list_services`
List all 26 supported services with their category, description, signup URL, and whether a key is stored.

**Input:** none

**Output:**
```json
[
  {
    "name": "openai",
    "displayName": "OpenAI",
    "category": "ai",
    "description": "AI research company providing GPT-4, DALL-E, Whisper, and embeddings APIs.",
    "signupUrl": "https://platform.openai.com/signup",
    "has_key": true,
    "freetier": "$5 free credit for new accounts (limited time)",
    "envVarName": "OPENAI_API_KEY"
  }
]
```

---

### `get_api_key`
Retrieve a stored API key. Returns the key if found, or provisioning guidance if not.

**Input:**
```json
{ "service": "openai" }
```

**Output (found):**
```json
{
  "found": true,
  "service": "openai",
  "key": "sk-proj-...",
  "stored_at": "2024-01-15T10:30:00.000Z",
  "envVarName": "OPENAI_API_KEY"
}
```

**Output (not found):**
```json
{
  "found": false,
  "service": "openai",
  "message": "No API key stored for OpenAI. Use provision_api_key to get instructions.",
  "signupUrl": "https://platform.openai.com/signup"
}
```

---

### `store_api_key`
Store an API key in the encrypted vault.

**Input:**
```json
{
  "service": "openai",
  "key": "sk-proj-...",
  "metadata": { "org": "my-org", "created_by": "agent" }
}
```

**Output:**
```json
{
  "success": true,
  "service": "openai",
  "displayName": "OpenAI",
  "message": "API key for OpenAI stored successfully.",
  "envVarName": "OPENAI_API_KEY"
}
```

---

### `check_api_key`
Verify a stored key is still valid by calling the service's test endpoint.

**Input:**
```json
{ "service": "openai" }
```

**Output:**
```json
{
  "valid": true,
  "service": "openai",
  "displayName": "OpenAI",
  "status": 200,
  "message": "API key for OpenAI is valid."
}
```

Services with test endpoints: openai, sendgrid, stripe, github, groq, together-ai, elevenlabs, deepgram, replicate, brave-search, serper, tavily.

---

### `provision_api_key`
Get step-by-step instructions and the direct signup URL for acquiring an API key.

**Input:**
```json
{ "service": "groq" }
```

**Output:**
```json
{
  "service": "groq",
  "displayName": "Groq",
  "signupUrl": "https://console.groq.com/login",
  "steps": [
    "Go to https://console.groq.com/login",
    "Create a free account or sign in",
    "Navigate to https://console.groq.com/keys",
    "Click 'Create API Key'",
    "Give it a name and click 'Submit'",
    "Copy the generated API key immediately (shown only once)",
    "Store it using store_api_key with service 'groq'"
  ],
  "freetier": "Free tier with generous rate limits"
}
```

---

### `remove_api_key`
Delete a key from the vault.

**Input:**
```json
{ "service": "openai" }
```

**Output:**
```json
{
  "success": true,
  "service": "openai",
  "message": "API key for OpenAI removed from vault."
}
```

---

### `export_env`
Generate shell `export` statements for stored keys.

**Input:**
```json
{ "services": ["openai", "anthropic"] }
```
Or omit `services` to export all stored keys.

**Output:**
```json
{
  "exports": [
    "export OPENAI_API_KEY=\"sk-proj-...\"",
    "export ANTHROPIC_API_KEY=\"sk-ant-...\""
  ],
  "shell": "export OPENAI_API_KEY=\"sk-proj-...\"\nexport ANTHROPIC_API_KEY=\"sk-ant-...\"",
  "count": 2
}
```

---

## Supported Services

### AI (5 services)

| Name | Display Name | Free Tier | Env Var |
|------|-------------|-----------|---------|
| `openai` | OpenAI | $5 credit (new accounts) | `OPENAI_API_KEY` |
| `anthropic` | Anthropic | Free tier with rate limits | `ANTHROPIC_API_KEY` |
| `replicate` | Replicate | Pay-per-use, free community models | `REPLICATE_API_TOKEN` |
| `together-ai` | Together AI | $25 free credit | `TOGETHER_API_KEY` |
| `groq` | Groq | Free tier, generous limits | `GROQ_API_KEY` |

### Communication (6 services)

| Name | Display Name | Free Tier | Env Var(s) |
|------|-------------|-----------|------------|
| `twilio` | Twilio | $15 trial credit | `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN` |
| `sendgrid` | SendGrid | 100 emails/day forever | `SENDGRID_API_KEY` |
| `mailgun` | Mailgun | 100 emails/day, 3 months | `MAILGUN_API_KEY` |
| `postmark` | Postmark | 100 emails/month forever | `POSTMARK_API_TOKEN` |
| `vonage` | Vonage (Nexmo) | $2 trial credit | `VONAGE_API_KEY`, `VONAGE_API_SECRET` |
| `telnyx` | Telnyx | $1 credit on signup | `TELNYX_API_KEY` |

### Voice (3 services)

| Name | Display Name | Free Tier | Env Var |
|------|-------------|-----------|---------|
| `elevenlabs` | ElevenLabs | 10,000 chars/month | `ELEVENLABS_API_KEY` |
| `deepgram` | Deepgram | $200 free credit | `DEEPGRAM_API_KEY` |
| `assemblyai` | AssemblyAI | $50 free credit | `ASSEMBLYAI_API_KEY` |

### Infrastructure (8 services)

| Name | Display Name | Free Tier | Env Var |
|------|-------------|-----------|---------|
| `stripe` | Stripe | No monthly fee | `STRIPE_SECRET_KEY` |
| `github` | GitHub | Free for personal use | `GITHUB_TOKEN` |
| `cloudflare` | Cloudflare | Free plan available | `CLOUDFLARE_API_TOKEN` |
| `vercel` | Vercel | Hobby plan free | `VERCEL_TOKEN` |
| `railway` | Railway | $5 credit/month | `RAILWAY_TOKEN` |
| `supabase` | Supabase | 2 free projects | `SUPABASE_ANON_KEY` |
| `planetscale` | PlanetScale | 5GB free storage | `PLANETSCALE_SERVICE_TOKEN` |
| `upstash` | Upstash | 10,000 commands/day | `UPSTASH_REDIS_REST_TOKEN` |

### Data (4 services)

| Name | Display Name | Free Tier | Env Var |
|------|-------------|-----------|---------|
| `serper` | Serper | 2,500 free searches | `SERPER_API_KEY` |
| `brave-search` | Brave Search | 2,000 queries/month | `BRAVE_API_KEY` |
| `tavily` | Tavily | 1,000 calls/month | `TAVILY_API_KEY` |
| `firecrawl` | Firecrawl | 500 credits on signup | `FIRECRAWL_API_KEY` |

## Adding a New Service

Edit `src/registry.ts` and add a new object to the `registry` array:

```typescript
{
  name: 'my-service',           // slug used in tool calls
  displayName: 'My Service',    // human-readable name
  category: 'ai',               // 'communication' | 'ai' | 'voice' | 'infrastructure' | 'data'
  description: 'What it does.',
  signupUrl: 'https://myservice.com/signup',
  docsUrl: 'https://docs.myservice.com/api',
  envVarName: 'MY_SERVICE_API_KEY',
  freetier: 'Description of free tier',
  programmatic: false,
  provisioningSteps: [
    'Go to https://myservice.com/signup',
    'Create an account',
    'Navigate to API Keys',
    'Click Create Key',
    'Copy the key',
    'Store it using store_api_key with service "my-service"',
  ],
  testEndpoint: {               // optional
    url: 'https://api.myservice.com/v1/me',
    method: 'GET',
    headers: (key: string) => ({ Authorization: `Bearer ${key}` }),
    successStatus: 200,
  },
}
```

Then run `npm run build`.

## Security

- **Encryption:** AES-256-GCM with scrypt key derivation (N=16384, r=8, p=1)
- **Per-write randomness:** Each vault write uses a fresh 16-byte salt and 16-byte IV
- **Auth tag:** GCM auth tag prevents undetected tampering
- **Plaintext fallback:** If `AGENT_KEYS_SECRET` is not set, keys are stored unencrypted with a warning
- **Vault location:** `~/.agent-keys/vault.json` by default; override with `AGENT_KEYS_VAULT`
- **Secret management:** Never commit `AGENT_KEYS_SECRET` to source control; use env vars or a secrets manager

## Development

```bash
# Install dependencies
npm install

# Build TypeScript
npm run build

# Run directly with tsx (no build step)
npm run dev
```

## License

MIT

TDQS

A3.9/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: listing services, getting/storing/checking/provisioning/removing keys, and exporting. No overlap.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern (e.g., list_services, get_api_key, store_api_key). The use of 'env' in export_env is a different noun but still fits the pattern.

Tool Count5/5

7 tools is well-scoped for managing API keys, covering all essential operations without being excessive or insufficient.

Completeness5/5

The tool surface covers the full lifecycle: discovery, storage, retrieval, verification, provisioning guidance, deletion, and export. No obvious gaps.

Maintenance

ActivityInactive
ResponsivenessNo issues