Skip to main content
Glama
KB01111

auth-mcp

by KB01111
README.md
# auth-mcp

A secure **MCP server** that stores all your API keys and auth credentials in one place, retrievable by any MCP client (Goose, Claude Code, Cursor, Codex, Gemini CLI...). Built with [FastMCP](https://github.com/jlowin/fastmcp) so it can be **hosted on [Prefect Horizon](https://horizon.prefect.io/)** and reached over HTTP at a URL like `https://<name>.fastmcp.app/mcp`.

## Features

| Tool | Description |
| --- | --- |
| `auth_set(name, value, description)` | Store or update a credential |
| `auth_get(name, mask=True)` | Retrieve a credential (masked by default; `mask=False` for full value) |
| `auth_list()` | List names + metadata only — **never values** |
| `auth_search(query)` | Search by name/description — metadata only |
| `auth_recommend(task)` | **MCP sampling** — asks goose's AI to pick the best credential for a task |
| `auth_delete(name)` | Delete a credential |
| `auth_health()` | Health check |

## Security model

- **Encrypted at rest** — the `file` backend encrypts every value with Fernet (AES-128-CBC + HMAC), key derived from `AUTH_MCP_MASTER_KEY` via PBKDF2-HMAC-SHA256 (600k iterations). The vault file never contains a plaintext secret.
- **List/search never leak values** — only names, descriptions and timestamps.
- **Masked by default** — `auth_get` returns `********last4` unless you explicitly pass `mask=False`.
- **Remote access is authenticated by the hosting platform** (FastMCP/Prefect Horizon).
- Optional `prefect` backend stores secrets as Prefect Cloud `Secret` blocks (durable, encrypted at rest by Prefect, RBAC-scoped) — ideal for the hosted deployment.

## MCP sampling

`auth_recommend(task)` uses [MCP sampling](https://goose-docs.ai/docs/guides/mcp-sampling): the server sends the task plus a list of available credentials (**names + descriptions only — values never leave the vault**) back to goose's LLM, which returns the single best match and its reasoning. This turns the vault into a smart credential router:

```
auth_recommend(task="call OpenAI to summarize this email thread")
# -> {"ok": true, "recommendation": "openai",
#     "reasoning": "Task mentions OpenAI summarization.", "available": [...]}
# then:  auth_get(name="openai", mask=False)
```

Sampling is automatically available in goose (no configuration needed) and gracefully degrades — if the client doesn't support sampling, the tool returns the full list instead.

> ⚠️ Never commit `.env`, the vault file, or real keys. Everything sensitive is git-ignored.

## Project layout

```
auth-mcp/
├── pyproject.toml            # deps + entry point (also used as Horizon "requirements")
├── README.md
├── .env.example              # copy to .env and fill in
├── src/auth_mcp/
│   ├── config.py             # env config (backend, master key, vault path)
│   ├── storage.py            # EncryptedFileStore + PrefectSecretStore backends
│   └── server.py             # FastMCP server + tools (Horizon server path)
└── tests/test_storage.py
```

## Run locally

```bash
cd auth-mcp
python -m venv .venv
.venv\Scripts\activate            # Windows  (macOS/Linux: source .venv/bin/activate)
pip install -e ".[test]"

# generate a master key and run the server
set AUTH_MCP_MASTER_KEY=CHANGE-ME-strong-passphrase
python -m auth_mcp.server
```

Test it:

```bash
pytest -q
```

The server speaks MCP over stdio. Add it to your local Goose/Claude Code/Cursor config, then try:

```
auth_set(name="openai", value="sk-...", description="OpenAI API key")
auth_list()
auth_get(name="openai")            # -> ********1234
auth_get(name="openai", mask=False)
```

## Deploy to Prefect Horizon

Prefect Horizon hosts FastMCP servers directly from a GitHub repo. Steps:

1. **Push this project to GitHub**

   ```bash
   cd auth-mcp
   git init && git add . && git commit -m "Initial auth-mcp"
   # create a repo on github.com and:
   git remote add origin git@github.com:<you>/auth-mcp.git
   git push -u origin main
   ```

2. **Sign in to [horizon.prefect.io](https://horizon.prefect.io/)** (create an account if needed).

3. **Create a new server** and point it at your repo:
   - **Repository**: `<you>/auth-mcp`
   - **Server path**: `src/auth_mcp/server.py`
   - **Requirements**: `pyproject.toml`

4. **Set environment variables** in the Horizon UI:

   | Variable | Value |
   | --- | --- |
   | `AUTH_MCP_MASTER_KEY` | A strong passphrase (see below) |
   | `AUTH_MCP_BACKEND` | `prefect` (recommended for hosted: secrets live in Prefect Cloud) |
   | `PREFECT_API_URL` | `https://api.prefect.cloud/api/accounts/<ACCOUNT_ID>/workspaces/<WORKSPACE_ID>` |
   | `PREFECT_API_KEY` | A Prefect Cloud API key that can read/write `Secret` blocks |

   Generate a master key:
   ```bash
   python -c "import secrets; print(secrets.token_urlsafe(32))"
   ```

5. **Deploy**, then copy your server URL, e.g. `https://auth-mcp-xxxx.fastmcp.app/mcp`.

6. **Point your MCP client at the URL** (HTTP transport):

   - Goose: `goose mcp add auth-mcp --transport http https://auth-mcp-xxxx.fastmcp.app/mcp`
   - Claude Code: `claude mcp add auth-mcp --transport http https://auth-mcp-xxxx.fastmcp.app/mcp`
   - Cursor: add to `.cursor/mcp.json` with `"url": "https://auth-mcp-xxxx.fastmcp.app/mcp"`

   Any client on your team can now read/write shared credentials through one hosted endpoint.

## Backends

- **`file`** (default): encrypted vault on disk (`AUTH_MCP_VAULT_PATH`, default `.auth_vault.json`). Zero external services; good for local use and simple self-hosting.
- **`prefect`**: each credential is a Prefect `Secret` block. Install with `pip install "auth-mcp[prefect]"`. Requires `PREFECT_API_URL` + `PREFECT_API_KEY`. Best for the Horizon deployment since secrets survive restarts and are managed by Prefect Cloud.

## Security checklist

- [ ] Use a long, unique `AUTH_MCP_MASTER_KEY` and store it in a password manager
- [ ] Never commit `.env` or `*.json` vault files
- [ ] Grant the Horizon/Prefect API key only the permissions it needs (Secret blocks)
- [ ] Rotate keys regularly (`auth_set` overwrites in place)
- [ ] Keep `mask=True` unless a full value is genuinely required

TDQS

A4.4/5.0

Scored across 7 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: set (create/update), get (retrieve value), list (enumerate metadata), search (query metadata), delete (remove), recommend (AI selection), and health (server status). No two tools perform the same action; even the related list/search/recommend are distinguished by their inputs and outputs.

Naming Consistency5/5

All tools follow a consistent 'auth_<verb>' pattern (set, list, search, recommend, delete, get, health). The verb is always lowercase and after the namespace prefix, making the tool set predictable and easy to navigate.

Tool Count5/5

Seven tools is ideal for a credential vault: it covers the full lifecycle (create, read, update/delete, list/search) plus health and an AI recommendation feature. Every tool earns its place without redundancy or bloat.

Completeness5/5

The surface fully covers credential management: creation/updating (auth_set), retrieval (auth_get), listing (auth_list), searching (auth_search), deletion (auth_delete), and an intelligent selection helper (auth_recommend). No essential operation is missing, and the workflow between recommend and get is explicitly documented.

Maintenance

ActivityMaintained
ResponsivenessNo issues