> ## Documentation Index
> Fetch the complete documentation index at: https://artemiscity.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Governed Artemis Memory MCP server

> Run the Python `artemis-memory-mcp` server that exposes the canonical Postgres memory ledger to agents through four governed Model Context Protocol tools.

The **Governed Artemis Memory MCP server** (`artemis-memory-mcp`) is a Python Model Context Protocol server built on the official MCP SDK. It exposes the canonical Postgres/Neon memory ledger to agents as four typed tools, and authorizes every call through the `GovernedGate` — combining a capability grant (`memory:read` or `memory:write`) with a per-namespace scope check.

Use this server when you want agents to read and write the durable memory ledger under governance, with strict ATP validation and namespace isolation, rather than talking directly to an Obsidian vault.

<Note>
  This is a **different surface** from the [Agentic Memory Layer (MCP server)](/Documentation/integrations/agentic-memory-layer). The Agentic Memory Layer is a Node.js REST shell backed by an Obsidian vault; `artemis-memory-mcp` is a Python MCP server backed by the Postgres/Neon ledger, with Obsidian and the vector index treated as best-effort projections. Both can run side by side.
</Note>

## When to use it

Choose `artemis-memory-mcp` when you need:

* A **governed** memory surface where every call is validated as an ATP envelope, checked against a principal's capability grants, and scoped to one namespace.
* The Postgres/Neon ledger as the source of truth, with Obsidian and the vector index as durable-outbox projections.
* Structured, typed tool schemas (`write-memory`, `read-memory`, `search-memory`, `get-memory-status`) rather than a REST surface.
* A native MCP transport (`stdio` for local co-processes, authenticated Streamable HTTP for network deployments).

Choose the [Agentic Memory Layer](/Documentation/integrations/agentic-memory-layer) instead when your agents primarily need to read, write, tag, and search notes in a human-curated Obsidian vault.

## Tools

The server exposes four MCP tools. Each takes a typed input that includes an `AtpEnvelope`, and returns a typed result. Content and metadata are stored on the canonical Postgres ledger; projections (Obsidian, vector) are written best-effort through the durable outbox.

| Tool                | Purpose                                                                                                                                           |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `write-memory`      | Append a new immutable version to `(namespace, key)` and request projections. Requires `memory:write` plus the matching namespace scope.          |
| `read-memory`       | Read the current version of `(namespace, key)` from the ledger. Requires `memory:read` plus the matching namespace scope.                         |
| `search-memory`     | Bounded search within one namespace, returning record identifiers without full content. Requires `memory:read` plus the matching namespace scope. |
| `get-memory-status` | Report the projection delivery status for one immutable record version. Requires `memory:read` plus the matching namespace scope.                 |

## Governance and namespace scopes

Every tool call is authorized through `GovernedGate` in two layers:

1. **Capability grant.** The caller must hold `memory:read` for read-side tools, or `memory:write` for `write-memory`.
2. **Namespace scope.** The caller must additionally hold `memory:namespace:{namespace}` for the exact namespace being addressed, or the wildcard `memory:namespace:*` for all namespaces.

A `memory:write` or `memory:read` grant on its own is **not sufficient** — every call also needs the matching namespace scope. This makes it possible to grant an agent read/write access to one namespace without exposing every other tenant's memory on the same ledger.

Grants are supplied as a comma-separated list in `ARTEMIS_MCP_CAPABILITIES` for the stdio transport, or in `ARTEMIS_MCP_HTTP_SCOPES` for the HTTP transport.

## Projection status semantics

`write-memory` commits the record to the canonical Postgres ledger and then dispatches best-effort projections (for example, Obsidian and vector). `get-memory-status` reports the delivery status of each projection for one immutable record version, using four values:

| Status      | Meaning                                                                                                             |
| ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `pending`   | The projection is queued in the durable outbox and has not yet completed.                                           |
| `succeeded` | The projection was delivered to the target.                                                                         |
| `failed`    | The projection failed and remains retryable through the durable outbox. It is never silently reported as delivered. |
| `skipped`   | The projection was not requested for this write, or the target is not configured.                                   |

**A projection failure never removes the committed SQL record.** If Obsidian or the vector backend is unreachable, the Postgres ledger row is still the source of truth, and the failed projection can be retried from the outbox.

## Transports

The server supports two transports. The default is `stdio` for local co-process deployments; `--http` runs an authenticated Streamable HTTP endpoint at `/mcp`.

### stdio

Best for embedding the server as a subprocess of a local agent or CLI. The transport principal is the process itself, and capabilities are supplied through the environment.

```bash theme={null}
export ARTEMIS_MEMORY_DATABASE_URL=postgresql://...
export ARTEMIS_MCP_PRINCIPAL_ID=local-operator
export ARTEMIS_MCP_CAPABILITIES=memory:write,memory:read,memory:namespace:*
uv run artemis-memory-mcp
```

### Streamable HTTP

Best for network deployments where multiple clients hit one server. The transport authenticates every request with a bearer token, and the token is mapped to a synthetic principal whose capability grants come from `ARTEMIS_MCP_HTTP_SCOPES`.

