Skip to main content

Troubleshooting

First steps

When something breaks, these two commands tell me most of what I need to know — they'll do the same for you:

# Full setup diagnostic — checks runtime, config, server, extension, plugins
opentabs doctor
 
# Server status — shows plugins, tab states, tool counts
opentabs status

If the server isn't running, start it with opentabs start.


Extension not connecting

Symptom: The side panel shows "Disconnected" or opentabs status reports Extension: not connected.

  1. Server running? — Run opentabs status. If the server is not running, start it with opentabs start.
  2. Correct port? — Default is 9515. If using a custom port, make sure the extension is configured for the same one.
  3. Extension loaded? — Open chrome://extensions and verify OpenTabs is loaded and enabled. Click any error link for details.
  4. Version mismatch? — Run opentabs doctor. A mismatch between the installed extension and CLI version can cause failures. Restart opentabs start to auto-update the extension files, then reload the extension from chrome://extensions.
  5. Stale secret? — The extension reads the auth secret from ~/.opentabs/extension/auth.json (written by the server on startup). If the secret changed (e.g., after deleting auth.json or rotating the secret with opentabs config rotate-secret --confirm), restart the server with opentabs start to regenerate the file, then reload the extension from chrome://extensions.

Extension reconnection delays

Symptom: After the server restarts, the extension takes several seconds to reconnect.

The extension uses exponential backoff: 1s, 2s, 4s, 8s, up to a 30-second cap. Backoff resets after a successful connection. To force an immediate reconnect, close and reopen the side panel.


Plugin showing as "unavailable"

Symptom: opentabs status shows a plugin as "unavailable". Tool calls to this plugin fail.

A plugin is unavailable when a matching tab exists but isReady() returns false — usually because the user is not logged in.

  1. Log in — Sign into the target web app. The extension re-probes isReady() on navigation and tab events.
  2. Refresh the tab — A fresh page load may be needed to detect the authentication state.
  3. Check isReady() logic — Verify it checks the right signal (localStorage token, DOM element, cookie). The probe has a 5-second timeout.

Plugin showing as "closed"

Symptom: opentabs status shows a plugin as "closed".

A plugin is closed when no Chrome tab matches its URL patterns.

  1. Open the target web app — Navigate to a URL matching the plugin's urlPatterns.
  2. Check URL patterns — Verify the opentabs.urlPatterns field in package.json uses valid Chrome match pattern syntax.
  3. Multiple windows — The extension searches across all Chrome windows.

Tool dispatch timeout

Symptom: Tool calls fail after ~30 seconds.

CauseSolution
handle() takes too longAdd progress reporting to extend the timeout up to 5 minutes, or break long operations into multiple tool calls.
Tab unresponsive or crashedRefresh the target tab. Check Chrome's task manager (Shift+Esc) for hung tabs.
Extension disconnected mid-callThe server detects this and returns an error. Reconnect the extension.
Network request in handle() stalledUse the SDK's fetchFromPage() or fetchJSON() which have built-in 30-second timeouts.

Use opentabs audit to see recent tool invocations with their durations and error details.


MCP client cannot connect

Symptom: Claude Code, Cursor, or another MCP client reports a connection or authentication error.

  1. Server running?opentabs status or curl http://127.0.0.1:9515/health
  2. Correct URL — The endpoint is http://127.0.0.1:9515/mcp (not /ws or /)
  3. Auth tokenAuthorization: Bearer <secret> must match the secret in ~/.opentabs/extension/auth.json. Get it with:
    opentabs config show --json --show-secret | jq -r .secret
  4. Client config — For Claude Code, verify your MCP config has "type": "streamable-http" and the correct URL and Authorization header
  5. CORS — The server rejects requests with a browser Origin header. Native MCP clients don't send Origin headers, so this should only affect browser-based testing.

Plugin changes not picked up

Symptom: After rebuilding a plugin, the server still serves old tool definitions.

The opentabs-plugin build command calls POST /reload automatically. If the server didn't pick up changes:

  1. Check the build — Verify that dist/tools.json and dist/adapter.iife.js exist in the plugin directory.
  2. Check server logsopentabs logs shows recent server activity, including reload events.
  3. Manual reload — Call the reload endpoint directly:
    curl -X POST http://127.0.0.1:9515/reload \
      -H "Authorization: Bearer $(opentabs config show --json --show-secret | jq -r .secret)"
  4. Verify via statusopentabs status shows the current plugin list and tool counts.

Extension changes not taking effect

Symptom: After modifying extension source and rebuilding, behavior is unchanged.

The Chrome extension does not auto-reload. After rebuilding:

  1. Open chrome://extensions
  2. Find the OpenTabs card and click the circular refresh icon
  3. Close and reopen the side panel

Side panel not updating

Symptom: The side panel shows stale data (wrong plugins, old tab states).

  1. Close and reopen — Right-click the extension icon and select "Open side panel"
  2. Reload the extension — From chrome://extensions, click the refresh icon
  3. Check server connection — If "Disconnected", see Extension not connecting

Build failures

ErrorCauseSolution
TypeScript errorsType mismatches or missing typesRun npm run type-check for details and fix the errors.
Zod schema serialization.transform(), .pipe(), or .preprocess() in tool schemasMove the logic to handle() — transforms can't be serialized to JSON Schema. See the Plugin Development guide for details.
Plugin name validationName has invalid characters or is reservedNames must match ^[a-z0-9]+(-[a-z0-9]+)*$ (lowercase alphanumeric segments separated by single hyphens) and not be reserved (e.g., browser, extension).
Missing dependencies@opentabs-dev/plugin-sdk not installedRun npm install in the plugin directory.

Diagnostic commands

CommandWhat it does
opentabs doctorFull setup diagnostic — runtime, config, server, extension, plugins.
opentabs statusServer health, plugin list, tab states, tool counts.
opentabs auditRecent tool invocation history with durations and errors.
opentabs logsTail the MCP server log in real time.
opentabs logs --plugin <name>Show only logs from a specific plugin.
opentabs config showView current configuration (secret redacted).
curl http://127.0.0.1:9515/healthDirect health check (no CLI needed). Without a Bearer token, returns only {"status": "ok"}. Pass -H "Authorization: Bearer <secret>" for the full payload including version and extensionConnected.

Last Updated: 10 Mar, 2026