cognee-mcp
cognee-mcp runs cognee's memory engine as a Model Context Protocol server, letting any MCP client (terminal or IDE) store, recall, and delete agent memory and query indexed code graphs over stdio, SSE, or streamable HTTP.
remember — store text or a base64 file upload (≤10 MB) as permanent graph memory (add + cognify + improve) or as fast session cache when
session_idis given; supportsbackgroundingestion,dataset_name,ontology_key,custom_prompt, andself_improvement=Falseopt-out.recall — search memory with auto-routing, session-first lookup, and fall-through to the permanent graph; controls include
scope(graph, session, trace, tools, code, all, auto),datasets,top_k,search_type, andsystem_prompt; responses start with a count/state summary (found,indexing,build_failed,none).forget — delete a single data item (
data_id+ dataset/dataset_id), an entire dataset by name or id, or all owned memory witheverything=True.code_search — deterministic queries against an indexed code dataset via operations
query_facts,explore,traverse,find_path,impact_analysis,insights,architecture, anddelta.cognify_status — check progress of background ingestion started by
remember(background=True); unadvertised by default but discoverable and callable.search_tools / call_tool — discover and invoke tools not pinned in
tools/list(controlled byCOGNEE_MCP_TOOL_MODE: default/minimal pin remember, recall, forget;alladvertises everything).Connection modes — run locally against local databases (direct), against Cognee Cloud via
--serve-url/COGNEE_SERVICE_URL, or against an already-running Cognee FastAPI server in API mode (which exposes only remember, recall, forget, cognify_status).Transports & deployment — stdio (default), SSE, or Streamable HTTP with Host/Origin DNS-rebinding protection; Docker images with
TRANSPORT_MODEand runtimeEXTRASoptional dependency installs.Memory scoping — per-client auto-named datasets by default (
COGNEE_MCP_AGENT_SCOPED=falseto sharemain_dataset), and per-dataset storage isolation viaENABLE_BACKEND_ACCESS_CONTROL.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@cognee-mcpingest my project documentation from the docs folder"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
cognee‑mcp - Run cognee’s memory engine as a Model Context Protocol server
Build memory for Agents and query from any client that speaks MCP – in your terminal or IDE.
✨ Features
Multiple transports – choose Streamable HTTP --transport http (recommended for web deployments), SSE --transport sse (real‑time streaming), or stdio (classic pipe, default)
Cloud Mode – connect to Cognee Cloud via
--serve-urlorCOGNEE_SERVICE_URLenv var (see Connection Modes)API Mode – connect to an already running Cognee FastAPI server (see Connection Modes)
Minimal Memory API – exposes only
remember,recall, andforgetfor agent memory workflowsIntegrated logging – all actions written to a rotating file (see get_log_file_location()) and mirrored to console in dev
Session-aware memory – store fast session cache entries or permanent graph memory through one
remembertoolFocused recall – query memory through one
recalltool with optional session and search controlsCode graph search – inspect indexed symbols, dependencies, architecture, and change impact with
code_searchSimple deletion – remove a dataset or all owned memory through one
forgettool
Please refer to our documentation here for further information.
Code graph search
Use code_search for deterministic queries against an indexed code dataset. Select an operation and pass its operation-specific filters in arguments:
{
"operation": "query_facts",
"arguments": {"kinds": ["module", "symbol"], "limit": 100},
"datasets": "sample-code-dataset"
}Supported operations are query_facts, explore, traverse, find_path, impact_analysis, insights, architecture and delta, plus the navigation operations capabilities, search, neighbors, subgraph, flows, hubs and ask. search and ask take a question in plain words as query.
Related MCP server: remembrallmcp
🚀 Quick Start
Clone cognee repo
git clone https://github.com/topoteretes/cognee.gitNavigate to cognee-mcp subdirectory
cd cognee/cognee-mcpInstall uv if you don't have one
pip install uvInstall all the dependencies you need for cognee mcp server with uv
uv sync --dev --all-extras --reinstallActivate the virtual environment in cognee mcp directory
source .venv/bin/activateSet up your OpenAI API key in .env for a quick setup with the default cognee configurations
LLM_API_KEY="YOUR_OPENAI_API_KEY"Run cognee mcp server with stdio (default)
python src/server.pyor stream responses over SSE
python src/server.py --transport sseor run with Streamable HTTP transport (recommended for web deployments)
python src/server.py --transport http --host 127.0.0.1 --port 8000 --path /mcp
You can do more advanced configurations by creating .env file using our template. To use different LLM providers / database configurations, and for more info check out our documentation.
No API key? If your MCP host grants the
samplingcapability,LLM_PROVIDER="mcp-sampling"delegates completions to the host's own model, so noLLM_API_KEYis needed (embeddings still need a provider). Host support varies — as of early 2026 Claude Code does not yet grant sampling (anthropics/claude-code#1785). See the "MCP sampling" section of the .env template.
🐳 Docker Usage
If you'd rather run cognee-mcp in a container, you have two options:
Build locally
Make sure you are in /cognee root directory and have a fresh
.envcontaining only yourLLM_API_KEY(and your chosen settings).Remove any old image and rebuild:
docker rmi cognee/cognee-mcp:main || true docker build --no-cache -f cognee-mcp/Dockerfile -t cognee/cognee-mcp:main .Run it:
# For HTTP transport (recommended for web deployments) docker run -e TRANSPORT_MODE=http --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:main # For SSE transport docker run -e TRANSPORT_MODE=sse --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:main # For stdio transport (default) docker run -e TRANSPORT_MODE=stdio --env-file ./.env --rm -it cognee/cognee-mcp:mainInstalling optional dependencies at runtime:
You can install optional dependencies when running the container by setting the
EXTRASenvironment variable:# Install a single optional dependency group at runtime docker run \ -e TRANSPORT_MODE=http \ -e EXTRAS=aws \ --env-file ./.env \ -p 8000:8000 \ --rm -it cognee/cognee-mcp:main # Install multiple optional dependency groups at runtime (comma-separated) docker run \ -e TRANSPORT_MODE=sse \ -e EXTRAS=aws,postgres,neo4j \ --env-file ./.env \ -p 8000:8000 \ --rm -it cognee/cognee-mcp:mainAvailable optional dependency groups:
aws- S3 storage supportpostgres/postgres-binary- PostgreSQL database supportneo4j- Neo4j graph database supportneptune- AWS Neptune supportturso- Turso vector/graph store supportscraping- Web scraping capabilitieslangchain- LangChain integrationllama-index- LlamaIndex integrationanthropic- Anthropic modelsgroq- Groq modelsmistral- Mistral modelsollama/huggingface- Local model supportdocs- Document processingtracing- OpenTelemetry tracingredis- Redis supportAnd more (see pyproject.toml for full list)
Pull from Docker Hub (no build required):
The image is published to Docker Hub on every push to
main. If you have not cloned the repo, create the.envfile the run commands expect first — it needs at least your LLM key:# Pull the prebuilt image docker pull cognee/cognee-mcp:main # Create a minimal .env in the current directory (no repo checkout required) echo 'LLM_API_KEY="YOUR_OPENAI_API_KEY"' > .env# With HTTP transport (recommended for web deployments) docker run -e TRANSPORT_MODE=http --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:main # With SSE transport docker run -e TRANSPORT_MODE=sse --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:main # With stdio transport (default) docker run -e TRANSPORT_MODE=stdio --env-file ./.env --rm -it cognee/cognee-mcp:mainWith runtime installation of optional dependencies:
# Install optional dependencies from Docker Hub image docker run \ -e TRANSPORT_MODE=http \ -e EXTRAS=aws,postgres \ --env-file ./.env \ -p 8000:8000 \ --rm -it cognee/cognee-mcp:main
Important: Docker vs Direct Usage
Docker uses environment variables, not command line arguments:
✅ Docker:
-e TRANSPORT_MODE=http❌ Docker:
--transport http(won't work)
Direct Python usage uses command line arguments:
✅ Direct:
python src/server.py --transport http❌ Direct:
-e TRANSPORT_MODE=http(won't work)
Docker API Mode
To connect the MCP Docker container to a Cognee API server running on your host machine:
Simple Usage (Automatic localhost handling):
# Start your Cognee API server on the host
python -m cognee.api.client
# Run MCP container in API mode - localhost is automatically converted!
docker run \
-e TRANSPORT_MODE=sse \
-e API_URL=http://localhost:8000 \
-e API_TOKEN=your_auth_token \
-p 8001:8000 \
--rm -it cognee/cognee-mcp:mainNote: The container will automatically convert localhost to host.docker.internal on Mac/Windows/Docker Desktop. You'll see a message in the logs showing the conversion.
Explicit host.docker.internal (Mac/Windows):
# Or explicitly use host.docker.internal
docker run \
-e TRANSPORT_MODE=sse \
-e API_URL=http://host.docker.internal:8000 \
-e API_TOKEN=your_auth_token \
-p 8001:8000 \
--rm -it cognee/cognee-mcp:mainOn Linux (use host network or container IP):
# Option 1: Use host network (simplest)
docker run \
--network host \
-e TRANSPORT_MODE=sse \
-e API_URL=http://localhost:8000 \
-e API_TOKEN=your_auth_token \
--rm -it cognee/cognee-mcp:main
# Option 2: Use host IP address
# First, get your host IP: ip addr show docker0
docker run \
-e TRANSPORT_MODE=sse \
-e API_URL=http://172.17.0.1:8000 \
-e API_TOKEN=your_auth_token \
-p 8001:8000 \
--rm -it cognee/cognee-mcp:mainEnvironment variables for API mode:
API_URL: URL of the running Cognee API serverAPI_TOKEN: Authentication token (optional, required if API has authentication enabled)
Note: When running in API mode:
Database migrations are automatically skipped (API server handles its own DB)
Some features are limited (see API Mode Limitations)
🔗 MCP Client Configuration
After starting your Cognee MCP server with Docker, you need to configure your MCP client to connect to it.
⚠️ Host/Origin protection (why you might get HTTP 421 or 403)
Both the http and sse transports validate the
HostandOriginheaders to block DNS-rebinding attacks, on every bind address including loopback — rebinding targets loopback services specifically, so127.0.0.1is not a mitigation.
A
Hostthe server does not recognise returns421 Misdirected RequestAn
Originit does not recognise returns403 ForbiddenWhen you bind a non-loopback address (
--host 0.0.0.0, which is what the Docker entrypoint does), onlylocalhost/127.0.0.1/[::1]are accepted by default, so reaching the server by LAN IP or a custom hostname returns 421 — the guard working, not a bug.Allow specific hosts (the
:*port glob is required):-e MCP_ALLOWED_HOSTS="192.168.1.50:*,myserver.local:*"Or turn the guard off entirely (only on a trusted network):
-e MCP_DISABLE_DNS_REBINDING_PROTECTION=trueImplementation note. FastMCP installs this guard on its streamable-http app only —
create_sse_app()accepts no such option, so the allow-lists were silently dropped for SSE. cognee-mcp mounts the same middleware on the SSE app itself, with the same allow-lists, so both transports behave identically.
SSE Transport Configuration (Legacy — prefer HTTP below; both are guarded)
Start the server with SSE transport:
docker run -e TRANSPORT_MODE=sse --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:mainConfigure your MCP client:
Claude CLI (Easiest)
claude mcp add cognee-sse -t sse http://localhost:8000/sseVerify the connection:
claude mcp listYou should see your server connected:
Checking MCP server health...
cognee-sse: http://localhost:8000/sse (SSE) - ✓ ConnectedManual Configuration
Claude (~/.claude.json)
{
"mcpServers": {
"cognee": {
"type": "sse",
"url": "http://localhost:8000/sse"
}
}
}Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"cognee-sse": {
"url": "http://localhost:8000/sse"
}
}
}HTTP Transport Configuration (Recommended)
Start the server with HTTP transport:
docker run -e TRANSPORT_MODE=http --env-file ./.env -p 8000:8000 --rm -it cognee/cognee-mcp:mainConfigure your MCP client:
Claude CLI (Easiest)
claude mcp add cognee-http -t http http://localhost:8000/mcpVerify the connection:
claude mcp listYou should see your server connected:
Checking MCP server health...
cognee-http: http://localhost:8000/mcp (HTTP) - ✓ ConnectedManual Configuration
Claude (~/.claude.json)
{
"mcpServers": {
"cognee": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}Cursor (~/.cursor/mcp.json)
{
"mcpServers": {
"cognee-http": {
"url": "http://localhost:8000/mcp"
}
}
}Dual Configuration Example
You can configure both transports simultaneously for testing:
{
"mcpServers": {
"cognee-sse": {
"type": "sse",
"url": "http://localhost:8000/sse"
},
"cognee-http": {
"type": "http",
"url": "http://localhost:8000/mcp"
}
}
}Note: Only enable the server you're actually running to avoid connection errors.
🌐 Connection Modes
The MCP server supports three connection modes:
Direct Mode (Default)
The MCP server directly imports and uses the cognee library with local databases (SQLite, LanceDB, Ladybug). This is the default mode with full feature support.
Cloud Mode
Connect to Cognee Cloud or a remote Cognee instance. The server calls cognee.serve() at startup, and all SDK operations transparently route to the cloud. No local databases needed.
Via CLI flags:
python src/server.py --serve-url https://your-instance.cognee.ai --serve-api-key ck_...Via environment variables (zero-config):
export COGNEE_SERVICE_URL="https://your-instance.cognee.ai"
export COGNEE_API_KEY="ck_..."
python src/server.pyCloud Mode with Docker:
docker run \
-e TRANSPORT_MODE=sse \
-e COGNEE_SERVICE_URL=https://your-instance.cognee.ai \
-e COGNEE_API_KEY=ck_... \
-p 8000:8000 \
--rm -it cognee/cognee-mcp:mainCloud Mode arguments / environment variables:
--serve-url/COGNEE_SERVICE_URL: Cognee Cloud or remote instance URL--serve-api-key/COGNEE_API_KEY: API key for the instance
Database migrations are automatically skipped in Cloud mode.
API Mode
The MCP server connects to an already running Cognee FastAPI server via HTTP requests. This is useful when:
You have a centralized Cognee API server running
You want to separate the MCP server from the knowledge graph backend
You need multiple MCP servers to share the same knowledge graph
Starting the MCP server in API mode:
# Start your Cognee FastAPI server first (default port 8000)
cd /path/to/cognee
python -m cognee.api.client
# Then start the MCP server in API mode
cd cognee-mcp
python src/server.py --api-url http://localhost:8000 --api-token YOUR_AUTH_TOKENAPI Mode with different transports:
# With SSE transport
python src/server.py --transport sse --api-url http://localhost:8000 --api-token YOUR_TOKEN
# With HTTP transport
python src/server.py --transport http --api-url http://localhost:8000 --api-token YOUR_TOKENAPI Mode with Docker:
# On Mac/Windows (use host.docker.internal to access host)
docker run \
-e TRANSPORT_MODE=sse \
-e API_URL=http://host.docker.internal:8000 \
-e API_TOKEN=YOUR_TOKEN \
-p 8001:8000 \
--rm -it cognee/cognee-mcp:main
# On Linux (use host network)
docker run \
--network host \
-e TRANSPORT_MODE=sse \
-e API_URL=http://localhost:8000 \
-e API_TOKEN=YOUR_TOKEN \
--rm -it cognee/cognee-mcp:mainCommand-line arguments for API mode:
--api-url: Base URL of the running Cognee FastAPI server (e.g.,http://localhost:8000)--api-token: Authentication token for the API (optional, required if API has authentication enabled)
Docker environment variables for API mode:
API_URL: Base URL of the running Cognee FastAPI serverAPI_TOKEN: Authentication token (optional, required if API has authentication enabled)
API Mode behavior:
The MCP server intentionally exposes only the memory API: remember, recall, and forget (plus the cognify_status progress check).
In API mode these tools call the Cognee API server endpoints directly. Operational helpers such as
cognify, search, list_data, delete, prune, improve, and document retrieval helpers are
kept internal and are not exposed as MCP tools.
💻 Basic Usage
The MCP server exposes its functionality through tools. Call them from any MCP client (Cursor, Claude Desktop, Cline, Roo and more).
Available Tools
The MCP server exposes four tools (three memory tools pinned in tools/list, plus cognify_status):
remember: Store data in memory. Pass
datafor text, orfilename+content_base64to ingest an uploaded file (up to 10 MB). Withsession_id: fast session cache (text only). Withoutsession_id: permanent graph memoryrecall: Search memory with auto-routing. Searches session cache first when
session_idis provided, then falls through to the permanent graphforget: Delete memory by dataset name or id, a single data item by
data_id, or delete all owned memory witheverything=Truecognify_status: Check the progress of background ingestion started by
remember(background=True). Unadvertised by default; discoverable viasearch_toolsand callable by name
Recall result summaries
recall (the MCP memory-search tool) starts every successful response with a
summary, followed by the same result body as before:
3 memories found (2 from sessions, 1 from project docs)
[session] ...The count is the number of returned memory entries, not top_k, underlying
chunks used to synthesize an answer, or system status messages. Source and dataset
hints use metadata already present in the returned entries; no recency lookup or
extra LLM call is made.
Empty results distinguish an empty memory graph, indexing in progress, indexing
failure, and no match. When available, progress is displayed as, for example,
still indexing — 12/40 items processed, retry shortly. These are data items,
not an inferred chunk count. A graph with no recorded indexing run is reported
as not yet indexed. If the status check fails or exceeds its two-second budget,
the summary explicitly says memory status is unavailable. Successful hits do
not trigger status checks.
The MCP content remains a single TextContent block. Text consumers can separate
line one from the unchanged body with text.partition("\n"). Machine consumers
can read content[0]._meta["cognee/memory"], containing count and state.
state is one of four values, one per action a caller can take:
state | meaning |
| memory contributed; |
| ingestion is still running — retry shortly |
| ingestion failed — check |
| nothing to return |
indexing additionally carries completed/total when the pipeline reports
them. Tool errors retain their existing Error: response.
Tool surface (COGNEE_MCP_TOOL_MODE)
Advertising every tool up front costs agent context and hurts tool-selection accuracy, so by default the server pins a small set in tools/list and makes the rest discoverable through FastMCP's built-in search_tools. Unadvertised tools stay callable by name.
COGNEE_MCP_TOOL_MODE=default # pinned: remember, recall, forget
COGNEE_MCP_TOOL_MODE=minimal # pinned: remember, recall, forget
COGNEE_MCP_TOOL_MODE=all # no search transform; advertise every toolAlso settable per-process with --tool-mode. In default/minimal an agent calls search_tools(query=...) to find a tool and either calls it by name or goes through the call_tool proxy. Tiers are declared per tool via @registry.tool(tags={...}) in src/server.py, so the pinned set is derived from the decorators rather than a separate list.
search_tools returns up to TOOL_SEARCH_MAX_RESULTS (10) tools, sized for a catalog that will grow. The window only costs context on turns that actually call search; tools/list stays constant either way. See tests/test_tool_search_benchmark.py for the recall sweep behind the number.
Writing a tool so search can find it
Search works well on natural-language queries. Every phrasing below returns its target ranked first (covered by tests/test_tool_search.py):
query | returns |
"is my background ingestion finished?" |
|
"check the progress of a pipeline job" |
|
The one thing to know when adding a tool: matching is purely lexical. FastMCP's BM25 tokenizer does no stemming and drops tools that score zero, so a query shares no credit with a word it doesn't literally contain. Multi-word queries paper over this (they usually contain some matching token), which is why the table above passes, but terse queries won't.
So: write descriptions in the words an agent would use, including both singular and plural. Recall is bounded by vocabulary, not by TOOL_SEARCH_MAX_RESULTS. If lexical matching ever stops being enough, BaseSearchTransform leaves _search() abstract — a semantic ranker over cognee's own embeddings can be dropped in without touching the rest of the plumbing.
Agent Scoping (per-client default datasets)
By default, each MCP client gets its own auto-named dataset (e.g. Cursor → cursor_vscode_memory, Claude Code → claude_code_memory) so different agents don't share memory unintentionally. The dataset is created on demand the first time a client writes to it.
remember and cognify_status route to the agent-scoped dataset when dataset_name is omitted (the internal cognify/improve helpers, which are not exposed as tools, do the same). Pass dataset_name explicitly to override (e.g. dataset_name="main_dataset" still works).
To disable agent scoping and have all clients share main_dataset as the default, set in .env:
COGNEE_MCP_AGENT_SCOPED=falseWhen disabled, no per-client datasets are autocreated.
Per-dataset isolation (ENABLE_BACKEND_ACCESS_CONTROL)
Agent scoping decides which dataset name a tool defaults to. Whether two datasets are actually isolated at the storage layer is governed by cognee's ENABLE_BACKEND_ACCESS_CONTROL flag:
true(default) — each(user, dataset)pair gets its own per-dataset Kuzu + LanceDB under.cognee_system/databases/<dataset_uuid>/, and search is strictly per-dataset.false— all datasets share one Kuzu graph DB and one LanceDB. The dataset filter is honored for top-level data points, butGRAPH_COMPLETIONtraversal can pull connected nodes from any dataset. Use for single-user local dev; also disables the API auth requirement unlessREQUIRE_AUTHENTICATION=trueis set explicitly.
Switching modes wipes nothing automatically — but data does not migrate. Data ingested in one mode lives at a different on-disk path than the other and won't be visible after the flip. Clean-slate when changing the flag:
# Stop server, then:
DATA_ROOT="/absolute/path/to/data-root"
rm -rf "$DATA_ROOT/.cognee_system" "$DATA_ROOT/.data_storage"
# Edit .env to flip ENABLE_BACKEND_ACCESS_CONTROL, restart, re-cognify.(Set DATA_ROOT to whatever you used for DATA_ROOT_DIRECTORY / SYSTEM_ROOT_DIRECTORY, or your cognee install dir if you didn't set those.)
Examples:
# Store permanent memory
remember(data="Cognee MCP now exposes a focused memory API.", dataset_name="main_dataset")
# Store permanent memory without the automatic improve stage (add + cognify still run)
remember(data="A new fact", dataset_name="main_dataset", self_improvement=False)
# The opt-out also applies to file uploads and background=True ingestion
remember(data="A new fact", self_improvement=False, background=True)
# Store session memory without a background graph bridge in direct mode
remember(data="Temporary working note", session_id="agent-session-1", self_improvement=False)
# Recall from memory
recall(query="What changed in the MCP server?", session_id="agent-session-1")
# Delete one dataset
forget(dataset="main_dataset")self_improvement defaults to True; only an explicit False is forwarded, so
True leaves the core default in charge. In permanent mode, False disables
automatic improvement without skipping ingestion or graph building.
In direct session mode, it disables the automatic session-to-graph bridge while
still storing the session entry. In API session mode, MCP uses typed QA entries,
which stay in the session cache for all flag values; the flag does not enable a
graph bridge there. It does not control separately requested skill improvement.
Select an uploaded ontology for a write
Pass ontology_key to remember to ground permanent-memory extraction with one
or more previously uploaded OWL ontologies:
remember(data="Alice works at Acme.", dataset_name="workspace_a", ontology_key="workspace_a_v2")
remember(
data="Acme develops software.",
ontology_key=["organizations", "software"],
background=True,
)In API mode, upload the ontologies first through POST /api/v1/ontologies using
the same authenticated user as the MCP server. Keys are sent as repeated
ontology_key form fields. In local mode, keys resolve through OntologyService
in the default user's local ontology store; remote uploads are not copied locally.
Unknown or inaccessible keys fail the write. Background failures are reported by
cognify_status.
Omitting ontology_key (or passing an empty list) preserves the configured
server ontology, including ONTOLOGY_FILE_PATH. Ontology selection is only for
permanent writes: combining a nonempty key with session_id returns an error
because session-cache writes do not perform extraction.
Development and Debugging
Debugging
Use the fastmcp CLI, not mcp. Since the FastMCP 3 migration this server is a
standalone fastmcp.FastMCP instance, which the mcp CLI does not recognise —
mcp dev src/server.py fails with "Ignoring object 'src/server.py:mcp' as it's not a
valid server object".
Inspect the server without launching anything (fast sanity check — name, version, tool count):
uv run fastmcp inspect src/server.py:mcpRun it against the MCP Inspector UI:
uv run fastmcp dev src/server.py:mcpOpen the inspector with a longer timeout — cognee's first call can be slow while the databases initialise:
http://localhost:5173?timeout=120000To apply new changes while developing cognee:
Update dependencies in the cognee folder if needed
uv sync --group dev --reinstalluv run fastmcp dev src/server.py:mcp
The
:mcpsuffix names the server object in the file. Without it the CLI has to guess, and the guess is not reliable across FastMCP versions.
Development
In order to use local cognee:
Uncomment the following line in the cognee-mcp
pyproject.tomlfile and set the cognee root path.#"cognee[postgres-binary,docs,neo4j] @ file:/path/to/your/cognee"Replace
/path/to/your/cogneewith the absolute path to your cognee checkout, and comment out the released"cognee[...]>=1.5.0,<2.0.0"line directly below it — otherwise both requirements apply and uv resolves the published package instead.Install dependencies with uv in the mcp folder
uv sync --reinstallRe-run this after every change to the local cognee checkout.
Note: editing that line modifies the tracked
pyproject.tomland rewritesuv.lockwith a machine-local absolute path. Revert both before committing —git checkout -- pyproject.toml uv.lock— or the path leaks into the repo.
Code of Conduct
We are committed to making open source an enjoyable and respectful experience for our community. See CODE_OF_CONDUCT for more information.
💫 Contributors
Star History
Available Tools
6 toolscall_toolA
Call a tool by name with the given arguments.
Use this to execute tools discovered via search_tools.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | The name of the tool to call | |
| arguments | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, and the description does not mention potential side effects, required permissions, or the fact that this tool may execute arbitrary actions. This lack of transparency is risky for an agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two concise sentences with no redundant information. The description is efficient and to the point.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description explains the basic purpose and links to search_tools, but it lacks details on error handling, return values, or behavioral constraints. Given the tool's generic nature, this is acceptable but not comprehensive.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only the 'name' parameter has a description in the schema; 'arguments' is not described. The description adds minimal value by implying arguments are passed, but does not clarify structure or constraints, leaving significant ambiguity.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (call a tool) and the target (by name with arguments), and it is distinct from the sibling tools which perform specific operations like remember or recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this for executing tools discovered via search_tools, giving a clear use case. It does not elaborate on when not to use it, but the guidance is sufficient for typical scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
code_searchA
Search Cognee's indexed code graph with a structured operation.
This tool is for source-code structure, symbols, call/dependency paths,
impact, architecture, and index changes. It does not search conversational
memory. Choose an operation and pass its operation-specific fields in
arguments. For example, use operation="query_facts" with
arguments={"kinds": ["module", "symbol"], "limit": 100}, or
operation="impact_analysis" with arguments={"seeds": ["UserService"]}.
For a question in plain words ("how does checkout work?"), use
operation="ask" with the question as query: it returns matching
symbols, entry-point flows, their neighbourhood and file:line citations.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Optional seed text, used by explore when no explicit seed is supplied in arguments, and the text or question for search and ask. | |
| top_k | No | Maximum number of results to return (default: 15). | |
| datasets | No | Comma-separated Cognee dataset names containing indexed code. | |
| arguments | No | Operation-specific structured arguments. Do not include an "operation" key here; select it with the operation parameter. | |
| operation | Yes | Code-graph operation: query_facts, explore, traverse, find_path, impact_analysis, insights, architecture, delta, capabilities, search, neighbors, subgraph, flows, hubs, or ask. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses some return context ('returns matching symbols, entry-point flows, their neighbourhood and file:line citations') and the seed-vs-query behavior of explore, but says nothing about read-only semantics, permission requirements, cost/latency of the heavier operations, or how the fifteen operations differ in behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then scope exclusion, then operation guidance with runnable examples. Every sentence earns its place and there is no filler; only mild redundancy in re-listing the operation enum, which the schema already carries.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be described, and the description is otherwise well scoped. But for a tool with 15 operations funnelling through a freeform `arguments` object, exemplifying only 3 operations leaves the agent without the operation-specific argument shapes needed to call most of the enum correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description goes beyond it by showing concrete operation-specific contents for the opaque `arguments` object (kinds/limit for query_facts, seeds for impact_analysis), which the schema does not enumerate. It also clarifies that `query` doubles as seed text or plain-language question depending on operation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Search Cognee's indexed code graph') and then enumerates exactly what is in scope: source-code structure, symbols, call/dependency paths, impact, architecture, index changes. It also explicitly excludes conversational memory, so an agent can distinguish it from the memory-oriented siblings without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives concrete when-to-use guidance by routing three named operations with example payloads: query_facts for fact queries, impact_analysis for seeds, ask for plain-language questions. However, only 3 of the 15 operations are explained, so the agent gets no guidance on when to pick traverse, find_path, hubs, flows, or the other ten, and there is no statement of exclusion beyond 'not conversational memory'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
forgetA
Delete data from memory.
Can target a single data item, a specific dataset (by name or id), or everything the user owns. Removes data from the relational DB, graph DB, and vector DB.
| Name | Required | Description | Default |
|---|---|---|---|
| data_id | No | UUID of a single data item to delete. Must be paired with `dataset` or `dataset_id` so the owning dataset is unambiguous. | |
| dataset | No | Dataset name to delete entirely. | |
| dataset_id | No | UUID of the dataset to delete entirely, or to scope `data_id`. | |
| everything | No | If true, delete ALL data across all datasets. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden. It discloses that records are removed from three types of databases, which is useful. However, it does not mention irreversibility, permission requirements, or potential cascading effects. This is adequate but not comprehensive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is succinct, leading with the primary action, then the targeting options, and finally the storage impact. No unnecessary words; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a delete operation, it covers the key aspects: what can be deleted, how scope is specified, and which storage layers are affected. It does not explain error scenarios or side effects beyond deletion, but that is not essential given the presence of an output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents each parameter at 100% coverage. The description adds overarching semantics: it clarifies that data_id must be paired with a dataset identifier, and distinguishes three targeting modes. This guidance helps the agent correctly combine parameters beyond what individual descriptions provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with 'Delete data from memory', a precise verb+resource pair, and enumerates the three deletion scopes (single item, dataset by name/id, everything). It also specifies that deletion spans relational, graph, and vector databases, clearly distinguishing it from siblings like remember and recall.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is for deletion but does not explicitly name alternatives or conditions. It could have said 'Use this instead of remember/recall for removing data' to guide the agent, but the intent is clear from context and sibling names.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recallA
Search memory with auto-routing and session awareness.
When session_id is provided without datasets or search_type, searches session cache first by keyword matching. Falls through to the permanent knowledge graph if no session results match.
Auto-routing picks the best search strategy when search_type is not specified.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Natural language query to search for. | |
| scope | No | Comma-separated memory sources to include: 'graph', 'session', 'session_first', 'trace', 'session_context', 'tools', 'code', 'all', 'auto'. Defaults to 'auto' (session first when session_id is set, else graph). 'tools' and 'code' are explicit opt-in only. 'code' runs a deterministic code-graph query and tags results source='code'. | |
| top_k | No | Maximum results to return (default: 15). | |
| datasets | No | Comma-separated dataset names to search within. | |
| code_query | No | 'code' scope only: structured operation and arguments for the deterministic code-graph query, e.g. {"operation": "query_facts", "property": "language", "limit": 500}. Supported operations: query_facts, explore, traverse, find_path, impact_analysis, insights, architecture, delta, capabilities, search, neighbors, subgraph, flows, hubs, ask. When omitted, 'code' scope runs an 'explore' seeded with the query text. Most operations take exact node names/IDs or structured filters; search and ask take natural-language text. | |
| session_id | No | Session ID for session-first search. | |
| search_type | No | Override auto-routing with one SearchType name. Completion types (answer written by an LLM): HYBRID_COMPLETION (the default when routing is off), GRAPH_COMPLETION, GRAPH_COMPLETION_COT, GRAPH_COMPLETION_CONTEXT_EXTENSION, GRAPH_COMPLETION_DECOMPOSITION, GRAPH_SUMMARY_COMPLETION, RAG_COMPLETION, TEMPORAL, AGENTIC_COMPLETION. Retrieval-only types (no LLM): CHUNKS, CHUNKS_LEXICAL, SUMMARIES, SKILLS, CODE. Other: CYPHER, NATURAL_LANGUAGE, CODING_RULES, GRAPH_REPORT, FEELING_LUCKY. An unknown name is rejected with a validation error. | |
| system_prompt | No | Override the synthesis prompt for completion searches. When omitted, falls back to COGNEE_MCP_RECALL_SYSTEM_PROMPT / _FILE if configured on the server. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does disclose the two-phase session-cache-then-graph search and keyword matching. However it omits important traits: some search_type values invoke an LLM (cost/latency), the operation is read-only, and no rate/limit behavior is mentioned. Useful, but incomplete for a tool this complex.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the first line, then the two behavioral rules follow in short paragraphs. It is appropriately sized for an 8-parameter router, with only minor redundancy between the opening sentence and the auto-routing paragraph.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and 100% schema coverage covers parameter detail. Given the tool's complexity the description supplies the key routing semantics; only the cost implications of LLM-backed search types are left unstated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so a baseline of 3 applies. The description goes further by explaining how session_id interacts with datasets/search_type to change routing, which the per-parameter schema text does not fully spell out, and it explains what auto-routing does when search_type is omitted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource: 'Search memory', which cleanly separates it from the write/delete siblings remember and forget. It does not explicitly name alternatives like code_search, but 'memory' + 'auto-routing' is concrete enough that an agent knows what it does without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It states the exact condition that selects session-first behavior (session_id set, no datasets or search_type) and the fall-through to the permanent graph when session results miss. That is real when-to-use guidance, though it never routes the agent toward or away from siblings like code_search or search_tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rememberA
Store data in memory.
Two modes depending on whether session_id is provided:
Without session_id (permanent memory): Runs the full add + cognify pipeline to ingest data and build the knowledge graph, then the self-improvement loop (improve) unless self_improvement=False.
With session_id (session memory): Stores the data in the session cache. Direct mode may also bridge it to the graph in the background; API mode uses typed cache entries and does not bridge to the graph. Omit session_id when the content should be stored as permanent graph memory.
Pass either data (text) or filename + content_base64 (a file
upload, up to 10 MB), not both. File uploads are permanent-memory
only and don't support session_id.
| Name | Required | Description | Default |
|---|---|---|---|
| data | No | The text content to store. Mutually exclusive with filename/content_base64. | |
| filename | No | Original filename for a file upload. Used to derive the stored document's name. Requires content_base64. | |
| node_set | No | Node-set names to file the data under, the same names recall filters on with node_name. Permanent memory tags the ingested data. With session_id the first write that carries one pins it on the session; later writes must repeat it or omit it, and a different set is refused, so one session never spans two node sets. improve() keeps the pinned set on everything it bridges from the session into the graph. Used for per-project memory. | |
| background | No | Queue permanent ingestion as a background task and return immediately instead of waiting for the pipeline. Use when the caller has a request deadline shorter than ingestion takes. Ignored with session_id, which is already fast. Errors surface via cognify_status, not the return value. | |
| session_id | No | Session ID. Stores in cache; direct mode may also bridge to the graph unless self_improvement is False. | |
| dataset_name | No | Target dataset name. Defaults to the current MCP client's agent-scoped dataset (e.g. "cursor_vscode_memory"), or "main_dataset" if no client identity is detected. | |
| ontology_key | No | One or more uploaded ontology keys for extraction (permanent mode only). API mode uses ontologies uploaded by the authenticated API user. Local mode uses the default user's ontology store. Omit to keep the configured server ontology. | |
| custom_prompt | No | Custom prompt for entity extraction (permanent mode only). | |
| content_base64 | No | Base64-encoded file content to ingest. Requires filename. | |
| self_improvement | No | False skips automatic improvement after permanent ingestion; add and cognify still run. In direct session mode, False disables the background session-to-graph bridge. API session entries are cache-only regardless of this flag. Default True. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so: it discloses the add+cognify pipeline, the self-improvement loop and its opt-out flag, the session-to-graph background bridge, background queuing semantics (errors surface via cognify_status, not the return value), and a 10 MB upload limit. That is unusually complete side-effect and failure-mode coverage for an unannotated mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded with the two modes stated before the details, and every sentence carries information. It runs long for a tool description, though the density of distinct behaviors (modes, limits, pipeline flags) justifies most of the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Ten parameters are all documented, an output schema exists so return values need no explanation, and the description still supplies the mode logic, ingestion pipeline, background behavior, and size limit that an agent needs to call this correctly. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds functional meaning beyond the schema: session_id selects the storage mode, data vs filename/content_base64 are exclusive, and file uploads are incompatible with session_id. These mode-level semantics are not fully recoverable from the per-parameter text alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Store data in memory') and immediately partitions behavior into two named modes keyed on session_id, which makes it distinguishable from the retrieval-oriented sibling 'recall'. An agent knows both what it does and the shape of its two behavioral branches.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the caller when to omit session_id ('when the content should be stored as permanent graph memory'), what each mode does, and the mutual-exclusivity rule for data vs filename/content_base64. It also constrains file uploads to permanent memory only, so misuse is largely prevented.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_toolsA
Search for tools using natural language.
Returns matching tool definitions ranked by relevance, in the same format as list_tools.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | Natural language query to search for tools |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It states that it returns matching tool definitions ranked by relevance, which is a behavioral trait. It also mentions the format is same as list_tools, which is useful. However, it doesn't disclose any side effects, rate limits, or other behavioral details. Given the tool is a search operation, this is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, two sentences, and front-loaded with the purpose. Every sentence adds value: the first states what it does, the second clarifies the return format. No waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple with one parameter and an output schema. The description explains the return format (same as list_tools) and ranking by relevance. Given the simplicity and the presence of an output schema, the description is complete enough. It could mention that it's a read-only operation, but that's not critical.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents the single parameter 'query' as a natural language query. The description adds no additional meaning beyond that. Baseline 3 is appropriate since the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: searching for tools using natural language. It specifies the action (search) and the resource (tools), and distinguishes it from siblings like list_tools by mentioning the return format. However, it doesn't explicitly differentiate from other sibling tools like call_tool, but the purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: when you need to find tools by natural language query. It mentions the return format is same as list_tools, which gives some context. However, it doesn't explicitly state when to use this vs alternatives, nor does it provide exclusions or alternative tool references. The guidance is minimal but not misleading.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v1.6.5- Changed
code_search3 fields changed- changed
Input schema / properties / operation / descriptionPrevious value: -"Code-graph operation: query_facts, explore, traverse, find_path,\nimpact_analysis, insights, architecture, or delta."New value: +"Code-graph operation: query_facts, explore, traverse, find_path,\nimpact_analysis, insights, architecture, delta, capabilities, search,\nneighbors, subgraph, flows, hubs, or ask." - changed
Input schema / properties / operation / enumPrevious value: -[ - "query_facts", - "explore", - "traverse", - "find_path", - "impact_analysis", - "insights", - "architecture", - "delta" -]New value: +[ + "query_facts", + "explore", + "traverse", + "find_path", + "impact_analysis", + "insights", + "architecture", + "delta", + "capabilities", + "search", + "neighbors", + "subgraph", + "flows", + "hubs", + "ask" +] - changed
Input schema / properties / query / descriptionPrevious value: -"Optional seed text, primarily used by explore when no explicit seed is\nsupplied in arguments."New value: +"Optional seed text, used by explore when no explicit seed is supplied\nin arguments, and the text or question for search and ask."
- Changed
recall2 fields changed- changed
Input schema / properties / code_query / descriptionPrevious value: -"'code' scope only: structured operation and arguments for the\ndeterministic code-graph query, e.g. {\"operation\": \"query_facts\",\n\"property\": \"language\", \"limit\": 500}. Supported operations:\nquery_facts, explore, traverse, find_path, impact_analysis, insights,\narchitecture, delta. When omitted, 'code' scope runs an 'explore'\nseeded with the query text. Requires exact node names/IDs or\nstructured filters, not natural-language questions."New value: +"'code' scope only: structured operation and arguments for the\ndeterministic code-graph query, e.g. {\"operation\": \"query_facts\",\n\"property\": \"language\", \"limit\": 500}. Supported operations:\nquery_facts, explore, traverse, find_path, impact_analysis, insights,\narchitecture, delta, capabilities, search, neighbors, subgraph, flows,\nhubs, ask. When omitted, 'code' scope runs an 'explore' seeded with the\nquery text. Most operations take exact node names/IDs or structured\nfilters; search and ask take natural-language text." - changed
Input schema / properties / search_type / descriptionPrevious value: -"Override auto-routing with one SearchType name. Completion types\n(answer written by an LLM): HYBRID_COMPLETION (the default when\nrouting is off), GRAPH_COMPLETION, GRAPH_COMPLETION_COT,\nGRAPH_COMPLETION_CONTEXT_EXTENSION, GRAPH_COMPLETION_DECOMPOSITION,\nGRAPH_SUMMARY_COMPLETION, RAG_COMPLETION, TRIPLET_COMPLETION,\nTEMPORAL, AGENTIC_COMPLETION. Retrieval-only types (no LLM):\nCHUNKS, CHUNKS_LEXICAL, SUMMARIES, SKILLS, CODE. Other: CYPHER,\nNATURAL_LANGUAGE, CODING_RULES, GRAPH_REPORT, FEELING_LUCKY.\nAn unknown name is rejected with a validation error."New value: +"Override auto-routing with one SearchType name. Completion types\n(answer written by an LLM): HYBRID_COMPLETION (the default when\nrouting is off), GRAPH_COMPLETION, GRAPH_COMPLETION_COT,\nGRAPH_COMPLETION_CONTEXT_EXTENSION, GRAPH_COMPLETION_DECOMPOSITION,\nGRAPH_SUMMARY_COMPLETION, RAG_COMPLETION, TEMPORAL,\nAGENTIC_COMPLETION. Retrieval-only types (no LLM):\nCHUNKS, CHUNKS_LEXICAL, SUMMARIES, SKILLS, CODE. Other: CYPHER,\nNATURAL_LANGUAGE, CODING_RULES, GRAPH_REPORT, FEELING_LUCKY.\nAn unknown name is rejected with a validation error."
- Changed
remember1 field changed- added
Input schema / properties / node_setAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Node-set names to file the data under, the same names recall filters\non with node_name. Permanent memory tags the ingested data. With\nsession_id the first write that carries one pins it on the session;\nlater writes must repeat it or omit it, and a different set is\nrefused, so one session never spans two node sets. improve() keeps\nthe pinned set on everything it bridges from the session into the\ngraph. Used for per-project memory." +}
2 tool updates
v1.6.4- Added
code_search - Changed
recall2 fields changed- added
Input schema / properties / code_queryAdded value: +{ + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "description": "'code' scope only: structured operation and arguments for the\ndeterministic code-graph query, e.g. {\"operation\": \"query_facts\",\n\"property\": \"language\", \"limit\": 500}. Supported operations:\nquery_facts, explore, traverse, find_path, impact_analysis, insights,\narchitecture, delta. When omitted, 'code' scope runs an 'explore'\nseeded with the query text. Requires exact node names/IDs or\nstructured filters, not natural-language questions." +} - added
Input schema / properties / scopeAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "Comma-separated memory sources to include: 'graph', 'session',\n'session_first', 'trace', 'session_context', 'tools', 'code', 'all',\n'auto'. Defaults to 'auto' (session first when session_id is set,\nelse graph). 'tools' and 'code' are explicit opt-in only. 'code' runs\na deterministic code-graph query and tags results source='code'." +}
1 tool update
v1.6.1- Changed
remember2 fields changed- changed
Input schema / properties / self_improvement / descriptionPrevious value: -"Run the improve loop (triplet enrichment and, with sessions, the\nsession bridge) after cognify. Permanent mode only; default True.\nPass False for a plain add + cognify ingestion."New value: +"False skips automatic improvement after permanent ingestion; add and\ncognify still run. In direct session mode, False disables the background\nsession-to-graph bridge. API session entries are cache-only regardless\nof this flag. Default True." - changed
Input schema / properties / session_id / descriptionPrevious value: -"Session ID. When set, stores in session cache only."New value: +"Session ID. Stores in cache; direct mode may also bridge to the graph\nunless self_improvement is False."
3 tool updates
v1.6.0- Changed
forget6 fields changed- added
Input schema / properties / data_id / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / data_id / typeRemoved value: -"string" - added
Input schema / properties / dataset / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / dataset / typeRemoved value: -"string" - added
Input schema / properties / dataset_id / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / dataset_id / typeRemoved value: -"string"
- Changed
recall10 fields changed- added
Input schema / properties / datasets / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / datasets / typeRemoved value: -"string" - added
Input schema / properties / search_type / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - changed
Input schema / properties / search_type / descriptionPrevious value: -"Override auto-routing. Options: GRAPH_COMPLETION,\nGRAPH_COMPLETION_COT, RAG_COMPLETION, CHUNKS, SUMMARIES,\nTEMPORAL, FEELING_LUCKY, etc."New value: +"Override auto-routing with one SearchType name. Completion types\n(answer written by an LLM): HYBRID_COMPLETION (the default when\nrouting is off), GRAPH_COMPLETION, GRAPH_COMPLETION_COT,\nGRAPH_COMPLETION_CONTEXT_EXTENSION, GRAPH_COMPLETION_DECOMPOSITION,\nGRAPH_SUMMARY_COMPLETION, RAG_COMPLETION, TRIPLET_COMPLETION,\nTEMPORAL, AGENTIC_COMPLETION. Retrieval-only types (no LLM):\nCHUNKS, CHUNKS_LEXICAL, SUMMARIES, SKILLS, CODE. Other: CYPHER,\nNATURAL_LANGUAGE, CODING_RULES, GRAPH_REPORT, FEELING_LUCKY.\nAn unknown name is rejected with a validation error." - removed
Input schema / properties / search_type / typeRemoved value: -"string" - added
Input schema / properties / session_id / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / session_id / typeRemoved value: -"string" - added
Input schema / properties / system_prompt / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / system_prompt / typeRemoved value: -"string" - changed
Input schema / properties / top_k / descriptionPrevious value: -"Maximum results to return (default: 10)."New value: +"Maximum results to return (default: 15)."
- Changed
remember14 fields changed- added
Input schema / properties / content_base64 / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / content_base64 / typeRemoved value: -"string" - added
Input schema / properties / custom_prompt / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / custom_prompt / typeRemoved value: -"string" - added
Input schema / properties / data / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / data / typeRemoved value: -"string" - added
Input schema / properties / dataset_name / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / dataset_name / typeRemoved value: -"string" - added
Input schema / properties / filename / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / filename / typeRemoved value: -"string" - added
Input schema / properties / ontology_keyAdded value: +{ + "anyOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "description": "One or more uploaded ontology keys for extraction (permanent mode only).\nAPI mode uses ontologies uploaded by the authenticated API user. Local\nmode uses the default user's ontology store. Omit to keep the configured\nserver ontology." +} - added
Input schema / properties / self_improvementAdded value: +{ + "default": true, + "description": "Run the improve loop (triplet enrichment and, with sessions, the\nsession bridge) after cognify. Permanent mode only; default True.\nPass False for a plain add + cognify ingestion.", + "type": "boolean" +} - added
Input schema / properties / session_id / anyOfAdded value: +[ + { + "type": "string" + }, + { + "type": "null" + } +] - removed
Input schema / properties / session_id / typeRemoved value: -"string"
5 tool updates
v1.5.1- Changed
forget2 fields changed- added
Input schema / properties / data_idAdded value: +{ + "default": null, + "description": "UUID of a single data item to delete. Must be paired with `dataset`\nor `dataset_id` so the owning dataset is unambiguous.", + "type": "string" +} - added
Input schema / properties / dataset_idAdded value: +{ + "default": null, + "description": "UUID of the dataset to delete entirely, or to scope `data_id`.", + "type": "string" +}
- Removed
open_cognee_workspace - Changed
remember1 field changed- added
Input schema / properties / backgroundAdded value: +{ + "default": false, + "description": "Queue permanent ingestion as a background task and return immediately\ninstead of waiting for the pipeline. Use when the caller has a request\ndeadline shorter than ingestion takes. Ignored with session_id, which\nis already fast. Errors surface via cognify_status, not the return\nvalue.", + "type": "boolean" +}
- Removed
upload_file_ui - Removed
visualize_graph_ui
13 tool updates
v1.5.0- Added
call_tool - Removed
cognify_file - Removed
create_dataset_json - Changed
forget7 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / dataset / descriptionAdded value: +"Dataset name to delete entirely." - removed
Input schema / properties / dataset / titleRemoved value: -"Dataset" - added
Input schema / properties / everything / descriptionAdded value: +"If true, delete ALL data across all datasets." - removed
Input schema / properties / everything / titleRemoved value: -"Everything" - removed
Input schema / titleRemoved value: -"forgetArguments" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "result": { + "items": {}, + "type": "array" + } + }, + "required": [ + "result" + ], + "type": "object", + "x-fastmcp-wrap-result": true +}
- Removed
get_client_info_json - Removed
list_dataset_data_json - Removed
list_datasets_json - Changed
open_cognee_workspace2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / titleRemoved value: -"open_cognee_workspaceArguments"
- Changed
recall15 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / datasets / descriptionAdded value: +"Comma-separated dataset names to search within." - removed
Input schema / properties / datasets / titleRemoved value: -"Datasets" - added
Input schema / properties / query / descriptionAdded value: +"Natural language query to search for." - removed
Input schema / properties / query / titleRemoved value: -"Query" - added
Input schema / properties / search_type / descriptionAdded value: +"Override auto-routing. Options: GRAPH_COMPLETION,\nGRAPH_COMPLETION_COT, RAG_COMPLETION, CHUNKS, SUMMARIES,\nTEMPORAL, FEELING_LUCKY, etc." - removed
Input schema / properties / search_type / titleRemoved value: -"Search Type" - added
Input schema / properties / session_id / descriptionAdded value: +"Session ID for session-first search." - removed
Input schema / properties / session_id / titleRemoved value: -"Session Id" - added
Input schema / properties / system_prompt / descriptionAdded value: +"Override the synthesis prompt for completion searches. When omitted,\nfalls back to COGNEE_MCP_RECALL_SYSTEM_PROMPT / _FILE if configured\non the server." - removed
Input schema / properties / system_prompt / titleRemoved value: -"System Prompt" - added
Input schema / properties / top_k / descriptionAdded value: +"Maximum results to return (default: 10)." - removed
Input schema / properties / top_k / titleRemoved value: -"Top K" - removed
Input schema / titleRemoved value: -"recallArguments" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "result": { + "items": {}, + "type": "array" + } + }, + "required": [ + "result" + ], + "type": "object", + "x-fastmcp-wrap-result": true +}
- Changed
remember15 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / content_base64Added value: +{ + "default": null, + "description": "Base64-encoded file content to ingest. Requires filename.", + "type": "string" +} - added
Input schema / properties / custom_prompt / descriptionAdded value: +"Custom prompt for entity extraction (permanent mode only)." - removed
Input schema / properties / custom_prompt / titleRemoved value: -"Custom Prompt" - added
Input schema / properties / data / defaultAdded value: +null - added
Input schema / properties / data / descriptionAdded value: +"The text content to store. Mutually exclusive with\nfilename/content_base64." - removed
Input schema / properties / data / titleRemoved value: -"Data" - added
Input schema / properties / dataset_name / descriptionAdded value: +"Target dataset name. Defaults to the current MCP client's\nagent-scoped dataset (e.g. \"cursor_vscode_memory\"), or\n\"main_dataset\" if no client identity is detected." - removed
Input schema / properties / dataset_name / titleRemoved value: -"Dataset Name" - added
Input schema / properties / filenameAdded value: +{ + "default": null, + "description": "Original filename for a file upload. Used to derive the stored\ndocument's name. Requires content_base64.", + "type": "string" +} - added
Input schema / properties / session_id / descriptionAdded value: +"Session ID. When set, stores in session cache only." - removed
Input schema / properties / session_id / titleRemoved value: -"Session Id" - removed
Input schema / requiredRemoved value: -[ - "data" -] - removed
Input schema / titleRemoved value: -"rememberArguments" - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "result": { + "items": {}, + "type": "array" + } + }, + "required": [ + "result" + ], + "type": "object", + "x-fastmcp-wrap-result": true +}
- Added
search_tools - Changed
upload_file_ui2 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / titleRemoved value: -"upload_file_uiArguments"
- Changed
visualize_graph_ui3 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / dataset_name / titleRemoved value: -"Dataset Name" - removed
Input schema / titleRemoved value: -"visualize_graph_uiArguments"
4 tool updates
v1.4.1- Added
create_dataset_json - Added
get_client_info_json - Added
recall - Added
remember
4 tool updates
v1.4.0- Removed
create_dataset_json - Removed
get_client_info_json - Removed
recall - Removed
remember
1 tool update
v1.0.2- Changed
recall1 field changed- changed
Input schema / properties / top_k / defaultPrevious value: -10New value: +15
11 tool updates
v1.0.1- First observed
cognify_file - First observed
create_dataset_json - First observed
forget - First observed
get_client_info_json - First observed
list_dataset_data_json - First observed
list_datasets_json - First observed
open_cognee_workspace - First observed
recall - First observed
remember - First observed
upload_file_ui - First observed
visualize_graph_ui
TDQS
Scored across 6 tools
remember/recall/forget form a clearly distinct memory CRUD triad, and search_tools (discovery) vs call_tool (execution) are functionally separate. The only mild overlap is recall vs code_search (both 'search'), but the descriptions explicitly separate conversational memory from source-code graph search, so selection remains clear.
All names are snake_case and readable, but the convention is mixed: bare verbs (remember, recall, forget) sit alongside compound verb_noun forms (code_search, search_tools, call_tool). The pattern isn't uniformly predictable, though it's still interpretable.
Six tools is well-scoped for a memory/knowledge-graph server, sitting comfortably in the ideal range. Each tool covers a distinct capability (store, search, delete, code search, and dynamic tool discovery/execution) without redundancy.
Core lifecycle is covered: remember (create), recall (read), forget (delete), plus code_search and a dynamic tool layer. Minor gaps exist—no explicit update/modify operation for stored memory and no dataset listing/creation despite forget targeting datasets—but these are workarounds.
Maintenance
Related MCP Connectors
Persistent memory for AI agents. Semantic search, memory graph, W3C DID identity.
Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.
Universal memory for AI agents and tools. Save, organize and search context anywhere.
Shared memory for AI agents, as a graph in your own Postgres. Writes never call an LLM.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to store, retrieve, and connect information in a Neo4j graph database as persistent memory, with semantic relationships, natural language search, and temporal tracking across conversations.9122 npm69MIT
- AlicenseNot gradedqualityAmaintenancePersistent knowledge memory layer for AI agents. Hybrid semantic + full-text search with pgvector, code dependency graph with blast-radius impact analysis, and incremental indexing for 7 languages. In-process ONNX embeddings, no external API required.31 npm35MIT
- AlicenseNot gradedqualityDmaintenanceProvides persistent knowledge graph memory for AI agents, enabling them to store, recall, and query facts about people, projects, and relationships across sessions.MIT
- FlicenseNot gradedqualityFmaintenanceEnables LLMs to store, search, and manage memories with hybrid semantic and keyword search using ChromaDB and Neo4j for persistent memory and knowledge graph capabilities.-