Troubleshooting

  • reference
Common issues and fixes for the Couchbase MCP Server, covering connections, transport, OAuth, and logging.

Common issues that you might run into while using the Couchbase MCP Server and their solutions.

uv/uvx Issues

If you see errors related to uv or uvx, check the following:

  • uvx not found: Verify that uv is on your system PATH. Install uv following the official instructions. If installed via a package manager, verify it’s on your PATH.

  • Run which uv (macOS/Linux) or where uv (Windows) to find the path. You may need to provide the absolute path to uv/uvx in the command field of your MCP client configuration.

  • After updating source code, run uv sync to update dependencies. This is only required when running from source after pulling new changes.

Connection Issues

If you see errors related to connecting to the Operational Insights cluster, check the following:

  • Check credentials: Verify that your connection string, username, password, or certificate paths are correct.

  • Cluster accessibility: Verify that the Operational Insights cluster is accessible from the machine running the MCP server.

  • Database permissions: Check that the Operational Insights user has proper permissions to access at least one database.

  • Connection string format: Use https:// for TLS-enabled clusters, http:// for unencrypted local connections.

  • Certificates for TLS: If you’re connecting with TLS enabled, verify that you’ve configured the certificate correctly via CB_OPERATIONAL_INSIGHTS_CA_CERT_PATH.

Transport Mode Issues

If the MCP client is unable to communicate with the server, check the following based on your configured transport mode:

  • stdio: Verify that you’ve configured the MCP client to launch the server as a subprocess. Check the client’s server configuration for the correct command and arguments to start the server.

  • HTTP: Check that the configured port is not in use. Verify that the URL ends with /mcp. Also check if the client configuration is set correctly.

  • Port conflicts: If the default port 8001 is in use, set a different port with CB_MCP_PORT or --port.

  • Host binding: By default, the server binds to 127.0.0.1 (localhost only). To allow external connections, set CB_MCP_HOST=0.0.0.0 or --host.

Large Result Issues

If a query result is cut short, or your client handles a large result in an unexpected way, review the following:

  • The response has truncated: true: The result is larger than CB_MCP_OPERATIONAL_INSIGHTS_QUERY_RESULT_MAX_SIZE. The remaining rows are not available by calling the tool again. Narrow the statement, raise the limit up to 4 MB, or export the result with the copy_to_* arguments.

  • The message says the result is not empty: The limit is smaller than the first row. The tool returns no rows, but matching rows exist. Raise the limit, or select fewer fields.

  • An export is blocked: COPY …​ TO is blocked in read-only mode and for a token without the write scope. Set CB_MCP_READ_ONLY_MODE=false and use a token with couchbase-mcp:write.

  • An export is rejected: Set copy_to_link, copy_to_bucket, and copy_to_path together. The link must already exist. copy_to_format accepts json or parquet.

See Large Result Handling for the full details.

Async Query Issues

The async query tools keep each query handle in the memory of one server process. For how the tools work together, see Query and Index.

Symptom What to do

operational_insights_get_async_query_results returns ready: false, or a handle stops working

ready: false means the query is still running, so call the tool again later. Handles live in process memory, so a restart of the server loses them. The query can still finish on the cluster, but its handle is gone and no tool can find it, so run the query again. Also discard the earlier query’s results on the Operational Insights cluster, using its UI directly. You cannot cancel a finished query, so discard it instead. When you finish with a result, call operational_insights_discard_async_query_results, because results stay on the cluster after a fetch.

A fetch of the results fails with a timeout

The query finished on the cluster, so raise CB_MCP_OPERATIONAL_INSIGHTS_ASYNC_QUERY_RESULT_TIMEOUT, which is 30 seconds by default. See Timeout for Async Query Tools.

A handle works on some calls and stops working on others, with more than one server behind a load balancer

Each server keeps its own handles. Configure the load balancer to send all requests for one handle to the same server.

Read-Only Mode Issues

