MCP

Quick start

Five minutes to an assistant that answers from your documents. Create an API key, paste the block your client reads, ask a question. There is one server and one key behind all of it, and only Claude Desktop runs anything on your machine.

1. Create an API key

In the app, open Settings > API keys and create one. Scope it to what the assistant will actually do:

To do thisThe key needs
Connect at all, and call list_corpora, list_documents, query_corpus, sync_statusquery
Call add_document as wellquery and ingest

The secret is shown once, at creation, and never again. Give each client its own key so revoking one does not take the others down. From the terminal it is one command each:

engram keys create --name "claude-desktop" --scope query
engram keys create --name "agent-writer" --scope query --scope ingest

engram keys revoke <id> kills a key immediately. More on API keys and scopes.

2. Point your client at the server

Engram runs one MCP server for your whole workspace, over streamable HTTP, at:

https://api.engramdynamics.org/mcp-http/

The trailing slash matters: the mount's own route is /, so the un-slashed path answers with a redirect. Authentication is the API key on an Authorization: Bearer header.

Every client below reaches that one endpoint with that one key. What differs is how each client writes a remote server down, and a client handed the wrong shape starts up, lists no tools, and says nothing about why. So find yours, paste its block, restart it. The app shows the same blocks behind a picker on Settings > MCP, and the CLI prints them with engram mcp --client <name>.

Claude Code

One line, no file to edit:

claude mcp add --transport http engram https://api.engramdynamics.org/mcp-http/ \
  --header "Authorization: Bearer <your API key>"

Or check it into the project as .mcp.json, so everyone on the repo gets it:

{
  "mcpServers": {
    "engram": {
      "type": "http",
      "url": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

Claude Desktop

Claude Desktop is the one client that cannot take a remote server. Its claude_desktop_config.json only launches programs on your machine, so an entry with a url in it is ignored: no tools, no error, and no log file to read. The fix is a small local bridge, mcp-remote, which talks to Claude Desktop the way it expects and relays to the hosted server.

On Windows, in %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "engram": {
      "command": "cmd",
      "args": [
        "/c", "npx", "-y", "mcp-remote",
        "https://api.engramdynamics.org/mcp-http/",
        "--header", "Authorization:Bearer ${ENGRAM_API_KEY}"
      ],
      "env": { "ENGRAM_API_KEY": "<your API key>" }
    }
  }
}

On macOS, in ~/Library/Application Support/Claude/claude_desktop_config.json, and on Linux:

{
  "mcpServers": {
    "engram": {
      "command": "npx",
      "args": [
        "-y", "mcp-remote",
        "https://api.engramdynamics.org/mcp-http/",
        "--header", "Authorization:Bearer ${ENGRAM_API_KEY}"
      ],
      "env": { "ENGRAM_API_KEY": "<your API key>" }
    }
  }
}

Two things to get right, because either one leaves you with the same silent failure:

The key sits in env and the header points at it, which keeps the secret out of the command line the bridge is launched with.

Cursor

~/.cursor/mcp.json for every project, or .cursor/mcp.json inside one. Cursor knows a server is remote because it has a url, so there is no transport to name:

{
  "mcpServers": {
    "engram": {
      "url": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

Windsurf

~/.codeium/windsurf/mcp_config.json. The field is serverUrl here, not url:

{
  "mcpServers": {
    "engram": {
      "serverUrl": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

VS Code (GitHub Copilot)

.vscode/mcp.json in the workspace. Note the outer key: VS Code calls it servers, where everyone else says mcpServers:

{
  "servers": {
    "engram": {
      "type": "http",
      "url": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

Gemini CLI

~/.gemini/settings.json. The field is httpUrl, which is how Gemini CLI tells streamable HTTP from SSE:

{
  "mcpServers": {
    "engram": {
      "httpUrl": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

Cline

Open the file from Cline itself: MCP Servers > Configure > Configure MCP Servers. The transport is spelled streamableHttp:

{
  "mcpServers": {
    "engram": {
      "type": "streamableHttp",
      "url": "https://api.engramdynamics.org/mcp-http/",
      "headers": { "Authorization": "Bearer <your API key>" }
    }
  }
}

The block contains a live credential. Treat the config file like a password: do not commit it, and prefer a key scoped to exactly what the client needs. To cut a client off, revoke its key in Settings > API keys.

3. Ask the assistant something

Restart the client so it picks up the config, and the five Engram tools appear. If none of them do, the block is almost always in the wrong shape or the wrong file, which Troubleshooting walks through. A good first prompt is one that forces a tool call and shows you the sources:

Which Engram document bases can you see? Then ask the Support KB what it says
about refund eligibility, and cite the documents.

The first half calls list_corpora, which is the fastest confirmation that the key reached the right workspace. The second calls query_corpus, and the answer comes back with a Sources list naming each document and its doc_id. Those ids are pinnable: a follow-up can pass them back so the same evidence is used again without re-retrieving.

One connection, every document base

The connection is to the workspace, not to a base, so there is nothing to add when you create your next document base. The assistant names the base it wants as the corpus argument of each tool, by exact name or by id, and list_corpora is how it learns the names. A name that matches two bases is an error listing their ids, never a guess at which one you meant, so keep names distinct.

The same key reaches every base it can see, which means access is a property of the key rather than of the config file. Narrow what a client can reach by narrowing the key's scopes.

Print the block from the CLI

This command needs CLI 0.3.0 or later, and --client needs 0.3.1. Run engram --version to check, and pip install -U engram-dynamics to upgrade.

If you already use the CLI, it prints the block for the profile you are logged in on, so the url and the key are filled in for you, and --client picks the spelling:

engram mcp
engram mcp --client claude-desktop
engram mcp --client vscode > .vscode/mcp.json

The choices are claude-code (the default), claude-desktop, cursor, windsurf, vscode, gemini-cli and cline. On Windows the Claude Desktop block comes out in its Windows form.

It prints JSON on stdout and where to paste it on stderr, so redirecting the command gives you a clean file. Add --profile <name> to print the block for another environment. Installing the CLI is on Overview and install, and it is optional: the app shows the same block on every document base's MCP tab.

Next