# MCP server

> StateJar's memory as Model Context Protocol tools at https://statejar.com/mcp, for any client that speaks MCP over HTTP. Ten tools, a developer key as the bearer token, and the same limits, checks and audit trail as the REST API.

## What it does

`https://statejar.com/mcp` is a hosted MCP server: Streamable HTTP, stateless, JSON responses. A client that speaks MCP over HTTP gets these ten tools:

| Tool | What it does |
|---|---|
| `remember` | Stores the facts in a message. Secrets are removed first. The reply lists what was stored, held until said again, or declined, each with its reason. |
| `search` | The memory a question needs, as `memory_context`, with the handle it came from and the audit id of the disclosure. |
| `get` | The current state, one fact of it, or the state a handle names. The handle is re-derived first. |
| `list` | Every fact of the current state, as path and value. |
| `update` | A correction in your own words, stored as a new version. |
| `delete` | Removes one fact from the current state as a new version. History keeps it. |
| `history` | The versions, newest first, by handle. |
| `audit` | What was disclosed, newest first. |
| `verify` | Re-derives a handle from the stored state. |
| `export` | Every version with its handle and state. |

Each tool calls StateJar's own REST routes with your key. The same account, the same plan limits, the same type checks and the same audit rows apply as on the REST API.

## Install

There is nothing to install. Make a developer key on the [API keys page](/api-keys) and put it in `STATEJAR_API_KEY`, then add the server to your client.

Claude Code:

```bash
claude mcp add --transport http statejar https://statejar.com/mcp --header "Authorization: Bearer $STATEJAR_API_KEY"
```

Codex:

```bash
codex mcp add statejar --url https://statejar.com/mcp --bearer-token-env-var STATEJAR_API_KEY
```

OpenCode, in `opencode.json`:

```json
{
  "mcp": {
    "statejar": {
      "type": "remote",
      "url": "https://statejar.com/mcp",
      "oauth": false,
      "headers": { "Authorization": "Bearer {env:STATEJAR_API_KEY}" }
    }
  }
}
```

Any other client: a remote (HTTP) MCP server at `https://statejar.com/mcp`, with your developer key in the header `Authorization: Bearer sj_live_…`.

For memory that is recalled and captured on its own, not only through tools, use the plugin for your client: [Claude Code](/docs/claude-code.html), [Codex](/docs/codex.html), [OpenCode](/docs/opencode.html), [OpenClaw](/docs/openclaw.html) or [Hermes Agent](/docs/hermes.html).

## Set it up

- **Scope.** Every tool takes an optional `session`, the scope inside your account (a project, an agent, a chat). The default is `mcp`. A new scope's first message builds on your newest memory in any scope.
- **Limits.**
  - A message for `remember` can be at most 20,000 characters, and one request at most 256 KB.
  - Each key has a limit on MCP requests a minute; past it the server answers `429`.
  - Each tool's own calls count against your plan's limits, as REST calls do ([pricing and payments](/docs/pricing-and-payments.html)).
- **Keys.** A key belongs to one account and sees only that account's memory. Revoke it on the API keys page and the next request is refused.

## Check it works

1. Your client lists `statejar` as connected (`claude mcp list`, `codex mcp list` or `opencode mcp list`).
2. Ask the assistant to remember this: "I'm Kavya, I live in Bengaluru and my laptop budget is 80000 rupees." The `remember` reply lists the facts stored.
3. In a new chat, ask "what is my laptop budget?". The assistant's `search` returns the budget and the handle (`shm_…`) it came from.
4. The [audit log](/audit) lists that disclosure.

## What it sends

- **To StateJar:** what you ask a tool to remember, with secrets removed first, and the questions you search with. Secrets here are API keys and tokens, private keys, passwords written after their name, and card numbers. `remember` reports how many were removed, never what they were.
- **What StateJar keeps:** typed facts, never the message. The server logs no message, value or key.
- **What you can see:** every `search` is a disclosure in your audit log, with the fields it sent.
- **Your key:** goes to StateJar over HTTPS on every request. StateJar keeps only its SHA-256 hash.

## Troubleshooting

- **`401`:** no key, or the key is wrong, revoked or expired. The answer carries a `WWW-Authenticate` header that points to `/.well-known/oauth-protected-resource/mcp`. Make a new key and set it again.
- **The client asks you to sign in:** it is trying OAuth. In OpenCode, set `"oauth": false` on the `statejar` entry. Any client must send the key as a bearer token.
- **`421 Misdirected Request`:** the request was addressed to a host other than `statejar.com`, for example through a proxy that rewrites the `Host` header.
- **`429`:** too many requests a minute from one key, or your plan's limit ([what each limit counts](/docs/pricing-and-payments.html)). Wait a minute and try again.
- **A message is refused as too long:** `remember` takes at most 20,000 characters. Send it in parts.