If you’re trying to perform write operations but they’re not working as expected, check the following:

  • Check whether CB_MCP_READ_ONLY_MODE=true (the default).

  • When CB_MCP_READ_ONLY_MODE=true, operational_insights_create_index is not loaded, and SQL++ queries run with the server-side readonly option (so the cluster itself rejects data and structure modifications). COPY …​ TO (export) statements are also blocked client-side. Set CB_MCP_READ_ONLY_MODE=false to allow write operations.

  • See Read-Only Mode for the full behavior reference.

Tool Disabling Issues

If a tool you expect to be disabled is still executing, check the following:

  • Verify that you’ve spelled tool names exactly as listed in the Tools reference.

  • If using a file path for CB_MCP_DISABLED_TOOLS, verify that the file exists and the server process can read it. If using Docker, verify that the file is included in the container and the path is correct.

  • Remember that disabling tools alone does not prevent operations - RBAC is the authoritative security control. See Security.

Elicitation/Tools Requiring Confirmation

If the tool you expect to require confirmation is executing without it, check the following:

  • Verify that the MCP client supports Elicitation. If the client does not support it, the server executes the tools without requiring confirmation.

  • Verify that you’ve spelled tool names exactly as listed in the Tools reference.

  • The server fails to start with confirmation-required tools: Elicitation cannot work in stateless mode, which has no session for the prompt. The server refuses to start when you combine --confirmation-required-tools with --stateless-http. Turn off stateless mode, or remove the confirmation requirement.

  • If using a file path for CB_MCP_CONFIRMATION_REQUIRED_TOOLS, verify that the file exists and the server process can read it. If using Docker, verify that the file is included in the container and the path is correct.

Environment Variable Issues

If you’re setting environment variables but they do not seem to be taking effect, check the following:

  • Variables not taking effect: Verify that you’ve set variables in the env block of your MCP client configuration, not as system environment variables (unless your client supports that).

  • CLI vs environment variable conflicts: Command line arguments take priority over environment variables. If a setting is not behaving as expected, check if it’s being overridden by a CLI argument.

  • See Environment Variables for the full reference.

OAuth Issues

OAuth applies only to the Streamable HTTP transport — it’s ignored on stdio. For the full configuration reference, see OAuth.

Quick first-pass diagnosis

Before digging in, confirm these five things — a surprising number of OAuth issues are resolved here:

# Check Expected

1

What transport is the server on?

Streamable HTTP (--transport=http). OAuth is ignored on stdio

2

What does the startup log say about OAuth?

One of OAuth enabled …, OAuth disabled …, or OAuth settings provided but transport=…

3

Does the PRM endpoint respond?

curl -s http://<host>:<port>/.well-known/oauth-protected-resource/mcp returns JSON (only when --oauth-mcp-base-url is set)

4

Does an unauthenticated tool call return 401?

A POST to /mcp with no token → 401 Unauthorized

5

Decode a sample token and confirm iss, aud, exp, scope/scp

Values match what the server expects

Server startup

Symptom Meaning Fix

Incomplete OAuth configuration. To enable OAuth, set all of: …

You set some but not all of the required JWT settings.

OAuth is all-or-nothing: set all of CB_MCP_OAUTH_JWT_ISSUER, CB_MCP_OAUTH_JWT_AUDIENCE, CB_MCP_OAUTH_JWT_JWKS_URI, or none. The server refuses to start on partial config so OAuth never silently fails to enable.

…issuer must be a valid http(s) URL …

You enabled PRM (--oauth-mcp-base-url) but the issuer is not a URL.

With PRM, the issuer is published as the authorization-server URL and must be a valid http(s)://…. In token-only mode (no --oauth-mcp-base-url), any plain string works.

Log: OAuth disabled (no … settings provided)

The server is running with no OAuth — all requests are accepted unauthenticated.

