# Amnesic

> Persistent semantic memory for SQL databases. Postgres, MySQL, MSSQL, SQLite.

- **Type:** MCP server
- **Install:** `agentstack add mcp-surajkgoyal-amnesic`
- **Verified:** Pending review
- **Seller:** [SurajKGoyal](https://agentstack.voostack.com/s/surajkgoyal)
- **Installs:** 0
- **Latest version:** 0.1.10
- **License:** MIT
- **Upstream author:** [SurajKGoyal](https://github.com/SurajKGoyal)
- **Source:** https://github.com/SurajKGoyal/amnesic

## Install

```sh
agentstack add mcp-surajkgoyal-amnesic
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# amnesic — the MCP server with the most ironic name in the registry

[](https://pypi.org/project/amnesic/)
[](https://pypi.org/project/amnesic/)
[](LICENSE)
[](https://registry.modelcontextprotocol.io)
[](https://glama.ai/mcp/servers/SurajKGoyal/amnesic)

**Persistent semantic memory for your SQL databases. The name is ironic — it remembers everything.**

*"The MCP server with the most ironic name in the registry. It's anything but amnesic — it remembers your database so your AI doesn't have to."*

  

**Works with** Claude Code · Claude Desktop · Cursor · VS Code · Cline · Windsurf — any [MCP-compatible client](https://modelcontextprotocol.io/clients).

**Available on** [Official MCP Registry](https://registry.modelcontextprotocol.io) · [Claude Code plugin marketplace](https://github.com/SurajKGoyal/amnesic-marketplace)

> 🔒 **Read-only by design.** amnesic refuses to execute `INSERT`, `UPDATE`, `DELETE`, `DROP`, `TRUNCATE`, `ALTER`, `CREATE`, `EXEC`, `MERGE`, `GRANT`, `REVOKE` — and any write statement smuggled inside a `WITH` CTE. Two layers of defense: static SQL analysis rejects the statement before connecting, **and** every query runs inside a transaction that is immediately rolled back. Safe to point at prod. [Details ↓](#safety--read-only-enforcement)

---

## The problem

Every session with an AI starts cold. You spend the first few minutes re-explaining what tables exist, what a `status` column value of `3` means, which FK connects `orders` to `users`. Then the session ends, and you do it all over again tomorrow.

**amnesic fixes this.** It gives your AI a persistent SQLite knowledge store — one per database — that survives across sessions. Annotate a status enum once; every future session sees those labels automatically. Discover FK relationships once; every future JOIN query uses that graph.

---

## Quickstart (90 seconds)

```bash
pipx install amnesic            # install the core
amnesic init                    # interactive wizard
```

> ⚡ **Try it without credentials.** Run `amnesic init --demo` instead — it adds a self-contained SQLite sample DB (e-commerce schema: customers / products / orders with FKs and an enum column) so you can exercise every tool in under a minute. Great for a first look before pointing amnesic at a real database.

The wizard asks which database type you're connecting to and tells you the **one** command to run if its driver isn't installed yet — you never need to guess extras up front.

The wizard:
- Asks for your database type, host, and credentials
- Tests the connection before saving anything
- Stores the password securely in `~/.config/amnesic/.env` (chmod 600)
- Writes the connection block to `~/.config/amnesic/connections.toml`

Then [add amnesic to your AI client](#add-to-your-ai-client) and restart.

Don't have pipx? Or prefer uv / plain pip?

**Install `pipx`** (one-time):

```bash
brew install pipx                                  # macOS
sudo apt install pipx                              # Linux (Debian/Ubuntu)
python -m pip install --user pipx                  # Windows / generic
```

**Or use `uv`** (single-binary alternative — fast, no Python required):

```bash
brew install uv                                            # macOS
curl -LsSf https://astral.sh/uv/install.sh | sh            # Linux / macOS
powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # Windows

uv tool install amnesic
```

**Or plain `pip`** (installs into your active Python env):

```bash
pip install amnesic
```

> Whichever you pick, `amnesic init` asks which database you'll connect to and prints the one extra command to install that driver — no need to commit to extras up front.

After install, `amnesic --help` works from any terminal.

### Where amnesic stores things

| File | macOS / Linux | Windows |
|---|---|---|
| Config | `~/.config/amnesic/connections.toml` | `%APPDATA%\amnesic\connections.toml` |
| Secrets | `~/.config/amnesic/.env` (chmod 600) | `%APPDATA%\amnesic\.env` (user profile ACL) |
| Knowledge | `~/.config/amnesic/knowledge_.db` | `%APPDATA%\amnesic\knowledge_.db` |

Set `$AMNESIC_HOME` (or `$XDG_CONFIG_HOME` on Linux) to override the location.

### Adding more connections later

```bash
amnesic add          # add another connection to existing config
amnesic test         # verify all connections
amnesic test orders.prod  # verify one connection
```

### Setting and rotating passwords

`amnesic init` and `amnesic add` save your password automatically — for the typical setup flow, you never need to think about this section.

Use `set-secret` when you need to change a stored password later — IT rotated it, you mistyped it during setup, or you're hand-editing the config.

```bash
$ amnesic set-secret ORDERS_PROD_PASSWORD
Value: ****            ← hidden input (your typing is invisible)
Confirm: ****
✓ Set ORDERS_PROD_PASSWORD in ~/.config/amnesic/.env
```

**What's the variable name?** It's the env var your `connections.toml` references for that connection's password. The wizard auto-generates these as `_PASSWORD`:

| Connection name | Generated env var |
|---|---|
| `orders.prod` | `ORDERS_PROD_PASSWORD` |
| `analytics` | `ANALYTICS_PASSWORD` |
| `drive.staging` | `DRIVE_STAGING_PASSWORD` |

To see the exact name your config uses, check `~/.config/amnesic/connections.toml` — anything inside `${...}` is the variable to pass to `set-secret`.

**Under the hood**: writes (or replaces) the line in `~/.config/amnesic/.env`, sets file permission to `chmod 600` (only your user can read it), preserves all other entries.

### Managing connections and knowledge

Knowledge accumulates per connection in a local SQLite file. These commands let you move it between machines and clean up:

```bash
# Hand off everything you've taught amnesic about a database (annotations +
# relationships, not the re-derivable schema cache) as portable JSON:
amnesic export orders.prod -o orders-knowledge.json
amnesic export orders.prod            # or print to stdout to pipe/redirect

# Load that knowledge into another connection (e.g. promote staging → prod,
# or onboard a teammate). Unconditional upsert — existing entries are overwritten:
amnesic import orders.prod orders-knowledge.json

# Wipe stored knowledge for a connection but keep the config entry:
amnesic clear orders.staging

# Drop a connection from connections.toml entirely (knowledge file kept
# unless you pass --delete-knowledge):
amnesic remove old.connection
amnesic remove old.connection --delete-knowledge
```

`export`/`import`/`clear`/`remove` operate purely on local files — they never connect to the database, so they work even if a connection's credentials aren't set. `remove` edits `connections.toml` with surgical string edits, leaving every other block's formatting and comments byte-for-byte intact.

---

## Add to your AI client

Once amnesic is installed with the right driver extras (see [Quickstart](#quickstart-90-seconds)), the `amnesic` command is on your PATH. Use the same snippet across every MCP client:

### Claude Code

**One-line install** (recommended — no JSON editing). Inside Claude Code:

```
/plugin marketplace add SurajKGoyal/amnesic-marketplace
/plugin install amnesic@amnesic
```

That wires amnesic as an MCP server automatically. Source: [SurajKGoyal/amnesic-marketplace](https://github.com/SurajKGoyal/amnesic-marketplace).

Or wire it by hand — edit ~/.claude/mcp.json

```json
{
  "mcpServers": {
    "amnesic": {
      "command": "amnesic"
    }
  }
}
```

### Claude Desktop

Add to your platform's Claude Desktop config:

- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux**: `~/.config/Claude/claude_desktop_config.json`

```json
{
  "mcpServers": {
    "amnesic": {
      "command": "amnesic"
    }
  }
}
```

### Cursor

**One-click install** — click the button below and Cursor wires it up for you:

Or wire it by hand — edit .cursor/mcp.json

Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` globally):

```json
{
  "mcpServers": {
    "amnesic": {
      "command": "amnesic"
    }
  }
}
```

### Without a global install (ephemeral)

If you'd rather not install amnesic on your system, use `uvx` or `pipx` to fetch it each time the MCP client starts. Note the driver extras must be passed explicitly:

```json
// uvx — requires `uv` installed (see Install section for per-OS instructions)
{
  "mcpServers": {
    "amnesic": {
      "command": "uvx",
      "args": ["--from", "amnesic[mssql]", "amnesic"]
    }
  }
}

// pipx — usually pre-installed via Homebrew or system package manager
{
  "mcpServers": {
    "amnesic": {
      "command": "pipx",
      "args": ["run", "--spec", "amnesic[mssql]", "amnesic"]
    }
  }
}
```

For multiple drivers, comma-separate inside the brackets — e.g. `amnesic[postgres,mssql]` or use `amnesic[all]` for everything.

### VS Code (with MCP extension)

Add to `.vscode/mcp.json`:

```json
{
  "servers": {
    "amnesic": {
      "type": "stdio",
      "command": "amnesic"
    }
  }
}
```

---

## Updating

amnesic ships often. Upgrade with the same tool you installed it with:

| Installed via | Upgrade command |
|---|---|
| `pipx` | `pipx upgrade amnesic` |
| `uv tool` | `uv tool upgrade amnesic` |
| `pip` | `pip install --upgrade amnesic` |
| `uvx` (ephemeral, in your MCP config) | uvx caches builds — run `uv cache clean amnesic` to pull the newest |

Then **restart your MCP client** (Claude Code, Cursor, …) so it relaunches the amnesic server and picks up any new tools.

**Upgrading is safe — you won't lose annotations.** Your knowledge files auto-migrate to the new schema on first load; amnesic only ever *adds* columns, never drops your data.

To check the installed version: `amnesic --version`. Latest release: [PyPI](https://pypi.org/project/amnesic/) · [Releases](https://github.com/SurajKGoyal/amnesic/releases).

---

## Tools

| Tool | Description |
|------|-------------|
| `db_list_connections()` | List all configured connections (no secrets exposed) |
| `db_list_tables(connection)` | All known tables with descriptions and column counts |
| `db_search(query, connection, target, limit)` | BM25 search over table/column descriptions and aliases |
| `db_get_schema(table, connection)` | Column schema merged with saved annotations |
| `db_query(sql, connection)` | Execute a read-only SELECT query |
| `db_annotate(table, connection, ...)` | Persist semantic annotations for tables/columns |
| `db_deprecate(table, connection, column?, reason?, undo?)` | Soft-retire a stale annotation — flagged (and warned) but kept, reversible |
| `db_detect_drift(connection)` | Audit annotations vs the live schema — find orphaned annotations + undocumented tables |
| `db_forget(table, connection, column?, cascade?)` | Hard-delete an annotation (cascade opt-in) — permanent |
| `db_sync_knowledge(from, to)` | Copy annotations between connections (e.g. staging → prod) |
| `db_discover_relationships(connection)` | Discover all FK relationships from the live DB |
| `db_get_relationships(table, connection)` | Navigate the FK graph for JOIN planning |

---

## Searching the knowledge base

For large schemas, `db_list_tables` is impractical — you'd dump 500+ rows into Claude's context. Use `db_search` to find the relevant tables/columns by keyword instead:

```
"What table tracks customer payments?"
  → db_search("payments")
    Top results:
      - dbo.payments  (table) "Customer payment records..."
      - dbo.orders.payment_method  (column) "Mode of payment..."
```

`db_search` uses **SQLite FTS5 with BM25 ranking** — fast, local, no embeddings or external services. Search syntax supports:

| Syntax | Effect |
|--------|--------|
| `payment` | Match the word (with stemming — also matches "payments", "paying") |
| `"payment method"` | Exact phrase |
| `pay*` | Prefix match — "payment", "payable", etc. |
| `payment AND status` | Both terms required |
| `payment OR refund` | Either term |

Results return ranked table/column rows with descriptions and highlighted snippets.

---

## The knowledge layer

The core differentiator. Every annotation survives restarts, model updates, and new sessions.

### Session 1 — you discover something

```
You: What does status=3 mean in the orders table?
AI: Let me check. [runs db_query: SELECT DISTINCT status FROM dbo.orders]
    I see values 1, 2, 3, 4. Let me look at some examples...
    Based on the data, 3 appears to be "cancelled".

You: Save that. And status=1 is "pending", 2 is "confirmed", 4 is "delivered".
AI: [calls db_annotate]
    db_annotate(
      table="dbo.orders",
      column="status",
      column_description="Order lifecycle status",
      enum_values={"1": "pending", "2": "confirmed", "3": "cancelled", "4": "delivered"}
    )
    Saved. Future sessions will see these labels automatically.
```

### Session 2 — the knowledge is already there

```
You: How many cancelled orders are there this month?
AI: [calls db_get_schema("dbo.orders")]
    Schema response includes:
      column: "status"
      description: "Order lifecycle status"
      enum_values: {"1": "pending", "2": "confirmed", "3": "cancelled", "4": "delivered"}

    [writes correct SQL immediately]
    SELECT COUNT(*) FROM dbo.orders WHERE status = 3 AND ...
```

No re-discovery. No wasted turns. The annotation persisted.

---

## Relationship graph

Understand your schema's JOIN structure once, reuse it forever.

```
AI: [db_discover_relationships(connection="orders.prod")]
    Discovered 47 foreign key relationships.

AI: [db_get_relationships(table="orders", depth=2)]
    neighbors:
      orders → users (via user_id → id)
      orders → order_items (via id ← order_id)
    paths:
      orders -> users
      orders -> order_items
      order_items -> products
```

Now the AI knows exactly how to JOIN across your schema without guessing.

---

## Sync between environments

Build up annotations in staging, then promote to prod:

```
db_sync_knowledge(from_connection="orders.staging", to_connection="orders.prod")
```

Returns `{synced: [...], skipped: [{table, reason}], warnings: [{table, column, reason}]}`.

Tables missing from the target schema cache are skipped with a clear reason. Columns missing from target schema are warned but don't block the rest of the sync.

---

## Advanced: hand-edit the TOML

If you prefer to manage the config file yourself, generate a blank template:

```bash
amnesic init --template
```

This writes `~/.config/amnesic/connections.toml` with commented examples and exits — no wizard. Edit the file directly:

```toml
# ~/.config/amnesic/connections.toml

# Nested style: [connections.product.env]
[connections.orders.prod]
driver = "mssql"
server = "localhost"
port = 11433
database = "OrdersDB"
user = "${ORDERS_USER}"
password = "${ORDERS_PROD_PASSWORD}"
tunnel_script = "~/.scripts/mssql-tunnel.sh"     # macOS / Linux (bash)
# tunnel_script = "C:/scripts/mssql-tunnel.ps1"  # Windows (PowerShell)

[connections.orders.staging]
driver = "mssql"
server = "localhost"
port = 11434
database = "OrdersDB_Staging"
user = "${ORDERS_USER}"
password = "${ORDERS_STAGING_PASSWORD}"

# Flat style: [connections.name]
[connections.analytics]
driver = "postgres"
server = "analytics.company.com"
port = 5432
database = "warehouse"
user = "${ANALYTICS_DB_USER}"
password = "${ANALYTICS_DB_PASSWORD}"

# SQLite — no credentials needed
[connections.local]
driver = "sqlite"
database = "/absolute/path/to/local.db"       # macOS / Linux
# database = "C:/path/to/local.db"            # Windows (use forward slashes)
```

Use `${ENV_VAR}` for credentials — never hardcode passwords.

Secrets are loaded from `~/.config/amnesic/.env` automatically (format: `KEY=VALUE`, one per line, `#` for comments). For each `${VAR_NAME}` referenced in your TOML, populate the matching `.env` entry with [`amnesic set-secret VAR_NAME`](#setting-and-rotating-passwords) (hidden input, chmod 600), o

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [SurajKGoyal](https://github.com/SurajKGoyal)
- **Source:** [SurajKGoyal/amnesic](https://github.com/SurajKGoyal/amnesic)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Versions

- **0.1.10** — security scan: pending review — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-surajkgoyal-amnesic
- Seller: https://agentstack.voostack.com/s/surajkgoyal
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
