auth-mcp
# 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
Scored across 7 tools
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.
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.
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.
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.