You passed none of the OAuth settings (a dropped shell line-continuation \ is a frequent culprit), or set them in a different shell than the one you launched from. Verify with env | grep CB_MCP_OAUTH in the same shell, or hardcode the values on one launch line.

Log: OAuth settings provided but transport=stdio; …only honored for streamable-http

OAuth flags were detected but the server started on stdio.

Add --transport=http. OAuth applies only to Streamable HTTP.

Log: …MCP_BASE_URL set without any JWT settings; ignoring

You asked for PRM but configured no token verifier.

Set the JWT settings. PRM is meaningless without a verifier — it advertises an authorization server but validates nothing.

/.well-known/oauth-protected-resource/mcp returns 404

PRM is not mounted.

PRM is published only when --oauth-mcp-base-url is set. Also confirm you include the /mcp suffix (per RFC 9728 the mount path is appended).

401 Unauthorized — token validation

Returned by the auth middleware before any tool runs. The log shows Auth error returned: invalid_token (status=401). Decode the token and compare it against your server config.

Symptom Meaning Fix

audience mismatch (got 'X', expected 'Y')

Token’s aud ≠ --oauth-audience.

Decode a sample token, copy the aud value verbatim, and set --oauth-audience to match exactly (no trailing-slash differences). Some IdPs emit a different aud per grant type.

issuer mismatch (got 'X', expected 'Y')

Token’s iss ≠ --oauth-issuer.

Decode a token, copy iss verbatim, and match it. A trailing-slash difference is the most common cause.

token expired

The exp claim is in the past.

Mint a fresh token. If you suspect clock skew, run NTP on the server host — the server applies no leeway by default.

403 Forbidden — scope enforcement

Returned after JWT validation succeeds. The message names the required and missing scopes.

Symptom Meaning Fix

Tool 'X' requires scope(s) ['couchbase-mcp:read']; token is missing …

The token does not carry the required scope.

Decode the token and check both the scope (space-separated string) and scp (array) claims. Mint a token that includes the needed scope.

operational_insights_create_index rejected for a read-only token

This is the only OI tool classified as a write tool. Every other OI tool, including operational_insights_cancel_async_query and query execution, only needs couchbase-mcp:read.

Mint a token carrying couchbase-mcp:write if the agent needs to create indexes.

operational_insights_create_index rejected even with both scopes

Read-only mode is on, so the server does not load this tool when CB_MCP_READ_ONLY_MODE=true.

Set CB_MCP_READ_ONLY_MODE=false (or --read-only-mode=false) and confirm the token has couchbase-mcp:write.

Couchbase-layer errors (after OAuth succeeds)

These appear after the JWT validated and the scope check passed — they come from the Operational Insights cluster itself or its RBAC, not the OAuth layer.

Symptom Meaning Fix

Authentication fails against the Operational Insights cluster

CB_OPERATIONAL_INSIGHTS_USERNAME/CB_OPERATIONAL_INSIGHTS_PASSWORD (or client certificate) do not authenticate against CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING.

