Guide5 min read

Graphiti MCP ServerSetup for Claude Code, Cursor and Desktop

graphitimcpclaude-codeknowledge-graph
Graphiti MCP Server: Setup for Claude Code, Cursor and Desktop

Last tested: October 2026, Graphiti MCP server 1.1, graphiti-core 0.30, FalkorDB combined container.

The Graphiti MCP server gives your coding assistant a temporal knowledge graph as memory. Getting it running takes ten minutes. Keeping it useful depends on two settings most quickstarts skip: the group_id that separates your projects, and the concurrency limit that keeps your LLM provider from rate-limiting ingestion.

TL;DR: how do I set up the Graphiti MCP server?

Clone getzep/graphiti, put your OpenAI key in mcp_server/.env, run docker compose up and point your client at http://localhost:8000/mcp/. Claude Code and Cursor connect over HTTP directly. Claude Desktop needs the mcp-remote bridge. Set a group_id per project and lower SEMAPHORE_LIMIT to your provider tier before the first bulk import.

StepCommand or settingDefault
Start server and graph databasedocker compose up in mcp_server/FalkorDB in the same container
MCP endpointhttp://localhost:8000/mcp/HTTP transport
Health checkcurl http://localhost:8000/health
Claude Codeclaude mcp add --transport http graphiti-memory http://localhost:8000/mcp/
Cursor"url": "http://localhost:8000/mcp/" in mcp.json
Claude Desktopnpx mcp-remote http://localhost:8000/mcp/stdio bridge
Namespace--group-id <project>main
ConcurrencySEMAPHORE_LIMIT in .env10
TelemetryGRAPHITI_TELEMETRY_ENABLED=falseon

The server defaults to FalkorDB, bundled in a single container with the MCP server, and to the HTTP transport. That is the setup to start with. One command brings up the graph database on port 6379, the FalkorDB browser on port 3000 and the MCP endpoint on port 8000.

git clone https://github.com/getzep/graphiti.git
cd graphiti/mcp_server
cp .env.example .env
# in .env: OPENAI_API_KEY=..., SEMAPHORE_LIMIT=5, GRAPHITI_TELEMETRY_ENABLED=false
docker compose up -d
curl -s http://localhost:8000/health

The .env file must sit in mcp_server/, the parent of the docker/ folder. Run compose from docker/ and the container starts without your keys, then fails on the first memory.

The other setups exist for specific reasons:

SetupCommandUse it when
FalkorDB combined (recommended)docker compose upOne developer, local memory
FalkorDB in its own containerdocker compose -f docker/docker-compose-falkordb.yml upYou restart server and database separately
Neo4jdocker compose -f docker/docker-compose-neo4j.yml upYour team already runs Neo4j 5.26+
No Dockeruv sync then uv run main.py --database-provider falkordbYou point at an existing FalkorDB
stdiouv run main.py --transport stdioThe client cannot speak HTTP

Connect Claude Code to the Graphiti MCP server

Claude Code speaks HTTP, so one command registers the server:

claude mcp add --transport http graphiti-memory http://localhost:8000/mcp/
claude mcp list

Add --scope project to write the entry into the repository’s .mcp.json, so everyone who clones the repo gets the same memory server.

Connect Cursor and Claude Desktop

Cursor takes the URL in its MCP configuration:

{
  "mcpServers": {
    "graphiti-memory": {
      "url": "http://localhost:8000/mcp/"
    }
  }
}

Claude Desktop does not connect to this HTTP endpoint natively. Route it through mcp-remote in claude_desktop_config.json, then restart the app:

{
  "mcpServers": {
    "graphiti-memory": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8000/mcp/"]
    }
  }
}

Set group_id before the first memory lands

Every add_memory call writes into a group, and the default group is main. On FalkorDB each group_id is its own graph. Leave everything in main and the assistant working in client B’s repository will recall client A’s decisions, because nothing told it they belong apart.

Run one server per project when you work without Docker:

uv run main.py --group-id acme-billing

With the shared container, pass group_id on each tool call and use the same value when you read, delete or clear. Separating groups after the fact means re-ingesting.

Graphiti MCP tools: what the assistant can call

ToolWhat it does
add_memoryAdds an episode (text, JSON or messages) with an optional reference_time
add_tripletWrites one fact directly, without extraction
search_nodesFinds entities, filterable by entity_types
search_memory_factsFinds facts (edges), filterable by valid_at and invalid_at
get_episodesLists recent episodes for one or more groups
get_episode_entitiesShows which entities and facts an episode created
delete_episode, delete_entity_edgeRemoves an episode or a single fact
clear_graphDeletes all data for the given groups
get_statusChecks server and database connection

