Guide5 min read
Graphiti MCP ServerSetup 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.
| Step | Command or setting | Default |
|---|---|---|
| Start server and graph database | docker compose up in mcp_server/ | FalkorDB in the same container |
| MCP endpoint | http://localhost:8000/mcp/ | HTTP transport |
| Health check | curl http://localhost:8000/health | |
| Claude Code | claude mcp add --transport http graphiti-memory http://localhost:8000/mcp/ | |
| Cursor | "url": "http://localhost:8000/mcp/" in mcp.json | |
| Claude Desktop | npx mcp-remote http://localhost:8000/mcp/ | stdio bridge |
| Namespace | --group-id <project> | main |
| Concurrency | SEMAPHORE_LIMIT in .env | 10 |
| Telemetry | GRAPHITI_TELEMETRY_ENABLED=false | on |
Recommended path: one container, FalkorDB, HTTP
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:
| Setup | Command | Use it when |
|---|---|---|
| FalkorDB combined (recommended) | docker compose up | One developer, local memory |
| FalkorDB in its own container | docker compose -f docker/docker-compose-falkordb.yml up | You restart server and database separately |
| Neo4j | docker compose -f docker/docker-compose-neo4j.yml up | Your team already runs Neo4j 5.26+ |
| No Docker | uv sync then uv run main.py --database-provider falkordb | You point at an existing FalkorDB |
| stdio | uv run main.py --transport stdio | The 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
| Tool | What it does |
|---|---|
add_memory | Adds an episode (text, JSON or messages) with an optional reference_time |
add_triplet | Writes one fact directly, without extraction |
search_nodes | Finds entities, filterable by entity_types |
search_memory_facts | Finds facts (edges), filterable by valid_at and invalid_at |
get_episodes | Lists recent episodes for one or more groups |
get_episode_entities | Shows which entities and facts an episode created |
delete_episode, delete_entity_edge | Removes an episode or a single fact |
clear_graph | Deletes all data for the given groups |
get_status | Checks 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 tier | Requests per minute | SEMAPHORE_LIMIT |
|---|---|---|
| OpenAI Tier 1 | 3 | 1–2 |
| OpenAI Tier 2 | 60 | 5–8 |
| OpenAI Tier 3 | 500 | 10–15 |
| Anthropic default | 50 | 5–8 |
| Anthropic high tier | 1,000 | 15–30 |
| Ollama (local) | hardware | 1–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_memoryas 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.
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.