Mcp Server Couchbase — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Mcp Server Couchbase (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Couchbase MCP Server is a self-hosted MCP Server that allows AI agents to connect to and interact with data in Couchbase Servers (whether hosted on Capella or self-managed) or Operational Insights Enterprise. It provides tools across categories including Cluster Health, Data Schema, Query, and more — with safety controls via read-only mode and fine-grained tool disabling. It supports both STDIO and Streamable HTTP transports with OAuth capabilities.
Couchbase MCP Server is distributed as a Python Package Index (PyPI) package and via Docker. Enterprise support for Couchbase MCP Server is available by licensing Couchbase AI Data Plane, which also entitles use and enterprise support of Couchbase Agent Memory and Couchbase Agent Catalog.
Full documentation: docs.couchbase.com/mcp-server
<a href="https://glama.ai/mcp/servers/@couchbase/mcp-server-couchbase"> <img width="380" height="200" src="https://glama.ai/mcp/servers/@couchbase/mcp-server-couchbase/badge" alt="Couchbase Server MCP server" /> </a>
<!-- mcp-name: io.github.couchbase/mcp-server-couchbase -->
CB_MCP_READ_ONLY_MODE=false; individual tools can also be disabled or gated behind user confirmation.Once connected, you can ask things like:
orders collection?"users where status = 'active'."products with these fields: …" (requires CB_MCP_READ_ONLY_MODE=false)This package ships two MCP servers. Each one is started by its own subcommand, connects to a different kind of cluster, and has its own tools. Pick the one that matches your cluster, follow its section for setup and tools, then use Common Configuration for the settings both share. To use both, register each as a separate server in your MCP client.
| Operational server | Operational Insights server | |
|---|---|---|
| Use it with | A Couchbase cluster (Capella or self-managed) | A self-managed Operational Insights cluster (not available on Capella) |
| Subcommand | operational (the default) | operational-insights |
| Connection string | couchbase:// / couchbases:// | HTTP(S) URL, e.g. http://localhost:8095 |
| Credential variables | CB_CONNECTION_STRING, CB_USERNAME, … | CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING, CB_OPERATIONAL_INSIGHTS_USERNAME, … |
| Tools | 52 — cluster health, schema, KV, SQL++, indexes, full-text and vector search, query performance | 13 — schema, SQL++ (sync and async), indexes, exports |
| Default HTTP port | 8000 | 8001 |
| Default log file | mcp_server.log | mcp_server_operational_insights.log |
The subcommand is optional for the operational server today — a barecouchbase-mcp-serverstarts it — but naming it keeps your configuration unambiguous. Options go after the subcommand:couchbase-mcp-server operational --transport=http. Check the installed version withuvx couchbase-mcp-server --version.
The operational server connects to a Couchbase cluster on Capella or self-managed Couchbase Server, using the couchbase Python SDK.
You need a running Couchbase cluster — the Capella free tier is the quickest way to get one (you can import a sample dataset) — and an MCP client. Add one of these configurations to your client (see Client Setup for where each client keeps it). If the client already has other servers, add couchbase to the existing mcpServers object.
From PyPI with uvx (requires uv and Python 3.11+):
{
"mcpServers": {
"couchbase": {
"command": "uvx",
"args": ["couchbase-mcp-server", "operational"],
"env": {
"CB_CONNECTION_STRING": "couchbases://connection-string",
"CB_USERNAME": "username",
"CB_PASSWORD": "password"
}
}
}
}With Docker (requires only Docker):
{
"mcpServers": {
"couchbase": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "CB_CONNECTION_STRING=couchbases://connection-string",
"-e", "CB_USERNAME=username",
"-e", "CB_PASSWORD=password",
"couchbase/mcp-server:latest", "operational"
]
}
}
}<details> <summary>From source</summary>
git clone https://github.com/couchbase/mcp-server-couchbase.git{
"mcpServers": {
"couchbase": {
"command": "uv",
"args": [
"--directory", "path/to/cloned/repo/mcp-server-couchbase/",
"run", "src/mcp_server.py", "operational"
],
"env": {
"CB_CONNECTION_STRING": "couchbases://connection-string",
"CB_USERNAME": "username",
"CB_PASSWORD": "password"
}
}
}
}path/to/cloned/repo/mcp-server-couchbase/ is the path to your clone — keep the trailing slash. After pulling updates, run uv sync to update dependencies.
</details>
Use either a username and password or a client certificate (mTLS). If both are set, the certificate is used.
| Environment Variable | CLI Argument | Description |
|---|---|---|
CB_CONNECTION_STRING | --connection-string | Connection string to the cluster. Required |
CB_USERNAME / CB_PASSWORD | --username / --password | Basic authentication |
CB_CLIENT_CERT_PATH / CB_CLIENT_KEY_PATH | --client-cert-path / --client-key-path | mTLS authentication |
CB_CA_CERT_PATH | --ca-cert-path | Root certificate for a self-signed/untrusted server certificate (not needed for Capella) |
<details> <summary>mTLS example</summary>
{
"mcpServers": {
"couchbase": {
"command": "uvx",
"args": ["couchbase-mcp-server", "operational"],
"env": {
"CB_CONNECTION_STRING": "couchbases://connection-string",
"CB_CLIENT_CERT_PATH": "/path/to/client-certificate.pem",
"CB_CLIENT_KEY_PATH": "/path/to/client.key"
}
}
}
}</details>
Write tools (marked ✏️) are not loaded while read-only mode is on, the default. Tools marked 🖥️ are self-managed only — they use admin REST endpoints that Capella does not expose, or (discover_tool_input_values) only serve reference data for a tool that does — so they need self-managed Couchbase Server 7.6+ and are not registered on Capella connections.
#### Cluster setup and health
| Tool | Description |
|---|---|
get_server_configuration_status | Server status and configuration without connecting to the cluster: read-only mode, disabled/confirmation-required tools, OAuth, logging and audit counters |
test_cluster_connection | Check the cluster credentials by connecting to the cluster |
get_cluster_health_and_services | Cluster health and running services, optionally filtered via service_types |
get_client_connectivity_report | The SDK's cached connection diagnostics, without active network probing |
get_cluster_metrics 🖥️ | Cluster statistics over a historic time window (stats-range endpoint) |
get_cluster_tasks 🖥️ | Tasks running right now — rebalance, compaction, XDCR, index build. Needs ro_admin |
get_cluster_health_snapshot 🖥️ | Per-node health: service topology, membership, orchestrator and a health rollup. Needs ro_admin |
get_bucket_config 🖥️ | A bucket's (or every bucket's) configuration and live state — quotas, eviction, replicas, durability, storage, compaction. Needs ro_admin |
get_cluster_system_events 🖥️ | The system event log (config changes, failovers, rebalances, restarts), windowed with since_time. Needs Full Admin or Cluster Admin |
discover_tool_input_values 🖥️ | Look up exact input values other tools need (e.g. every metric name for get_cluster_metrics). Works offline |
#### Data model and schema discovery
| Tool | Description |
|---|---|
get_buckets_in_cluster | List all buckets in the cluster |
get_scopes_in_bucket | List all scopes in a bucket |
get_collections_in_scope | List all collections in a scope (requires the Query service) |
get_scopes_and_collections_in_bucket | List all scopes and collections in a bucket |
get_schema_for_collection | Infer the structure of a collection |
create_scope ✏️ | Create a scope in a bucket (Server 7.6+ and Capella) |
create_collection ✏️ | Create a collection in an existing scope (Server 7.6+ and Capella) |
delete_scope ✏️ | Delete a scope and all its collections — permanent |
delete_collection ✏️ | Delete a collection and all its documents — permanent |
#### Document (KV) operations
| Tool | Description |
|---|---|
get_document_by_id | Get a document by ID |
lookup_subdocument | Read specific paths, existence checks or counts without fetching the whole document |
upsert_document_by_id ✏️ | Upsert a document by ID |
insert_document_by_id ✏️ | Insert a new document (fails if it exists) |
replace_document_by_id ✏️ | Replace an existing document (fails if it doesn't exist) |
delete_document_by_id ✏️ | Delete a document by ID |
mutate_subdocument ✏️ | Modify paths in an existing document (upsert, insert, replace, remove, array ops, counters) |
#### Query and indexing
| Tool | Description |
|---|---|
run_sql_plus_plus_query | Run a SQL++ query scoped to a bucket and scope — use collection names directly (SELECT * FROM users). Data-modifying statements are blocked in read-only mode |
explain_sql_plus_plus_query | Generate and evaluate an EXPLAIN plan: metadata, extracted plan and findings |
get_index_advisor_recommendations | Index Advisor recommendations for a SQL++ query |
list_indexes | List indexes with definitions, filterable by bucket/scope/collection/name; flags vector indexes (is_vector, vector_type) |
get_index_stats 🖥️ | Per-index size, fragmentation, scan traffic and lag, per node — finds pressure and unused indexes |
create_query_index ✏️ | Create a scalar, Hyperscale vector or Composite vector GSI index (index_type). Deferred by default — follow with build_index |
create_index ✏️ | Deprecated — use create_query_index. Removed in 2.0 |
build_index ✏️ | Build all deferred indexes on a collection |
drop_index ✏️ | Drop a GSI index (scalar or vector) |
#### Full-text search (FTS)
Requires Couchbase Server 7.6+ and the Search service. Scope-level and cluster-level (legacy) indexes are both supported: pass bucket_name and scope_name together for scope-level, or omit both.
| Tool | Description |
|---|---|
list_search_indexes | List Search indexes — cluster-level, per bucket, or per scope |
get_search_index_definition | Full definition of one Search index (mappings, analyzers, plan params) |
run_search | Run any non-vector FTS query from its raw JSON body; explain=true returns the execution plan |
upsert_search_index ✏️ | Create or update a Search index, including vector field mappings. Updates trigger a full rebuild — pass the current uuid to avoid clobbering concurrent changes |
drop_search_index ✏️ | Drop a Search index — permanent |
#### Vector search
Both tools embed plain query text with the model configured under Embedding Providers. Available on self-managed Couchbase Server and Capella.
| Tool | Description |
|---|---|
run_vector_query | Similarity search against a GSI vector index (Server 8.0+) via APPROX_VECTOR_DISTANCE(). The index is chosen automatically; supports a SQL++ where prefilter and Hyperscale tuning (num_probes, rerank, top_n_scan). Returns full documents |
run_vector_search | Search-service vector search (Server 7.6+) against a named index. scalar_query makes it hybrid; prefilter narrows candidates first. Returns index-stored fields per hit |
#### Query performance analysis
| Tool | Description |
|---|---|
get_longest_running_queries | Longest-running queries by average service time |
get_most_frequent_queries | Most frequently executed queries |
get_queries_with_largest_response_sizes | Queries with the largest response sizes |
get_queries_with_large_result_count | Queries with the largest result counts |
get_queries_using_primary_index | Queries using a primary index |
get_queries_not_using_covering_index | Queries not using a covering index |
get_queries_not_selective | Queries whose scans — secondary index, primary index or sequential — return far more documents than the final result |
#### Query service health 🖥️
These call the Query service's own admin REST API on every query node.
| Tool | Description |
|---|---|
get_cluster_query_vitals | Query-engine health: request rate, active/queued requests, memory, GC, uptime. Needs ro_admin |
get_active_queries | Queries executing right now across all query nodes. Needs ro_admin |
delete_active_query ✏️ | Cancel an in-flight query by request ID. Needs Full Admin or Cluster Admin |
#### Tools disabled automatically on Capella
The 🖥️ tools reach Couchbase through admin REST endpoints that Capella does not expose (the one exception, discover_tool_input_values, is withheld because it only serves a tool that needs them). When every host in CB_CONNECTION_STRING ends in .cloud.couchbase.com, the server does not register them and reports them alongside your own disabled tools in get_server_configuration_status and the startup log. SDK-based tools such as get_cluster_health_and_services and get_client_connectivity_report stay available.
| Tool | Endpoint it needs |
|---|---|
get_cluster_metrics | Management REST (/pools/default/stats/range) |
get_cluster_tasks | Management REST (/pools/default/tasks) |
get_bucket_config | Management REST (/pools/default/buckets[/<name>]) |
get_cluster_health_snapshot | Management REST, plus per-node endpoints |
get_cluster_system_events | Management REST (/events) |
get_index_stats | Index Service REST (each indexer's /api/v1/stats) |
get_cluster_query_vitals | Query service REST (/admin/vitals) |
get_active_queries | Query service REST (/admin/active_requests) |
delete_active_query | Query service REST (DELETE /admin/active_requests/{id}) |
discover_tool_input_values | None (works offline), but it only serves get_cluster_metrics, which Capella lacks |
run_vector_query and run_vector_search embed query text with the provider set in CB_MCP_EMBEDDING_MODEL_PROVIDER. This is optional: without it the server starts normally and both tools stay registered, but calling them returns an error explaining what to set.
CB_MCP_EMBEDDING_MODEL_PROVIDER | Required | Optional | Notes |
|---|---|---|---|
capella | CB_MCP_EMBEDDING_MODEL_API_KEY, CB_MCP_EMBEDDING_MODEL, CB_MCP_EMBEDDING_MODEL_ENDPOINT | — | Capella Model Service. CB_MCP_EMBEDDING_MODEL_ENDPOINT is your deployment's own URL (e.g. https://<id>.ai.couchbase.com) from Capella's AI Data Plane > Models |
openai | CB_MCP_EMBEDDING_MODEL_API_KEY, CB_MCP_EMBEDDING_MODEL | CB_MCP_EMBEDDING_MODEL_ENDPOINT | Set the endpoint to use an OpenAI-compatible local server (Ollama, vLLM, LM Studio) |
cohere | CB_MCP_EMBEDDING_MODEL_API_KEY, CB_MCP_EMBEDDING_MODEL | CB_MCP_EMBEDDING_MODEL_ENDPOINT | |
voyage | CB_MCP_EMBEDDING_MODEL_API_KEY, CB_MCP_EMBEDDING_MODEL | CB_MCP_EMBEDDING_MODEL_ENDPOINT | |
bedrock | CB_MCP_EMBEDDING_MODEL | CB_MCP_EMBEDDING_MODEL_AWS_ACCESS_KEY_ID, CB_MCP_EMBEDDING_MODEL_AWS_SECRET_ACCESS_KEY, CB_MCP_EMBEDDING_MODEL_AWS_REGION | Amazon Titan embedding models (e.g. amazon.titan-embed-text-v2:0) — the provider sends Titan's inputText request shape, so other Bedrock embedding models such as Cohere Embed are not supported yet. Omit credentials to use the default AWS chain. Needs the extra: pip install couchbase-mcp-server[bedrock-embeddings] |
"env": {
"CB_CONNECTION_STRING": "couchbases://connection-string",
"CB_USERNAME": "username",
"CB_PASSWORD": "password",
"CB_MCP_EMBEDDING_MODEL_PROVIDER": "openai",
"CB_MCP_EMBEDDING_MODEL": "text-embedding-3-small",
"CB_MCP_EMBEDDING_MODEL_API_KEY": "sk-..."
}<details> <summary>Every environment variable and CLI flag for the <code>operational</code> server</summary>
The Operational Insights server accepts the same options, except that it has its own connection settings and no CB_MCP_EMBEDDING_MODEL_* options.
| Environment Variable | CLI Argument | Description | Default |
|---|---|---|---|
CB_CONNECTION_STRING | --connection-string | Connection string to the Couchbase cluster | Required |
CB_USERNAME | --username | Username with access to required buckets for basic authentication | Required (or Client Certificate and Key needed for mTLS) |
CB_PASSWORD | --password | Password for basic authentication | Required (or Client Certificate and Key needed for mTLS) |
CB_CLIENT_CERT_PATH | --client-cert-path | Path to the client certificate file for mTLS authentication | Required if using mTLS (or Username and Password required) |
CB_CLIENT_KEY_PATH | --client-key-path | Path to the client key file for mTLS authentication | Required if using mTLS (or Username and Password required) |
CB_CA_CERT_PATH | --ca-cert-path | Path to server root certificate for TLS if server is configured with a self-signed/untrusted certificate. This will not be required if you are connecting to Capella | |
CB_MCP_READ_ONLY_MODE | --read-only-mode | Prevent all data modifications (KV, Query, scope/collection management, index management, and FTS index management). When enabled, write tools are not loaded. | true |
CB_MCP_TRANSPORT | --transport | Transport mode: stdio, http | stdio |
CB_MCP_HOST | --host | Host for the HTTP transport mode | 127.0.0.1 |
CB_MCP_PORT | --port | Port for the HTTP transport mode | 8000 |
CB_MCP_WORKERS | --workers | Number of server worker processes for the http transport. Values above 1 run in stateless HTTP mode (see Multiple Workers) | 1 |
CB_MCP_STATELESS_HTTP | --stateless-http | Handle each HTTP request without per-session state. Only honored with http; cannot be combined with confirmation-required tools (see Multiple Workers) | true when workers > 1, otherwise false |
CB_MCP_DISABLED_TOOLS | --disabled-tools | Tools to disable (see Disabling Tools) | None |
CB_MCP_CONFIRMATION_REQUIRED_TOOLS | --confirmation-required-tools | Tools that require explicit user confirmation before execution via MCP elicitation (see Requiring confirmation) | None |
CB_MCP_LOG_LEVEL | --log-level | Logging level for the MCP server: off, debug, info, warning, error (see Logging) | info |
CB_MCP_LOG_SINKS | --log-sinks | Comma-separated log destinations: stderr, file, or both (see Logging) | stderr |
CB_MCP_LOG_FILE | --log-file | Base path for per-level log files (only used when the file sink is enabled) | mcp_server.log |
CB_MCP_LOG_ROTATION_MAX_SIZE_MB | --log-rotation-max-size-mb | Global maximum size in MB per log file before it rotates, inherited by every level unless overridden. 0 — or a value that cannot be used, such as a negative, nan or inf — is invalid and falls back to the default with a startup warning | 1 (1 MB) |
CB_MCP_LOG_MAX_BYTES | --log-max-bytes | Deprecated — use CB_MCP_LOG_ROTATION_MAX_SIZE_MB (MB). Global rotation size in bytes, still honored for backward compatibility; ignored when CB_MCP_LOG_ROTATION_MAX_SIZE_MB is also set | Unset |
CB_MCP_LOG_ERROR_ROTATION_MAX_SIZE_MB | --log-error-rotation-max-size-mb | Rotation size in MB for the ERROR log file; overrides CB_MCP_LOG_ROTATION_MAX_SIZE_MB for ERROR | Inherits CB_MCP_LOG_ROTATION_MAX_SIZE_MB |
CB_MCP_LOG_WARNING_ROTATION_MAX_SIZE_MB | --log-warning-rotation-max-size-mb | Rotation size in MB for the WARNING log file; overrides CB_MCP_LOG_ROTATION_MAX_SIZE_MB for WARNING | Inherits CB_MCP_LOG_ROTATION_MAX_SIZE_MB |
CB_MCP_LOG_INFO_ROTATION_MAX_SIZE_MB | --log-info-rotation-max-size-mb | Rotation size in MB for the INFO log file; overrides CB_MCP_LOG_ROTATION_MAX_SIZE_MB for INFO | Inherits CB_MCP_LOG_ROTATION_MAX_SIZE_MB |
CB_MCP_LOG_DEBUG_ROTATION_MAX_SIZE_MB | --log-debug-rotation-max-size-mb | Rotation size in MB for the DEBUG log file; overrides CB_MCP_LOG_ROTATION_MAX_SIZE_MB for DEBUG | Inherits CB_MCP_LOG_ROTATION_MAX_SIZE_MB |
CB_MCP_LOG_RETENTION_BACKUP_COUNT | --log-retention-backup-count | Rotated backup files kept per-level log file (excluding the live file), applied to every level unless overridden. 0 keeps only the live file (see Logging) | 1 |
CB_MCP_LOG_ERROR_RETENTION_BACKUP_COUNT | --log-error-retention-backup-count | Rotated backups kept for the ERROR log file; overrides the global count for ERROR | Inherits CB_MCP_LOG_RETENTION_BACKUP_COUNT |
CB_MCP_LOG_WARNING_RETENTION_BACKUP_COUNT | --log-warning-retention-backup-count | Rotated backups kept for the WARNING log file; overrides the global count for WARNING | Inherits CB_MCP_LOG_RETENTION_BACKUP_COUNT |
CB_MCP_LOG_INFO_RETENTION_BACKUP_COUNT | --log-info-retention-backup-count | Rotated backups kept for the INFO log file; overrides the global count for INFO | Inherits CB_MCP_LOG_RETENTION_BACKUP_COUNT |
CB_MCP_LOG_DEBUG_RETENTION_BACKUP_COUNT | --log-debug-retention-backup-count | Rotated backups kept for the DEBUG log file; overrides the global count for DEBUG | Inherits CB_MCP_LOG_RETENTION_BACKUP_COUNT |
CB_MCP_OAUTH_JWT_JWKS_URI | --oauth-jwks-uri | JWKS endpoint of the identity provider used to verify bearer JWTs. Enables OAuth when set with the issuer and audience (see OAuth 2.1 Authorization) | None |
CB_MCP_OAUTH_JWT_ISSUER | --oauth-issuer | Expected JWT iss claim. Required to enable OAuth | None |
CB_MCP_OAUTH_JWT_AUDIENCE | --oauth-audience | Expected JWT aud claim. Required to enable OAuth | None |
CB_MCP_OAUTH_JWT_ALGORITHM | --oauth-algorithm | JWT signing algorithm: one of RS256/384/512, ES256/384/512, PS256/384/512 | RS256 |
CB_MCP_OAUTH_MCP_BASE_URL | --oauth-mcp-base-url | Public base URL of this server. When set, publishes RFC 9728 Protected Resource Metadata so PRM-aware clients can discover the IdP | None |
CB_MCP_OAUTH_SCOPE_READ_LABEL | --oauth-scope-read-label | Override the OAuth scope label treated as 'read' access (advertised in PRM and matched against the token's scope/scp claim). Use when your IdP can't emit the canonical form | couchbase-mcp:read |
CB_MCP_OAUTH_SCOPE_WRITE_LABEL | --oauth-scope-write-label | Override the OAuth scope label treated as 'write' access; same semantics as the read label | couchbase-mcp:write |
CB_MCP_AUDIT_LOG_ENABLED | --audit-log-enabled | Enable audit logging — a separate sink from the CB_MCP_LOG_* operational logs, with a stable schema and its own retention (see Auditing) | false |
CB_MCP_AUDIT_LOG_SINKS | --audit-log-sinks | Comma-separated audit destinations: console, file, or both. console writes to stderr — never stdout, which carries the JSON-RPC protocol on stdio | console |
CB_MCP_AUDIT_LOG_FILE_PATH | --audit-log-file-path | Path to the audit log file. Required when file is in the sinks; the hostname and process id are inserted before the extension (audit.log → audit.<host>.<pid>.log) | None |
CB_MCP_AUDIT_LOG_ROTATION_MAX_SIZE_MB | --audit-log-rotation-max-size-mb | Maximum size in MB the live audit file may reach before it rotates. 0 turns size-based rotation off | 10 (10 MB) |
CB_MCP_AUDIT_LOG_ROTATION_INTERVAL | --audit-log-rotation-interval | Age the live audit file may reach before it rotates, as <value><unit> where the unit is d (24 hours) or w (7 days) — e.g. 1d, 30d, 8w. 0 turns interval-based rotation off | 1d |
CB_MCP_AUDIT_LOG_RETENTION_MAX_BACKUPS | --audit-log-retention-max-backups | Rotated backups retained per audit file, excluding the live file. Backups are gzipped. 0 keeps none. This bounds one file, not the directory — see Auditing | 10 |
CB_MCP_AUDIT_LOG_TOOL_ARGS | --audit-log-tool-args | Record tool argument values in the audit log. Off by default — there is no redaction in this release, so enabling it writes arguments verbatim, including full document bodies | false |
CB_MCP_AUDIT_LOG_DISABLED_EVENTS | --audit-log-disabled-events | Audit events to suppress: comma-separated numeric event ids (e.g. 61490,61492), or a file with one id per line. Only filterable events can be suppressed | None |
CB_MCP_EMBEDDING_MODEL_PROVIDER | --embedding-model-provider | Embedding provider for run_vector_query / run_vector_search: one of capella, openai, cohere, voyage, bedrock. Unset disables both tools' embedding step until configured — see Embedding Provider Configuration | None |
CB_MCP_EMBEDDING_MODEL | --embedding-model | Model name/ID for the configured embedding provider | None |
CB_MCP_EMBEDDING_MODEL_API_KEY | --embedding-model-api-key | API key for the configured provider. Not used by bedrock (uses the AWS credential chain / CB_MCP_EMBEDDING_MODEL_AWS_* instead) | None |
CB_MCP_EMBEDDING_MODEL_ENDPOINT | --embedding-model-endpoint | Base URL override (an OpenAI-compatible local server, or a Capella Model Service deployment's own URL — required when CB_MCP_EMBEDDING_MODEL_PROVIDER=capella) | None |
CB_MCP_EMBEDDING_MODEL_AWS_ACCESS_KEY_ID | --embedding-model-aws-access-key-id | AWS access key ID, bedrock provider only. Omit to use the default AWS credential chain | None |
CB_MCP_EMBEDDING_MODEL_AWS_SECRET_ACCESS_KEY | --embedding-model-aws-secret-access-key | AWS secret access key, bedrock provider only | None |
CB_MCP_EMBEDDING_MODEL_AWS_REGION | --embedding-model-aws-region | AWS region, bedrock provider only. Falls back to the AWS SDK's own region resolution if unset | None |
</details>
The operational-insights server connects to self-managed Operational Insights clusters. Operational Insights is a real-time analytical database (RT-OLAP) for real-time apps and operational intelligence. The server is not available for Capella. It uses the couchbase-operational-insights SDK. It runs as its own process, separate from the operational server.
[!IMPORTANT]CB_OPERATIONAL_INSIGHTS_CONNECTION_STRINGis an HTTP(S) URL, not acouchbase://connection string — e.g.http://localhost:8095, orhttps://<host>:18095over TLS. This is the most common misconfiguration.
From PyPI with uvx:
{
"mcpServers": {
"couchbase-operational-insights": {
"command": "uvx",
"args": ["couchbase-mcp-server", "operational-insights"],
"env": {
"CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING": "http://localhost:8095",
"CB_OPERATIONAL_INSIGHTS_USERNAME": "Administrator",
"CB_OPERATIONAL_INSIGHTS_PASSWORD": "password"
}
}
}
}With Docker:
{
"mcpServers": {
"couchbase-operational-insights": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-e", "CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING=http://host.docker.internal:8095",
"-e", "CB_OPERATIONAL_INSIGHTS_USERNAME=Administrator",
"-e", "CB_OPERATIONAL_INSIGHTS_PASSWORD=password",
"couchbase/mcp-server:latest", "operational-insights"
]
}
}
}From source, use the operational source configuration with operational-insights as the last argument and the variables above.
| Environment Variable | CLI Argument | Description |
|---|---|---|
CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING | --connection-string | Endpoint URL (HTTP/HTTPS). Required |
CB_OPERATIONAL_INSIGHTS_USERNAME | --username | Username |
CB_OPERATIONAL_INSIGHTS_PASSWORD | --password | Password |
CB_OPERATIONAL_INSIGHTS_CA_CERT_PATH | --ca-cert-path | Root certificate (PEM) for a self-signed/untrusted server certificate |
CB_OPERATIONAL_INSIGHTS_CLIENT_CERT_PATH | --client-cert-path | Client certificate for mTLS — PEM (with a key) or a PKCS#12 bundle (.p12/.pfx, no key). Requires an https:// URL; overrides username/password |
CB_OPERATIONAL_INSIGHTS_CLIENT_KEY_PATH | --client-key-path | Private key (PEM) for the client certificate. Leave unset for PKCS#12 |
CB_OPERATIONAL_INSIGHTS_CLIENT_CERT_PASSWORD | --client-cert-password | Password for an encrypted key or PKCS#12 bundle |
CB_MCP_OPERATIONAL_INSIGHTS_QUERY_RESULT_MAX_SIZE | --operational-insights-query-result-max-size | Maximum query result size in bytes. Unset means no limit. When set, reading stops at the budget and the response reports truncated: true; a row that would overrun it is not returned. Values above 4 MiB (4194304) are clamped to 4 MiB, with a warning on stderr at startup |
CB_MCP_OPERATIONAL_INSIGHTS_ASYNC_QUERY_RESULT_TIMEOUT | --operational-insights-async-query-result-timeout | Timeout in seconds for each async query request: starting the query, checking its status, fetching results, discarding and cancelling. For a fetch it covers the whole download, so a result that takes longer than this to read fails. Raise it for large results or slow links. Positive integer, default 30, maximum 600. Larger values are clamped to 600 with a warning; any other invalid value is logged as a warning and 30 is used |
All common configuration applies, with these differences from the operational server:
8001 and the default log file is mcp_server_operational_insights.log, so both servers can run side by side.CB_MCP_WORKERS=1), because async query handles live in process memory.CB_MCP_EMBEDDING_MODEL_* options.All names except get_server_configuration_status are prefixed operational_insights_, so both servers can be registered in one client without collisions. The write tool (marked ✏️) is not loaded while read-only mode is on, the default.
#### Server Status
| Tool | Description |
|---|---|
get_server_configuration_status | Same tool as on the operational server |
#### Data Model & Schema Discovery
| Tool | Description |
|---|---|
operational_insights_get_databases_in_cluster | List databases |
operational_insights_get_scopes_in_database | List scopes in a database |
operational_insights_get_collections_in_scope | List collections (datasets) in a scope |
operational_insights_get_schema_for_collection | Infer a collection's JSON schema by sampling |
#### Query and Index
| Tool | Description |
|---|---|
operational_insights_list_indexes | List secondary indexes from System.Metadata.Index |
operational_insights_explain_query | EXPLAIN a SQL++ statement without running it |
operational_insights_run_query_sync | Run SQL++ and return rows, up to the result size limit; can export instead. Read-only mode is enforced server-side |
operational_insights_run_query_async | Start a long-running query and return a query_handle without waiting for rows; also preferred for large exports. Read-only mode is enforced server-side |
operational_insights_get_async_query_results | Poll an async query; returns rows (or the export destination) when ready |
operational_insights_discard_async_query_results | Free a finished async query's results |
operational_insights_cancel_async_query | Stop a still-running async query (allowed in read-only mode) |
operational_insights_create_index ✏️ | Create a secondary index via CREATE INDEX |
Async queries follow a start → poll → discard-or-cancel flow: operational_insights_run_query_async returns a query_handle, operational_insights_get_async_query_results is polled until ready, then operational_insights_discard_async_query_results frees the results, or operational_insights_cancel_async_query stops a query still running.
Instead of returning rows, operational_insights_run_query_sync and operational_insights_run_query_async can wrap the statement in COPY ... TO and write the rows to external object storage. Pass all three of copy_to_link (an existing link created with CREATE LINK ... TYPE S3), copy_to_bucket and copy_to_path, plus optionally copy_to_format (json, the default, or parquet). The tool then returns a confirmation with no rows:
{
"success": true,
"exported": true,
"destination": {"link": "s3Link", "bucket": "my-exports", "path": "exports/run1", "format": "json"},
"message": "Results were written to my-exports/exports/run1 as json. ..."
}CB_MCP_READ_ONLY_MODE=false or a token with couchbase-mcp:write.csv is not offered, because it needs an explicit output schema that can't be inferred from an arbitrary SELECT.These settings work the same way for both servers. Every option can be set as an environment variable or as a CLI flag after the subcommand.
Follow these security principles:
CB_MCP_DISABLED_TOOLS to keep the tool list to the minimum.The controls below form three layers, from broadest to narrowest. Use them together — but remember that none of them replaces RBAC.
[!IMPORTANT] The database user's RBAC permissions are the authoritative security control. For example, disablingupsert_document_by_idanddelete_document_by_iddoes not stoprun_sql_plus_plus_queryfrom runningINSERT/UPDATE/DELETE/MERGE— only read-only mode or missing RBAC permissions do. Give the server's database user only the permissions it needs.
#### Read-only mode
CB_MCP_READ_ONLY_MODE (default true) is the single switch for writes:
true — the write tools marked ✏️ in each server's tool list are not loaded, and queries that modify data or structure are blocked.false — write tools are loaded and modifying queries are allowed.#### Disabling tools
CB_MCP_DISABLED_TOOLS removes tools from discovery entirely. It accepts a comma-separated list or a path to a file with one tool name per line (# starts a comment):
CB_MCP_DISABLED_TOOLS="upsert_document_by_id,delete_document_by_id"
# or
CB_MCP_DISABLED_TOOLS=/path/to/disabled_tools.txt# disabled_tools.txt
# Write operations
upsert_document_by_id
delete_document_by_id
# Index advisor
get_index_advisor_recommendationsOn Capella, the operational server also disables some admin tools automatically.
#### Requiring confirmation (elicitation)
CB_MCP_CONFIRMATION_REQUIRED_TOOLS asks the user to confirm before a listed tool runs, using MCP elicitation. It takes the same comma-separated or file formats as disabled tools:
CB_MCP_CONFIRMATION_REQUIRED_TOOLS="delete_document_by_id,replace_document_by_id"CB_MCP_STATELESS_HTTP=true or CB_MCP_WORKERS above 1). The server refuses to start with that combination. Behind a load balancer, confirmation needs sticky sessions — see Load balancers.| Transport | Use for | Endpoint |
|---|---|---|
stdio (default) | One local client that launches the server as a subprocess | — |
http | Several clients sharing one server; supports OAuth and health checks, and workers on the operational server | http://<host>:<port>/mcp |
Set the transport with CB_MCP_TRANSPORT, the bind address with CB_MCP_HOST (default 127.0.0.1) and the port with CB_MCP_PORT (each server's default port when unset). Without OAuth, the HTTP endpoint is unauthenticated.
uvx couchbase-mcp-server operational \
--connection-string='<couchbase_connection_string>' \
--username='<database_username>' \
--password='<database_password>' \
--transport=httpThen point your client at the URL:
{
"mcpServers": {
"couchbase-http": {
"url": "http://localhost:8000/mcp"
}
}
}#### Multiple workers
One process uses at most about one CPU core. --workers N (CB_MCP_WORKERS) runs N processes behind the same host and port; the number of available cores is a good starting point. Workers are supported by the operational server only. With more than one worker:
http transport is required, and the server runs in stateless HTTP mode, because a client's requests can reach different workers. You can also set --stateless-http=true on a single worker, for example behind a load balancer without sticky sessions.mcp_server.<host>.<pid>.info.log) — one set for the supervisor and one per worker.#### Load balancers
You can run several server instances behind a load balancer. Each instance keeps its MCP sessions in its own memory, so the load balancer setting decides what works:
| Load balancer | Server setting | Confirmation-required tools |
|---|---|---|
Sticky sessions, routed on the Mcp-Session-Id request header | One worker, stateful (the default) | Supported |
| No sticky sessions | --stateless-http=true | Not supported — the server refuses to start if they are configured |
Mcp-Session-Id header, not on cookies. Many MCP clients do not keep cookies.query_handle in the memory of the instance that started the query, also in stateless mode. Polling, discarding or cancelling the query on a different instance returns Unknown query_handle. Use these tools with a single instance, or with sticky sessions so that all calls reach the instance that started the query. Stateless mode sends no Mcp-Session-Id, so it needs another affinity key, such as the client IP address.#### Health check
In HTTP mode, GET /health returns {"status": "ok", "server": "<server>"} on the MCP port. It is a liveness check: it does not connect to the cluster (so a cluster outage doesn't restart healthy containers), needs no authentication even with OAuth enabled, and is served by every worker. See Docker for probe examples.
With --transport=http, either server can act as an OAuth 2.1 resource server, validating bearer JWTs against your identity provider's JWKS. It works with any OAuth 2.1/OIDC provider that publishes a JWKS, and does not issue tokens or manage users. OAuth settings are ignored on stdio.
CB_MCP_OAUTH_JWT_JWKS_URI, CB_MCP_OAUTH_JWT_ISSUER and CB_MCP_OAUTH_JWT_AUDIENCE are set; setting only some fails at startup.CB_MCP_OAUTH_MCP_BASE_URL additionally publishes RFC 9728 Protected Resource Metadata so clients can discover the authorization server.scope/scp claim: couchbase-mcp:read (read tools) and couchbase-mcp:write (write tools). Full access needs both. Rename them with CB_MCP_OAUTH_SCOPE_READ_LABEL / CB_MCP_OAUTH_SCOPE_WRITE_LABEL if your IdP can't emit these labels. Both servers use the same labels, so one IdP configuration covers both.uvx couchbase-mcp-server operational \
--connection-string='<couchbase_connection_string>' \
--username='<database_username>' \
--password='<database_password>' \
--transport=http \
--oauth-jwks-uri='https://auth.example.com/.well-known/jwks.json' \
--oauth-issuer='https://auth.example.com/' \
--oauth-audience='couchbase-mcp-server' \
--oauth-mcp-base-url='<public_base_url_of_this_server>'See the OAuth documentation for the operational server and the Operational Insights server for IdP setup.
Each server logs to stderr at info level by default.
off, error, warning, info (lifecycle events and tool calls) or debug.stderr, file, or both. With file, one rotating file per level is written next to CB_MCP_LOG_FILE (mcp_server.info.log, mcp_server.error.log, …).CB_MCP_LOG_ROTATION_MAX_SIZE_MB (default 1 MB) and CB_MCP_LOG_RETENTION_BACKUP_COUNT (default 1) apply to every level; override per level with CB_MCP_LOG_<LEVEL>_ROTATION_MAX_SIZE_MB / CB_MCP_LOG_<LEVEL>_RETENTION_BACKUP_COUNT. Invalid sizes fall back to the default with a startup warning. CB_MCP_LOG_MAX_BYTES is deprecated.file sink, a JSON record of the environment and redacted server config is written to mcp_server_config.log.json on every start, for support.# Debug logging to stderr and rotating per-level files
uvx couchbase-mcp-server operational --log-level=debug --log-sinks=stderr,fileYour MCP client usually also captures the server's stderr — see Client Setup for where. Details: logging documentation for the operational server and the Operational Insights server.
Audit logging records who did what, and whether it was allowed — separate from the operational logs, which record what went wrong. The MCP server is the only layer that can answer this for an agent: every request reaches the cluster as a single database user, and decisions such as a scope denial, a read-only block or a declined confirmation never reach the cluster at all.
Auditing is off by default. Turn it on with CB_MCP_AUDIT_LOG_ENABLED=true; it writes to stderr unless you set CB_MCP_AUDIT_LOG_SINKS=file and CB_MCP_AUDIT_LOG_FILE_PATH.
# 90 days of daily, gzipped audit files
uvx couchbase-mcp-server operational --audit-log-enabled=true \
--audit-log-sinks=file --audit-log-file-path=/var/log/cb-mcp/audit.log \
--audit-log-rotation-interval=1d --audit-log-rotation-max-size-mb=0 \
--audit-log-retention-max-backups=90Records are JSON Lines using the same field vocabulary as Couchbase Server and Sync Gateway:
{"id":61522,"name":"document write","description":"A document write operation was requested through a tool","timestamp":"2026-09-29T09:14:22.418Z","real_userid":{"domain":"oauth","user":"agent-svc-7"},"server":{"version":"1.0.2","host":"mcp-01"},"cid":"9f2c...","outcome":"success","tool_name":"upsert_document_by_id","required_scope":"write","ks":"travel-sample.inventory.airline","cb_userid":"mcp_service"}<details> <summary>How auditing behaves</summary>
real_userid is the caller: oauth (the token subject), local (the OS user, on stdio) or anonymous (HTTP without OAuth, which warns at startup).cid groups every record from one request, and is sent as the SQL++ client_context_id, so it joins exactly with Couchbase Server's clientContextId. There is deliberately no session identifier.query and search are the exceptions: each is recorded as a single event rather than a read/write pair, because the distinction could not be made reliably for statement-driven and search surfaces. Vector operations sit inside those two categories. The full catalogue ships as descriptor.json in the package. The operational server uses block 0xF000 (61440), Operational Insights 0x10000 (65536), and both share 0xE000 (57344) for core events.CB_MCP_AUDIT_LOG_DISABLED_EVENTS suppresses read events by numeric id (e.g. 61490,61492). Write and security events cannot be disabled, and neither can the single-event categories query (61507, or 65603 on Operational Insights) and search (61510): one event covers each category's writes as well as its reads, so switching it off would lose a mutation record.CB_MCP_AUDIT_LOG_ROTATION_MAX_SIZE_MB, default 10) and age (CB_MCP_AUDIT_LOG_ROTATION_INTERVAL, default 1d), whichever comes first; 0 switches either off. Rotated files are timestamped and gzipped; the live file stays plain text for tail -f.audit.log → audit.<host>.<pid>.log), so concurrent processes never share a file.CB_MCP_AUDIT_LOG_RETENTION_MAX_BACKUPS (default 10) bounds one file's backups. Each new process writes a new file and nothing prunes old ones, so size the volume or sweep old audit.*.log* files.get_server_configuration_status reports written / dropped / write_errors.CB_MCP_AUDIT_LOG_TOOL_ARGS=true, which warns at startup. There is no redaction in this release, so arguments, including full document bodies, are written verbatim.</details>
Each client needs a server configuration from the operational or Operational Insights quick start in its own configuration location. The examples below use the operational server.
<details> <summary>Claude Desktop</summary>
~/Library/Application Support/Claude/claude_desktop_config.json%APPDATA%\Claude\claude_desktop_config.jsonmcpServers and restart Claude Desktop.Logs: macOS ~/Library/Logs/Claude, Windows %APPDATA%\Claude\Logs. See the MCP troubleshooting guide.
</details>
<details> <summary>Cursor</summary>
mcpServers and save.couchbase is enabled.Logs: in the bottom panel, open Output and select Cursor MCP.
[cursor-install-basic]: https://cursor.com/en-US/install-mcp?name=Couchbase&config=eyJjb21tYW5kIjoidXZ4IiwiYXJncyI6WyJjb3VjaGJhc2UtbWNwLXNlcnZlciJdLCJlbnYiOnsiQ0JfQ09OTkVDVElPTl9TVFJJTkciOiJjb3VjaGJhc2VzOi8vY29ubmVjdGlvbi1zdHJpbmciLCJDQl9VU0VSTkFNRSI6InVzZXJuYW1lIiwiQ0JfUEFTU1dPUkQiOiJwYXNzd29yZCJ9fQ%3D%3D
</details>
<details> <summary>Windsurf Editor</summary>
couchbase is enabled.</details>
<details> <summary>VS Code</summary>
VS Code uses servers as the top-level key instead of mcpServers. Put the configuration in .vscode/mcp.json for a workspace, or run MCP: Open User Configuration for all workspaces (see VS Code's MCP docs):
{
"servers": {
"couchbase": {
"command": "uvx",
"args": ["couchbase-mcp-server", "operational"],
"env": {
"CB_CONNECTION_STRING": "couchbases://connection-string",
"CB_USERNAME": "username",
"CB_PASSWORD": "password"
}
}
}
}Saving the file starts the server; use the Running | Stop | n Tools actions above it to manage it.
Logs: run MCP: List Servers, pick couchbase, then Show Output.
</details>
<details> <summary>JetBrains IDEs</summary>
Logs: Help > Show Log in Finder (Explorer) > mcp > couchbase.
</details>
Prebuilt images are published to Docker Hub as couchbase/mcp-server, and the server is listed in the Docker MCP Catalog. Configure the container with the same environment variables as above. See the Docker Hub page (DOCKER.md) for tags, volumes and health-check examples.
Running over HTTP — note that the server must bind to 0.0.0.0 to be reachable from outside the container:
docker run --rm \
-e CB_CONNECTION_STRING='<couchbase_connection_string>' \
-e CB_USERNAME='<database_user>' \
-e CB_PASSWORD='<database_password>' \
-e CB_MCP_TRANSPORT=http \
-e CB_MCP_HOST=0.0.0.0 \
-p 8000:8000 \
couchbase/mcp-server:latest operationalcouchbase://host.docker.internal as the connection string (see Docker networking). Use --network=<your_network> to join another container's network.operational-insights instead of operational to run the Operational Insights server (port 8001).<details> <summary>Building the image from source</summary>
docker build -t mcp/couchbase-src ../build.sh [image-name] builds with the same arguments as CI — it sets the GIT_COMMIT_HASH and BUILD_DATE build args and tags the image latest and <short-commit> (default name mcp/couchbase-src). To build with the labels by hand:
docker build --build-arg GIT_COMMIT_HASH=$(git rev-parse HEAD) \
--build-arg BUILD_DATE=$(date -u +'%Y-%m-%dT%H:%M:%SZ') \
-t mcp/couchbase-src .
# Check the labels
docker inspect --format='{{json .Config.Labels}}' mcp/couchbase-src:latest</details>
For full guides, see the troubleshooting documentation for the operational server and the Operational Insights server, and the security guidelines for the operational server and the Operational Insights server. Quick checks:
uv/uvx, put the absolute path in command.uv sync after pulling updates.get_server_configuration_status to see the configuration the server actually resolved, and check your client's logs (see Client Setup).How do I connect Claude Desktop to Couchbase? Add the quick start configuration to claude_desktop_config.json and restart Claude Desktop — see Client Setup.
Can I use this with Couchbase Capella? Yes, with the operational server: the same configuration works for Capella and self-managed clusters, though a few admin tools are only available on self-managed clusters (see Tools). The Operational Insights server is for self-managed Operational Insights clusters only.
Is it safe to let an AI agent write to my database? By default, no write tools are loaded and modifying SQL++ is blocked. If you enable writes, you can still disable individual tools or require confirmation — but your Couchbase user's RBAC permissions remain the real security boundary. See Safety Controls.
Do I need to know SQL++? No. Ask in plain English and the assistant writes the SQL++ for run_sql_plus_plus_query. It can also explain a query plan or ask the Index Advisor for recommendations.
STDIO or Streamable HTTP? STDIO for a single local client. Streamable HTTP to share one server between clients, with OAuth. See Transports.
Is this officially supported by Couchbase? Yes, with a Couchbase AI Data Plane license. Without one, Couchbase engineers help on a best-effort basis through GitHub issues. See Support Policy.
Contributions are welcome — bug fixes, features and documentation. To report a bug or ask for help, open a GitHub issue.
See CONTRIBUTING.md for development setup, linting, testing, project structure and workflow. To get started:
git clone https://github.com/couchbase/mcp-server-couchbase.git
cd mcp-server-couchbase
uv sync --extra dev
uv run pre-commit install
./scripts/lint.shIntegration tests run against a live cluster. Export CB_CONNECTION_STRING, CB_USERNAME, CB_PASSWORD and optionally CB_MCP_TEST_BUCKET; the Operational Insights tests also use CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING / _USERNAME / _PASSWORD and are skipped when those are unset. Then run:
uv run --extra dev pytest tests/integration -vThis product automatically collects usage and performance data (such as product name and version) and browser information (such as IP address) (collectively, "Usage Data"). Couchbase uses Usage Data, along with other data you may provide to Couchbase (such as your user name or email address), to develop and improve our products as well as inform our sales and marketing programs. We do not access or collect any data you store in Couchbase products. We use Usage Data to understand aggregate usage patterns and make our products more useful to you. For more information on how Couchbase collects, protects, and processes information, please refer to the Couchbase Privacy Policy viewable at https://www.couchbase.com/privacy-policy.
Couchbase MCP Server is open source and maintained by Couchbase engineers. How you get help depends on how you use it:
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.