```bash theme={null}
export ARTEMIS_MEMORY_DATABASE_URL=postgresql://...
export ARTEMIS_MCP_BEARER_TOKEN=...
export ARTEMIS_MCP_HTTP_CLIENT_ID=artemis-mcp
export ARTEMIS_MCP_HTTP_SUBJECT=memory-service
export ARTEMIS_MCP_HTTP_SCOPES=artemis:memory,memory:write,memory:read,memory:namespace:*
export ARTEMIS_MCP_AUTH_ISSUER_URL=https://issuer.example.com
export ARTEMIS_MCP_RESOURCE_SERVER_URL=https://memory.example.com
uv run artemis-memory-mcp --http --host 0.0.0.0 --port 8000
```

`ARTEMIS_MCP_HTTP_SCOPES` must include the transport-wide `artemis:memory` scope in addition to the capability and namespace grants. Requests presenting a bearer token without `artemis:memory` are rejected at the transport before any tool call.

## Configuration

Nothing is opened at import time. Configuration is validated and connections are built lazily per operation, so a misconfigured deployment fails on the first tool call rather than at process startup.

| Variable                                    | Required by                            | Purpose                                                                                                                                                       |
| ------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ARTEMIS_MEMORY_DATABASE_URL`               | stdio and HTTP                         | PostgreSQL/Neon connection string for the canonical ledger. Operator-supplied secret.                                                                         |
| `ARTEMIS_MEMORY_DB_CONNECT_TIMEOUT_SECONDS` | Optional                               | Connection timeout in seconds. Defaults to `10`.                                                                                                              |
| `ARTEMIS_MEMORY_DB_STATEMENT_TIMEOUT_MS`    | Optional                               | Per-statement timeout in milliseconds. Defaults to `5000`.                                                                                                    |
| `OBSIDIAN_VAULT_PATH`                       | stdio and HTTP                         | Vault root for the Obsidian projection.                                                                                                                       |
| `ARTEMIS_VECTOR_BACKEND`                    | Optional                               | `sqlite` (default) or `supabase`. An explicit `supabase` selection that cannot be constructed fails setup rather than silently falling back to SQLite.        |
| `ARTEMIS_SUPABASE_DB_URL`                   | When `ARTEMIS_VECTOR_BACKEND=supabase` | Postgres connection string for the vector backend. Operator-supplied secret.                                                                                  |
| `ARTEMIS_MCP_PRINCIPAL_ID`                  | stdio only                             | The local service principal's identity.                                                                                                                       |
| `ARTEMIS_MCP_CAPABILITIES`                  | stdio only                             | Comma-separated capability and scope grants, for example `memory:write,memory:read,memory:namespace:*`.                                                       |
| `ARTEMIS_MCP_BEARER_TOKEN`                  | HTTP only                              | The single accepted bearer token. Operator-supplied secret.                                                                                                   |
| `ARTEMIS_MCP_HTTP_CLIENT_ID`                | HTTP only                              | Client ID reported for a verified bearer token.                                                                                                               |
| `ARTEMIS_MCP_HTTP_SUBJECT`                  | HTTP only                              | Principal subject reported for a verified bearer token.                                                                                                       |
| `ARTEMIS_MCP_HTTP_SCOPES`                   | HTTP only                              | Comma-separated grants for the bearer token, using the same vocabulary as `ARTEMIS_MCP_CAPABILITIES`. Must include the transport-wide `artemis:memory` scope. |
| `ARTEMIS_MCP_AUTH_ISSUER_URL`               | HTTP only                              | OAuth issuer URL advertised to clients.                                                                                                                       |
| `ARTEMIS_MCP_RESOURCE_SERVER_URL`           | HTTP only                              | This server's own resource URL, for example `https://memory.example.com`.                                                                                     |

## Database migrations

The server targets a specific schema. Before pointing `ARTEMIS_MEMORY_DATABASE_URL` at any database, apply the two migrations in order:

1. `0001_memory_write_through.sql` — creates the base ledger, outbox, and provenance tables.
2. `0002_memory_server_contract.sql` — evolves the schema for namespace/key identity, principal and provenance columns, the `vector` outbox target, and the `memory_completion_provenance` table.

Both migrations must be applied against a verified disposable environment before targeting a production database. Pointing the server at a database that has only `0001` applied will fail at the first tool call.

## Example: end-to-end write and status check

The following sequence starts the server over stdio, writes one memory record, and then checks its projection status. It assumes the target database has both migrations applied.

```bash theme={null}
export ARTEMIS_MEMORY_DATABASE_URL=postgresql://...
export ARTEMIS_MCP_PRINCIPAL_ID=local-operator
export ARTEMIS_MCP_CAPABILITIES=memory:write,memory:read,memory:namespace:agents
uv run artemis-memory-mcp
```

A client then invokes `write-memory` with an ATP envelope in the `agents` namespace, receives a `WriteMemoryResult` containing the new `record_id` and `projection_states`, and can call `get-memory-status` with the same `record_id` to see whether each projection has reached `succeeded`, is still `pending`, or has `failed` and is queued for retry.

## Related

* [Agentic Memory Layer (MCP server)](/Documentation/integrations/agentic-memory-layer) — the Node.js REST shell backed by an Obsidian vault.
* [Artemis Agentic Memory Layer](/Documentation/memory/MEMORY_INTEGRATION) — the Python client and trust-aware wrapper for the Obsidian-backed layer.
* [Hybrid Memory Bus](/Documentation/memory/hybrid-memory-bus) — how the memory subsystem composes ledger, projections, and retrieval.