Verify the credentials directly against the Operational Insights cluster. Check the connection scheme (http:// vs https://) and reachability.

Server fails to start with a connection configuration error

The server started without complete Operational Insights connection settings.

Set CB_OPERATIONAL_INSIGHTS_CONNECTION_STRING and either CB_OPERATIONAL_INSIGHTS_USERNAME/CB_OPERATIONAL_INSIGHTS_PASSWORD or the CB_OPERATIONAL_INSIGHTS_CLIENT_CERT_* settings.

Reads succeed but writes fail

The Operational Insights user lacks RBAC write permission on the target database.

RBAC is the ultimate authority — even a valid couchbase-mcp:write token cannot exceed the server’s cluster credentials. Grant the needed privilege on the target database.

Logging Issues

The MCP server’s own logging is configured at startup through environment variables or CLI flags — see Logging for the full configuration reference. Every start emits one INFO boot summary line reporting the resolved configuration: the level in effect, which sinks are live, and the exact file paths being written. For example:

2026-06-29T18:08:49+0530 - couchbase - INFO - Logging configured: level=INFO, sinks=stderr,file, log_files={'INFO': 'mcp_server_operational_insights.info.log', 'WARNING': 'mcp_server_operational_insights.warning.log', 'ERROR': 'mcp_server_operational_insights.error.log'}, max_bytes=1048576

When logging behaves unexpectedly, read this line first — then work through the following table.

Symptom Likely cause Fix

No log files anywhere

The file sink is not enabled — the default is stderr only.

Set CB_MCP_LOG_SINKS=stderr,file (or --log-sinks file). Confirm via the boot summary line.

Files exist but one stays empty

Each level’s file is filtered to exactly its level, so an idle server may legitimately have an empty warning/error file.

This is expected. The info file should grow during normal use. If it does not, recheck the level and sinks in the boot line.

A per-level file I expected is missing (for example, no debug file, or no info/warning file)

That level is below the configured threshold — a file is created only for levels at or above CB_MCP_LOG_LEVEL.

Lower the level to include it: --log-level=debug produces all four files. At warning, only the warning + error files exist.

Server logged "File logging is disabled…" warning

The file sink was not requested, so support files are not being persisted.

Expected when running stderr-only. Add file to --log-sinks if you need persisted logs.

I set a log level and nothing changed

An invalid level value silently fell back to info.

Check the boot output for Ignored invalid log level …. Valid values are off/debug/info/warning/error.

A sink I configured is being ignored

An unrecognized --log-sinks token was dropped.

Look for Ignored invalid log sink value(s) … at startup. Valid tokens are stderr and file only.

I set a rotation size to 0 and got a warning

0 is not a valid rotation size — this applies to CB_MCP_LOG_ROTATION_MAX_SIZE_MB, any per-level override, and the deprecated CB_MCP_LOG_MAX_BYTES. Both variables route through the same resolver.

The server logs a warning and falls back to the 1 MB default. You can’t disable rotation this way. To control disk usage, adjust CB_MCP_LOG_RETENTION_BACKUP_COUNT and CB_MCP_LOG_ROTATION_MAX_SIZE_MB (globally or per level) instead — see Per-Level Overrides.

Startup warning: CB_MCP_LOG_MAX_BYTES is deprecated

You’re using the deprecated byte-based size variable.

Switch to CB_MCP_LOG_ROTATION_MAX_SIZE_MB (megabytes, not bytes). If both are set, the new variable wins and the old one is ignored.

ERROR lines I want to suppress keep appearing

ERROR cannot be raised away — only off silences it.

Set CB_MCP_LOG_LEVEL=off to silence everything (understanding you lose error visibility too).

An ERROR line has no stack trace

Stack traces are emitted at DEBUG, by design — ERROR stays a clean one-liner.

Re-run at --log-level=debug to capture the traceback for the same failure.

No logs at all from the server

Either --log-level=off, or you’re looking in the wrong place (the client captures stderr).

Confirm the boot line appears. For stdio clients, see the Checking Logs section later in this page for client log locations.

mcp_server_operational_insights_config.log.json is missing or looks stale

The file sink is not enabled, or the server has not restarted since a configuration change.

This file captures resolved environment/system info. It’s written only when the file sink is active. It’s overwritten on every start and never rotates. Restart the server after any configuration change to refresh it.

Checking Logs

To configure the MCP server’s own logs — log level, console/file output, and file logging for support — see Logging.

The MCP client also keeps its own logs. Check the MCP client logs for errors or warnings:

Client Log Location

Claude Desktop

~/Library/Logs/Claude (macOS), %APPDATA%\Claude\Logs (Windows)

Cursor

Bottom panel > Output > "Cursor MCP"

Windsurf

Check Windsurf output panel

VS Code

Command Palette > "MCP: List Servers" > Show Output

JetBrains

Help > Show Log in Finder/Explorer > mcp > couchbase

Factory

~/.factory/logs/ (macOS)