Chroma MCP Server Cursor IDE Setup (2026): uvx Install, --client-type & Persistent Storage
Connect Chroma's official MCP server to Cursor IDE: install with uvx chroma-mcp, pick a --client-type (ephemeral, persistent, http, or cloud), and manage collections plus vector queries directly from the editor — including why the default mode silently loses your data on restart.
How do you connect Chroma (ChromaDB) to Cursor? Add a chroma entry to ~/.cursor/mcp.json that runs chroma-mcp via uvx, and pass a --client-type argument to tell it where your data lives: ephemeral for a throwaway in-memory store, persistent for a local on-disk directory, http for a self-hosted Chroma server, or cloud for Chroma's managed offering. Restart Cursor, and it gets eleven tools covering full collection lifecycle — create, list, query, add, update, delete — not just store-and-search.
That breadth is the first thing to notice if you've set up Qdrant or Weaviate first: those servers deliberately keep the tool surface narrow (a memory-style store/find pair, or a handful of read-plus-hybrid-search tools). Chroma's official server exposes real collection administration — chroma_create_collection, chroma_modify_collection, chroma_delete_collection — alongside the document operations. That makes it more capable and also means a misconfigured or overly-trusted agent can drop a collection it shouldn't touch, which is worth thinking about before wiring this into a shared project's mcp.json.
What the Chroma MCP Server Can Do
Two families of tools, eleven total:
Collection operations:
chroma_list_collections — list what exists in the connected Chroma instancechroma_create_collection — create a new collection, optionally with an embedding function specifiedchroma_get_collection_info / chroma_get_collection_count — inspect schema and sizechroma_peek_collection — sample a few documents without a full querychroma_modify_collection — rename or reconfigure metadatachroma_delete_collection — remove a collection entirely, no confirmation step built inDocument operations:
chroma_add_documents — insert documents (embedded automatically using the collection's configured embedding function)chroma_query_documents — vector similarity search, with metadata filtering supportchroma_get_documents — fetch by ID or filter, no similarity rankingchroma_update_documents — modify existing documents in placechroma_delete_documents — remove specific documents by ID or filterTypical prompts once connected:
product-docs using the default embedding function"support-kb collection"product-docs for anything about rate limiting and show me the top 5 matches"support-kb collection right now?"faq-042 from support-kb"Prerequisites
uv installed and on your PATH — this is a Python package run via uvx, the same pattern as Qdrant's official server, not an npx oneStep 1: Pick a Client Type
This is the decision that shapes everything else, and it's easy to skip past since the server runs fine with zero arguments — it just defaults to ephemeral, meaning fully in-memory with nothing written to disk. That's fine for testing a prompt or exploring the tools, but every collection and document disappears the moment the MCP server process restarts, which happens more often than you'd expect since Cursor can respawn MCP servers on its own (an IDE restart, a crashed process, a config reload).
For anything you want to persist across sessions, pick one of:
persistent — local on-disk storage at a directory you specify. Good default for solo, single-machine use.http — connects to a self-hosted Chroma server running elsewhere (your own Docker container, a shared team instance).cloud — Chroma's managed service, authenticated with tenant, database, and API key.Step 2: Configure Cursor MCP
Ephemeral (default, no persistence — good for a quick trial only):
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": ["chroma-mcp"]
}
}
}
Persistent local storage:
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": [
"chroma-mcp",
"--client-type",
"persistent",
"--data-dir",
"/Users/you/.chroma/cursor-data"
]
}
}
}
Self-hosted, via HTTP:
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": [
"chroma-mcp",
"--client-type",
"http",
"--host",
"your-chroma-host.internal",
"--port",
"8000",
"--ssl",
"true"
]
}
}
}
Chroma Cloud:
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": [
"chroma-mcp",
"--client-type",
"cloud",
"--tenant",
"your-tenant-id",
"--database",
"your-database-name",
"--api-key",
"your-api-key"
]
}
}
}
Restart Cursor after saving. The --data-dir path in persistent mode gets created automatically on first run if it doesn't already exist — you don't need to mkdir it yourself first.
Step 3: Keep API Keys Out of Plaintext Args (Optional but Worth Doing)
The README is upfront that putting --api-key directly in args is fine for a personal machine but not something you want in a mcp.json you might commit to a shared repo. The alternative is --dotenv-path, pointing at an env file instead of inlining the key:
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": [
"chroma-mcp",
"--client-type",
"cloud",
"--tenant",
"your-tenant-id",
"--database",
"your-database-name",
"--dotenv-path",
"/Users/you/.chroma/.env"
]
}
}
}
With CHROMA_API_KEY=your-api-key inside that .env file instead. The server also reads CHROMA_CLIENT_TYPE, CHROMA_DATA_DIR, CHROMA_TENANT, CHROMA_DATABASE, CHROMA_HOST, CHROMA_PORT, and CHROMA_SSL as environment-variable equivalents of every CLI flag above, so an entire config can live in the .env file with no flags in mcp.json at all if you'd rather keep mcp.json generic and swap .env files per environment.
Step 4: Test the Connection
Start with something that doesn't touch data:
List the Chroma collections available right now
Then create and query one:
Create a Chroma collection called "test-notes" and add a document saying "Cursor MCP integration test, created today"
Query the test-notes collection for anything about MCP integration testing
If the query returns the document you just added, the connection, embedding function, and query path are all working end to end.
Choosing an Embedding Function
By default, Chroma uses its built-in default embedding function with no extra configuration. If you want a specific provider's embeddings instead — for consistency with embeddings you've already generated elsewhere, or for quality on a specific domain — the server supports cohere, openai, jina, voyageai, and roboflow. Each needs its own API key set as an environment variable following the pattern CHROMA_<PROVIDER>_API_KEY — CHROMA_OPENAI_API_KEY, CHROMA_COHERE_API_KEY, and so on. Set the embedding function when a collection is created; switching it afterward doesn't re-embed existing documents, so a mid-project change means either accepting mixed embedding spaces (bad for similarity search) or recreating the collection.
Gotchas Worth Knowing
Ephemeral mode is the default, and it's silent about it. There's no warning when you run chroma-mcp with zero args that everything you create will vanish on restart. If a demo or test session "loses" data between Cursor restarts, check whether --client-type persistent (or http/cloud) was ever actually set — the ephemeral default is the most common reason data disappears, not a bug.
chroma_delete_collection has no confirmation step. The tool does exactly what it's told, immediately. If you're giving an agent broad latitude to manage collections, be specific in your prompts about which collection you mean — "delete the test collection" is more dangerous than it sounds if there's ambiguity about which one that is.
Switching embedding functions mid-project silently degrades search quality. Chroma doesn't block you from changing a collection's embedding function after documents already exist in a different embedding space; it just means new queries compare against a mix of two different vector spaces, which produces confusing, seemingly-random relevance. Recreate the collection instead of switching in place.
Troubleshooting
"uvx: command not found"uv isn't installed or isn't on the PATH Cursor's process sees, which can differ from your terminal's PATH on macOS depending on how Cursor was launched. Reinstall uv, then fully quit and reopen Cursor.
Data is gone after restarting Cursor
You're on the default ephemeral client type. Add --client-type persistent with a --data-dir, or switch to http/cloud if you need shared, longer-lived storage.
HTTP client type fails to connect
Confirm --host and --port match your self-hosted Chroma server's actual listen address, and that --ssl matches whether that server is actually serving over TLS — a mismatch here (e.g., --ssl true against a plain HTTP server) fails the connection with a generic-looking error rather than a clear SSL mismatch message.
Cloud client type fails with an auth error
Double-check --tenant and --database match exactly what's shown in the Chroma Cloud console — these are case-sensitive identifiers, not display names — and that the API key hasn't expired or been scoped to a different tenant.
Query results seem irrelevant or empty
Confirm the collection actually has documents (chroma_get_collection_count) and that you haven't mixed embedding functions within one collection, per the gotcha above. An empty or embedding-mismatched collection returns technically-valid but useless results rather than an obvious error.
When Not to Use This
If you need Chroma's full Python client capabilities — custom distance functions, advanced filtering syntax, direct control over HNSW index parameters — the MCP server's eleven tools cover common CRUD and query operations, not every knob Chroma's SDK exposes. For deep index tuning or bulk data migration, use the chromadb Python client directly rather than routing it through an agent conversation.
Frequently Asked Questions
Q: What happens to my data if I don't set a --client-type?
A: It defaults to ephemeral — fully in-memory, with everything lost when the MCP server process restarts. Set --client-type persistent with a --data-dir (or http/cloud) for anything you need to survive past the current session.
Q: Why does this use uvx instead of npx?
A: chroma-mcp is a Python package, like Qdrant's official server, not a Node one. If you're used to copying an npx -y <package> block from another guide on this site, swap command to uvx and drop the -y — it isn't an npx flag.
Q: Can Cursor create and delete Chroma collections through this, or is it read-only?
A: Full read/write by default — chroma_create_collection and chroma_delete_collection are both available with no separate flag to disable them, unlike some other vector-database MCP servers that gate write access behind an explicit setting. Be deliberate about what you connect this to, especially on a shared instance.
Q: How is this different from the Qdrant or Weaviate MCP servers?
A: Broader tool surface. Qdrant's official server is a minimal store/find memory layer; Weaviate's built-in server is read-only by default with an explicit flag to enable a single write tool. Chroma's exposes full collection lifecycle management (create, modify, delete) plus document CRUD, which is more capable but also more exposure if an agent misinterprets a prompt. See the Qdrant setup guide and Weaviate setup guide for the comparison.
Q: Do I need a Chroma Cloud account, or can I run this entirely locally?
A: Entirely local works fine — use --client-type persistent with a --data-dir for on-disk storage with no external account or server needed. Cloud and self-hosted HTTP are there for shared or multi-machine setups, not requirements.
Related Guides
Related guides
- CircleCI MCP Server Cursor IDE Setup 2026: API Token Config for Pipelines & Build Failures
- Clerk MCP Server Cursor IDE Setup 2026: One Command via clerk mcp install
- ClickHouse MCP Server Cursor IDE Setup (2026): Cloud OAuth & Self-Hosted mcp-clickhouse
- ClickUp MCP Server Cursor IDE Setup 2026: Manage Tasks Without Leaving Your Editor