> ## Documentation Index
> Fetch the complete documentation index at: https://cortex-e852fafe-auto-update-openapi-90ba87bf22729efa0749c85.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# HydraDB MCP

> MCP (Model Context Protocol) server for [HydraDB](https://hydradb.com). Provides tools for storing, recalling, and managing memories with knowledge-graph enriched context.

## Quick Start

The fastest way in is **Sign in with HydraDB**: paste one URL into your AI app,
approve it in the browser, done. No API key, no config file to edit.

<Tabs>
  <Tab title="Sign in with HydraDB (recommended)">
    Here is how you can connect:

    <Tabs>
      <Tab title="Claude Code">
        ```bash theme={null}
        claude mcp add --transport http hydradb https://mcp.hydradb.com
        ```

        Then run `/mcp`, choose **hydradb**, and click **Authenticate**.
      </Tab>

      <Tab title="Claude Desktop">
        **Settings → Connectors → Add custom connector**, paste
        `https://mcp.hydradb.com`, then click **Connect**.
      </Tab>

      <Tab title="Cursor">
        Add to `~/.cursor/mcp.json`:

        ```json theme={null}
        {
          "mcpServers": {
            "hydradb": { "url": "https://mcp.hydradb.com" }
          }
        }
        ```

        Restart Cursor, then click **Connect** on the server in Settings → MCP.
      </Tab>

      <Tab title="VS Code">
        Add to `.vscode/mcp.json`:

        ```json theme={null}
        {
          "servers": {
            "hydradb": { "type": "http", "url": "https://mcp.hydradb.com" }
          }
        }
        ```
      </Tab>

      <Tab title="OpenCode">
        ```bash theme={null}
        opencode mcp add hydradb --url https://mcp.hydradb.com
        opencode mcp auth hydradb
        ```
      </Tab>

      <Tab title="Codex">
        ```bash theme={null}
        codex mcp add hydradb --url https://mcp.hydradb.com
        codex mcp login hydradb
        ```
      </Tab>

      <Tab title="Windsurf">
        Add to `~/.codeium/windsurf/mcp_config.json`:

        ```json theme={null}
        {
          "mcpServers": {
            "hydradb": { "serverUrl": "https://mcp.hydradb.com" }
          }
        }
        ```
      </Tab>
    </Tabs>

    <Tip>
      **Not sure where to put the URL?** Paste this to your AI assistant and it
      will add or update the config file for you:

      > Add the HydraDB MCP server at `https://mcp.hydradb.com` to my MCP
      > config, then help me authenticate.
    </Tip>

    ### What you are approving

    The approval screen shows the app asking to connect, what it will be able to
    do, and which **database** it will read and write. It also asks whether the
    app may use your *other* databases:

    * **Allowed when asked** (default) - the app starts in the database you
      picked and can switch to another one of yours when you tell it to. Choose
      this if you work across several databases.
    * **Not allowed** - the app is confined to that database, and to the
      collection shown under **Advanced** (`hydra-db-mcp` unless you change
      it). Anything else is refused, including a request to delete a graph in
      another collection.

    You can change your mind at any time: **Settings → Connected apps** lists
    every app you have connected and **Disconnect** cuts one off immediately.
  </Tab>

  <Tab title="API key">
    Signing in is preferred, but an API key still works everywhere and is the
    right choice for servers, CI, scripts, and self-hosted deployments where no
    browser is available.

    <Steps>
      <Step title="Get your credentials">
        * Create an API key from the [HydraDB dashboard](https://app.hydradb.com/keys)
        * Create or copy your database ID from the [HydraDB dashboard](https://app.hydradb.com/databases)
      </Step>

      <Step title="Connect your client">
        <Tabs>
          <Tab title="Remote MCP server">
            Point your client at `https://mcp.hydradb.com` and pass your
            credentials as headers. The key names differ by client: VS Code uses
            the `servers` schema with an explicit `type`, the others use
            `mcpServers`. See [authentication](#authenticating-to-the-remote-server)
            for every header.

            <Tabs>
              <Tab title="Claude Desktop / Cursor / Windsurf">
                ```json theme={null}
                {
                  "mcpServers": {
                    "hydradb": {
                      "url": "https://mcp.hydradb.com",
                      "headers": {
                        "Authorization": "Bearer YOUR_HYDRADB_API_KEY",
                        "X-HydraDB-Database": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>

              <Tab title="VS Code">
                Add to `.vscode/mcp.json` - note the `servers` key and the
                explicit `"type": "http"`:

                ```json theme={null}
                {
                  "servers": {
                    "hydradb": {
                      "type": "http",
                      "url": "https://mcp.hydradb.com",
                      "headers": {
                        "Authorization": "Bearer YOUR_HYDRADB_API_KEY",
                        "X-HydraDB-Database": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>
            </Tabs>
          </Tab>

          <Tab title="Local MCP server">
            Your client spawns the server over stdio. Requires **Node.js 18 or
            later** (`node --version` to check).

            <Tabs>
              <Tab title="Claude Desktop">
                ```json theme={null}
                {
                  "mcpServers": {
                    "hydradb": {
                      "command": "npx",
                      "args": ["-y", "@hydradb/mcp@^1.1.0"],
                      "env": {
                        "HYDRADB_API_KEY": "your-api-key",
                        "HYDRADB_DATABASE": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>

              <Tab title="Cursor">
                Add to `~/.cursor/mcp.json`:

                ```json theme={null}
                {
                  "mcpServers": {
                    "hydradb": {
                      "command": "npx",
                      "args": ["-y", "@hydradb/mcp@^1.1.0"],
                      "env": {
                        "HYDRADB_API_KEY": "your-api-key",
                        "HYDRADB_DATABASE": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>

              <Tab title="Windsurf">
                Add to `~/.codeium/windsurf/mcp_config.json`:

                ```json theme={null}
                {
                  "mcpServers": {
                    "hydradb": {
                      "command": "npx",
                      "args": ["-y", "@hydradb/mcp@^1.1.0"],
                      "env": {
                        "HYDRADB_API_KEY": "your-api-key",
                        "HYDRADB_DATABASE": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>

              <Tab title="VS Code">
                Add to `.vscode/mcp.json`:

                ```json theme={null}
                {
                  "servers": {
                    "hydradb": {
                      "type": "stdio",
                      "command": "npx",
                      "args": ["-y", "@hydradb/mcp@^1.1.0"],
                      "env": {
                        "HYDRADB_API_KEY": "your-api-key",
                        "HYDRADB_DATABASE": "your-database"
                      }
                    }
                  }
                }
                ```
              </Tab>
            </Tabs>
          </Tab>
        </Tabs>
      </Step>

      <Step title="Replace the placeholders and restart">
        Swap `YOUR_HYDRADB_API_KEY` / `your-api-key` and `your-database` for the
        values from Step 1, then restart your editor or client so it picks up
        the new MCP server.
      </Step>
    </Steps>

    <Info>
      **Local MCP server only:** the canonical tool names and `HYDRADB_*`
      variables need **@hydradb/mcp 1.1.0 or later**. If your config pins
      `@0.0.1` or `@1.0.0`, change it to `@^1.1.0` and restart. Nothing else
      changes - every name you were using before still works, and the caret
      keeps you on the 1.x line this page documents.
    </Info>
  </Tab>
</Tabs>

***

## Authenticating to the remote server

There are two ways to authenticate against `https://mcp.hydradb.com`, and the
same URL serves both.

### Sign in with HydraDB (OAuth)

Point your client at the URL with no credentials and it discovers the sign-in
flow on its own: the server answers `401` with a pointer to its metadata, your
client registers itself, and opens your browser. You sign in, choose a database,
and approve. Your client stores a token that it refreshes silently, and you never
handle a key.

Disconnect any app from **Settings → Connected apps**. That revokes its access
immediately.

### API key headers

Every request carries its own credentials, so one server serves any number of
independent users. Send them as headers:

| Header                       | Maps to                                                                                                              | Required |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------- |
| `Authorization`              | Your HydraDB API key as a `Bearer` token (`X-HydraDB-Api-Key` is also accepted), or an OAuth access token            | Yes      |
| `X-HydraDB-Database`         | Database (tenant scope). API-key requests only; ignored for an OAuth token, whose scope comes from what you approved | Yes\*    |
| `X-HydraDB-Collection`       | Collection (sub-tenant); defaults to `hydra-db-mcp`                                                                  | No       |
| `X-HydraDB-Graph-Database`   | Default graph database for the Cypher tools; defaults to the request's database                                      | No       |
| `X-HydraDB-Graph-Collection` | Default graph collection; defaults to `default`                                                                      | No       |

\* Required with an API key. Not needed, and not read, with an OAuth token.

A request that authenticates nobody is refused with `401`, and that refusal is
what starts the sign-in flow for clients that support it. A request that carries
an API key but names no database is refused with `400`; an OAuth token needs no
database header, because the database was chosen when you approved the app.

<Info>
  The API key and database resolve together: a request that supplies its own key
  must also supply its own `X-HydraDB-Database`, so your key is never paired with
  another tenant's data. The base URL, request timeout, and retry count are
  operator settings on the server and are never read from a request header.
</Info>

<Tip>
  **Per-call tenant switching:** Multi-tenant agents serving multiple companies
  from a single session can pass `database` and `collection` directly in tool
  arguments (e.g. `hydradb_query` with `{"query": "...", "database": "tenant_b"}`).
  When omitted, calls fall back to the connection's default scope: the
  `X-HydraDB-Database` / `X-HydraDB-Collection` headers for an API key, or what
  you approved for an OAuth connection.

  On an OAuth connection you approved with **other databases not allowed**, a
  per-call `database` or `collection` outside that scope is refused before the
  request leaves the server, and `hydradb_databases` shows what the connection
  may use.
</Tip>

***

## Self-hosting the HTTP server

Prefer to run the remote server yourself instead of using `mcp.hydradb.com`? Use
the npm binary or the Docker image. Set `HYDRADB_API_KEY` and `HYDRADB_DATABASE`
in the environment for a single-tenant server (clients then send no credentials),
or leave them unset for a multi-tenant one where every client authenticates with
its own headers.

<Tabs>
  <Tab title="npm">
    ```bash theme={null}
    npm install -g @hydradb/mcp
    # Single-tenant: the server holds one account
    HYDRADB_API_KEY=your-key HYDRADB_DATABASE=your-database hydradb-mcp-http
    # Multi-tenant: clients authenticate per request
    BIND_ADDRESS=0.0.0.0 ALLOWED_HOSTS=mcp.hydradb.com hydradb-mcp-http
    ```
  </Tab>

  <Tab title="Docker">
    ```bash theme={null}
    docker build -t hydradb-mcp https://github.com/hydra-db/hydradb-mcp.git
    docker run -p 8080:8080 \
      -e HYDRADB_API_KEY=your-key -e HYDRADB_DATABASE=your-database \
      hydradb-mcp
    ```
  </Tab>
</Tabs>

The primary endpoint is `POST /` (with `/mcp` supported as an alias); `GET /health` is an unauthenticated liveness probe.

| Variable          | Description                                                                           | Default           |
| ----------------- | ------------------------------------------------------------------------------------- | ----------------- |
| `PORT`            | Port to listen on                                                                     | `8080`            |
| `BIND_ADDRESS`    | Interface to bind (`0.0.0.0` to accept off-host)                                      | `127.0.0.1`       |
| `ALLOWED_HOSTS`   | Extra `Host` headers to accept (comma-separated); loopback always allowed             | *(loopback only)* |
| `ALLOWED_ORIGINS` | CORS origins for browser clients (comma-separated; `*` allows any)                    | *(none)*          |
| `TRUST_PROXY`     | Express `trust proxy` when behind a reverse proxy: a hop count, `true`, or `loopback` | *off*             |

<Warning>
  The defaults are loopback-only. When you expose the server publicly, bind
  `0.0.0.0` deliberately, set `ALLOWED_HOSTS` to your hostname, list any browser
  origins in `ALLOWED_ORIGINS`, and terminate TLS in front of it. For a shared,
  public server, leave `HYDRADB_API_KEY` unset so every caller must authenticate
  with their own key rather than sharing yours.
</Warning>

***

## Configuration

### Environment Variables

| Variable             | Description                                      | Default                   |
| -------------------- | ------------------------------------------------ | ------------------------- |
| `HYDRADB_API_KEY`    | Your HydraDB API key                             | *Required*                |
| `HYDRADB_DATABASE`   | The database to read and write                   | *Required*                |
| `HYDRADB_COLLECTION` | Collection to partition data within the database | `hydra-db-mcp`            |
| `HYDRADB_BASE_URL`   | API base URL override                            | `https://api.hydradb.com` |
| `HYDRADB_LOG_LEVEL`  | Log level: `DEBUG`, `INFO`, `WARN`, `ERROR`      | `ERROR`                   |

<Accordion title="Deprecated variable names">
  The `HYDRA_DB_*` spellings still work. Each one is read as a deprecated alias
  of its canonical name and prints a single warning to stderr naming the
  replacement; if both are set, the canonical name wins.

  | Deprecated               | Canonical            |
  | ------------------------ | -------------------- |
  | `HYDRA_DB_API_KEY`       | `HYDRADB_API_KEY`    |
  | `HYDRA_DB_TENANT_ID`     | `HYDRADB_DATABASE`   |
  | `HYDRA_DB_SUB_TENANT_ID` | `HYDRADB_COLLECTION` |
  | `HYDRA_DB_BASE_URL`      | `HYDRADB_BASE_URL`   |
  | `HYDRA_DB_LOG_LEVEL`     | `HYDRADB_LOG_LEVEL`  |

  See the [Glossary](/essentials/v2/glossary) for why `tenant` became `database`.
</Accordion>

### Collections

Use `HYDRADB_COLLECTION` to partition data across projects within one database:

```json theme={null}
{
  "mcpServers": {
    "hydradb": {
      "command": "npx",
      "args": ["-y", "@hydradb/mcp@^1.1.0"],
      "env": {
        "HYDRADB_API_KEY": "your-api-key",
        "HYDRADB_DATABASE": "your-database",
        "HYDRADB_COLLECTION": "my-project"
      }
    }
  }
}
```

<Note>
  Give each project its own `HYDRADB_COLLECTION` to keep memory isolated, or point
  several projects at the same value to share context between them. Unset, the
  server writes to and reads from `hydra-db-mcp`.
</Note>

***

## Available Tools

Tool names follow the canonical HydraDB vocabulary - one verb per action, with the
same scope names the rest of the product uses. See the
[Glossary](/essentials/v2/glossary).

| Tool                        | What it does                                                                                                        |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `hydradb_query`             | Search memories; returns matching chunks plus graph-enriched context - entity paths, chunk relations, extra context |
| `hydradb_ingest`            | Store a note (`text`) or a conversation (`turns`); HydraDB extracts insights and builds the knowledge graph         |
| `hydradb_list`              | Browse stored memories or ingested knowledge sources                                                                |
| `hydradb_inspect`           | Retrieve the original content of a source by ID                                                                     |
| `hydradb_delete`            | Remove a memory or knowledge source by ID                                                                           |
| `hydradb_list_collections`  | List collections (sub-tenants) in a database                                                                        |
| `hydradb_delete_collection` | Permanently delete a collection and all of its data                                                                 |
| `hydradb_databases`         | List the databases this connection can use, with the default marked. Available on OAuth connections                 |

### hydradb\_query

| Parameter          | Type      | Required | Description                                                                                                            |
| ------------------ | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `query`            | string    | Yes      | The search query to find relevant memories                                                                             |
| `kind`             | string    | No       | Which family to search: `memory`, `knowledge`, or `all` (default: `all`)                                               |
| `max_results`      | number    | No       | Chunks to return, 1-50 (default: `10`)                                                                                 |
| `mode`             | string    | No       | `fast` for quick semantic search, `thinking` for deeper personalised recall with graph traversal (default: `thinking`) |
| `graph_context`    | boolean   | No       | Include knowledge graph relations in the results (default: `true`)                                                     |
| `titles`           | string\[] | No       | Restrict the search to documents whose **complete** title exactly matches any value, ignoring case                     |
| `metadata_filters` | object    | No       | Exact-match metadata filters as `{key: value}`                                                                         |
| `database`         | string    | No       | Database (tenant) scope override for this request                                                                      |
| `collection`       | string    | No       | Collection (sub-tenant) scope override for this request                                                                |

#### Filtering by document title

Use `titles` when you know document names but not their source IDs. The titles are
resolved to source IDs first, then the normal semantic or keyword query runs inside
those sources.

```json theme={null}
{
  "query": "What changed in the rollout plan?",
  "titles": ["Q3 Roadmap.md", "Launch Plan.md"]
}
```

* **Exact, complete titles.** `last-usage` does not match `last-usage.csv`.
* **Case-insensitive.** `q3 roadmap.md` matches `Q3 Roadmap.md`.
* **Several titles are ORed.** Surrounding whitespace is trimmed; punctuation such
  as commas is part of the title.
* **No match returns an empty result** rather than widening to the whole corpus.

<Note>
  Because matching ignores case, two documents whose names differ only by case -
  `Report.md` and `report.md` - are treated as the same title and both are returned.
</Note>

### hydradb\_ingest

Provide exactly one of `text` or `turns`. Passing both is rejected.

| Parameter          | Type    | Required | Description                                                                                 |
| ------------------ | ------- | -------- | ------------------------------------------------------------------------------------------- |
| `text`             | string  | No\*     | The information to store                                                                    |
| `turns`            | array   | No\*     | Conversation turns to ingest instead of `text`, each with a `user` and an `assistant` field |
| `kind`             | string  | No       | What to write: `memory` (default) or `knowledge`                                            |
| `title`            | string  | No       | Title for the entry                                                                         |
| `source_id`        | string  | No       | Optional identifier for this entry                                                          |
| `infer`            | boolean | No       | Let HydraDB extract insights and build the knowledge graph (default: `true`)                |
| `is_markdown`      | boolean | No       | Treat `text` as markdown (default: `false`)                                                 |
| `metadata`         | object  | No       | Key/value metadata stored with memory, matchable later via `metadata_filters`               |
| `observation_date` | string  | No       | Calendar date YYYY-MM-DD when the fact was true                                             |
| `user_name`        | string  | No       | Name of the user, used with `turns` for personalisation (default: `User`)                   |
| `database`         | string  | No       | Database (tenant) scope override for this request                                           |
| `collection`       | string  | No       | Collection (sub-tenant) scope override for this request                                     |

### hydradb\_list

| Parameter    | Type   | Required | Description                                             |
| ------------ | ------ | -------- | ------------------------------------------------------- |
| `kind`       | string | Yes      | Which family to list: `memory` or `knowledge`           |
| `ids`        | array  | No       | Specific IDs to filter by                               |
| `page`       | number | No       | Page number, 1-indexed (default: `1`)                   |
| `page_size`  | number | No       | Items per page, 1-100                                   |
| `database`   | string | No       | Database (tenant) scope override for this request       |
| `collection` | string | No       | Collection (sub-tenant) scope override for this request |

### hydradb\_inspect

| Parameter    | Type   | Required | Description                                                                         |
| ------------ | ------ | -------- | ----------------------------------------------------------------------------------- |
| `id`         | string | Yes      | The source ID to fetch content for                                                  |
| `mode`       | string | No       | `content` for text, `url` for a presigned URL, `both` for both (default: `content`) |
| `offset`     | number | No       | Character offset to start reading from                                              |
| `limit`      | number | No       | Maximum characters to return (max `20000`)                                          |
| `database`   | string | No       | Database (tenant) scope override for this request                                   |
| `collection` | string | No       | Collection (sub-tenant) scope override for this request                             |

### hydradb\_delete

| Parameter    | Type   | Required | Description                                                                 |
| ------------ | ------ | -------- | --------------------------------------------------------------------------- |
| `ids`        | array  | No\*     | IDs to delete                                                               |
| `id`         | string | No\*     | Single ID to delete (prefer `ids` when deleting multiple)                   |
| `kind`       | string | No       | Which family the ID belongs to: `memory` or `knowledge` (default: `memory`) |
| `database`   | string | No       | Database (tenant) scope override for this request                           |
| `collection` | string | No       | Collection (sub-tenant) scope override for this request                     |

### hydradb\_list\_collections

| Parameter  | Type   | Required | Description                                                                  |
| ---------- | ------ | -------- | ---------------------------------------------------------------------------- |
| `database` | string | No       | Database to list collections for (default: the server's configured database) |

### hydradb\_delete\_collection

Permanently removes one collection and every memory, knowledge source, and graph node inside it. The parent database is left intact.

| Parameter    | Type   | Required | Description                                                                   |
| ------------ | ------ | -------- | ----------------------------------------------------------------------------- |
| `collection` | string | Yes      | Collection (sub-tenant) to delete. Take it from `hydradb_list_collections`.   |
| `database`   | string | No       | Database that owns the collection (default: the server's configured database) |

### hydradb\_status

| Parameter    | Type   | Required | Description                                             |
| ------------ | ------ | -------- | ------------------------------------------------------- |
| `ids`        | array  | Yes      | The source IDs to check indexing status for             |
| `database`   | string | No       | Database (tenant) scope override for this request       |
| `collection` | string | No       | Collection (sub-tenant) scope override for this request |

### hydradb\_databases

Available on connections made with **Sign in with HydraDB**. Takes no parameters.

Lists the databases this connection can address and marks the one it uses by
default, so an agent working across several databases can find their names
without asking you. If you approved the app with **other databases not allowed**,
the list has one entry and any other name is refused.

### Graph tools (BYOG openCypher)

HydraDB MCP also exposes property graph tools for querying and writing domain graphs in openCypher:

* **`hydradb_graph_query`**: Run Cypher reads and writes (`CREATE`, `MERGE`, `MATCH`, traversals).
  * Parameters: `query` (string, required), `params` (object), `database` (string), `collection` (string), `max_rows` (number).
* **`hydradb_graph_collections`**: List graph collections in a database.
  * Parameters: `database` (string).
* **`hydradb_graph_admin`**: Manage graph databases and collections.
  * Parameters: `action` (`create_database`, `drop_collection`, `drop_database`), `database` (string), `collection` (string).

<Warning>
  `hydradb_delete` is irreversible.
</Warning>

<Note>
  A knowledge source cannot be deleted while it is still being indexed - the
  server refuses with *"Source is still processing; retry deletion after
  ingestion completes"*, and the tool passes that back rather than reporting a
  deletion that did not happen. Retry once ingestion finishes. This applies to
  freshly ingested sources only; a source is listable and inspectable before it
  is deletable.
</Note>

### Deprecated tool names

Tool names live in your `mcp.json`, so none were removed. Every earlier name is
still registered and still works; each is marked deprecated in its description so
your agent prefers the canonical one. Use the canonical names in new integrations.

| Deprecated                     | Canonical                          |
| ------------------------------ | ---------------------------------- |
| `hydra_db_search`              | `hydradb_query`                    |
| `hydra_db_store`               | `hydradb_ingest`                   |
| `hydra_db_ingest_conversation` | `hydradb_ingest` (pass `turns`)    |
| `hydra_db_list_memories`       | `hydradb_list` (`kind: memory`)    |
| `hydra_db_list_sources`        | `hydradb_list` (`kind: knowledge`) |
| `hydra_db_fetch_content`       | `hydradb_inspect`                  |
| `hydra_db_delete_memory`       | `hydradb_delete`                   |

***

## How It Works

At recall time, `hydradb_query` queries HydraDB and returns graph-enriched context -
entity paths, chunk relations, and linked extra context - injected directly into the
model's prompt.

At capture time, `hydradb_ingest` sends content with `infer: true`, triggering
HydraDB's knowledge graph extraction pipeline automatically. The same tool takes a
document (`text`) or a conversation (`turns`), and groups related writes under
`source_id`.

***

## Source & Show Support

<Note>
  If this HydraDB MCP server makes your agentic memory workflow faster (and smarter), please star the open-source repo that powers it.

  <Card title="hydradb-mcp" icon="star" href="https://github.com/hydra-db/hydradb-mcp">
    Star on GitHub if you found it useful.
  </Card>
</Note>