clear_graph sits in the same tool list as search_nodes. Any agent with the server attached can call it. In Claude Code, deny the destructive tools in .claude/settings.json:

{
  "permissions": {
    "deny": [
      "mcp__graphiti-memory__clear_graph",
      "mcp__graphiti-memory__delete_episode"
    ]
  }
}

Run the Graphiti MCP server with Ollama

No OpenAI key is needed. Point the OpenAI provider at Ollama’s compatible endpoint in config.yaml and embed locally:

llm:
  provider: "openai"
  model: "gpt-oss:120b"
  api_base: "http://localhost:11434/v1"
  api_key: "ollama"
  structured_output_mode: "json_object"

embedder:
  provider: "sentence_transformers"
  model: "all-MiniLM-L6-v2"

Graphiti depends on structured JSON for extraction and deduplication. Small models emit objects that miss fields such as extracted_entities, which surfaces as failed ingestion. json_object puts the schema into the prompt instead of trusting the endpoint to enforce it. Use the largest model your hardware can run.

Fix 429 errors during ingestion

One episode is several LLM calls: entity extraction, deduplication, summaries. SEMAPHORE_LIMIT=10 means ten episodes in parallel, so the real request rate is a multiple of that. The values the project recommends:

Provider tierRequests per minuteSEMAPHORE_LIMIT
OpenAI Tier 131–2
OpenAI Tier 2605–8
OpenAI Tier 350010–15
Anthropic default505–8
Anthropic high tier1,00015–30
Ollama (local)hardware1–5

Too high shows up as 429s in the server log and a larger bill. Too low shows up as a slow queue. Start low before importing a backlog.

Who should be allowed to write memory?

Out of the box, the assistant decides what becomes a fact. For a personal scratch graph that is fine. For a graph that holds client decisions, a wrong fact written once gets recalled in every later session. I put an approval step between the agent and the graph: the agent proposes, a human ratifies, and only then does the fact land. Graphiti Local is that setup as open source, and approval gates for agent memory explains why the gate sits on writes, not reads. If you want this running on your team’s own graph, that is the work behind knowledge graph consulting.

Changelog

  • 2026-10-12: First version, written against the Graphiti MCP server 1.1 documentation: HTTP transport and FalkorDB by default, add_memory as the write tool, SEMAPHORE_LIMIT guidance per provider tier.

Frequently asked questions

What is the Graphiti MCP server?

It is the Model Context Protocol server that ships in the Graphiti repository. It exposes a temporal knowledge graph as tools such as add_memory, search_nodes and search_memory_facts, so an assistant like Claude Code or Cursor can store facts and read them back across sessions.

Which MCP clients work with the Graphiti MCP server?

Any client that speaks MCP. Claude Code, Cursor and VS Code connect over HTTP to http://localhost:8000/mcp/. Claude Desktop needs the mcp-remote bridge for the HTTP endpoint, or you start the server with the stdio transport.

Does the Graphiti MCP server need Neo4j?

No. The default is FalkorDB, bundled with the server in one Docker container. Neo4j 5.26 or later remains supported through a separate compose file or the --database-provider neo4j flag.

Can we run the Graphiti MCP server with Ollama instead of OpenAI?

Yes. Configure the openai provider with api_base http://localhost:11434/v1 and a dummy key, and use sentence_transformers for embeddings. Use the largest model your hardware runs, and set structured_output_mode to json_object if extraction returns objects with missing fields.

How do we keep memories from different projects or clients apart?

Use group_id. Every memory lands in a group, and the default is main. On FalkorDB each group_id is stored as its own graph. Start one server per project with --group-id, or pass group_id on every tool call.

What causes 429 errors when the Graphiti MCP server ingests memories?

Concurrency. Each episode triggers several LLM calls for extraction, deduplication and summaries, and SEMAPHORE_LIMIT defaults to 10 parallel episodes. Lower it to match your provider tier, for example 5 to 8 on Anthropic's default tier and 1 to 5 on a local Ollama.

The context layer for your AI agents

Your agents answer from whatever the retriever finds, and too often that is last quarter's truth. I build the context layer they answer and act from: a temporal knowledge graph that keeps every fact with its source and the time it held, reads with each person's own permissions, and writes nothing without a person's approval. On your own tenant, billed by the hour, step by step.

Get your AI pilot checked