### Start server with various options Source: https://opentabs.dev/docs/reference/cli Examples of starting the server with default port, custom port, background mode, and stdio transport. ```bash # Start on default port opentabs start # Custom port opentabs start --port 3000 # Start in the background (use opentabs stop to stop) opentabs start --background # Auto-start via stdio (for MCP clients that manage server lifecycle) opentabs start --stdio ``` -------------------------------- ### Install plugin globally and start server Source: https://opentabs.dev/docs/guides/plugin-development Users install the plugin globally with npm install -g and then start the server with opentabs start. The MCP server auto-discovers packages matching opentabs-plugin-* in global node_modules. ```bash npm install -g opentabs-plugin-my-app opentabs start ``` -------------------------------- ### Search, list, and install plugins Source: https://opentabs.dev/docs/reference/cli Examples of searching for plugins, listing all plugins, and installing a discovered plugin globally to enable auto-discovery. ```bash # Search for plugins opentabs plugin search slack # List all available plugins opentabs plugin search # Install a discovered plugin npm install -g opentabs-plugin-slack ``` -------------------------------- ### Install plugins using shorthand, full, and scoped names Source: https://opentabs.dev/docs/reference/cli Examples of installing a plugin using shorthand, full package name, and scoped community package. ```bash # Install using shorthand opentabs plugin install slack # Install using full package name opentabs plugin install opentabs-plugin-slack # Install a scoped community plugin opentabs plugin install @my-org/opentabs-plugin-custom ``` -------------------------------- ### Install an OpenTabs plugin Source: https://opentabs.dev/docs/quick-start Installs a specific plugin, for example 'slack'. ```bash opentabs plugin install slack ``` -------------------------------- ### List plugins with JSON output Source: https://opentabs.dev/docs/reference/cli Examples of listing all installed plugins and producing machine-readable JSON output. ```bash # List all installed plugins opentabs plugin list # Machine-readable output opentabs plugin list --json ``` -------------------------------- ### Start the OpenTabs server Source: https://opentabs.dev/docs/quick-start Starts the OpenTabs server. On first run, it creates ~/.opentabs/, generates an auth secret, installs Chrome extension files, and prints config blocks for MCP clients. ```bash opentabs start ``` -------------------------------- ### onToolInvocationStart implementation example Source: https://opentabs.dev/docs/sdk/lifecycle-hooks Example implementation of onToolInvocationStart that logs the tool name before execution. The toolName parameter is the unprefixed tool name. ```typescript class MyPlugin extends OpenTabsPlugin { override onToolInvocationStart(toolName: string) { log.info(`Starting tool: ${toolName}`); } // ... abstract properties and methods } ``` -------------------------------- ### fetchFromPage usage example Source: https://opentabs.dev/docs/sdk/utilities Shows how to make a GET request with page cookies and a POST request with a custom timeout. The POST example sets Content-Type to application/json and uses a timeout of 60,000 ms. ```typescript // GET request with page cookies const response = await fetchFromPage('/api/users'); const users = await response.json(); // POST with custom timeout const response = await fetchFromPage('/api/export', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ format: 'csv' }), timeout: 60_000, }); ``` -------------------------------- ### Search and install OpenTabs plugins Source: https://opentabs.dev/docs/install Commands to search for and install OpenTabs plugins. ```bash opentabs plugin search opentabs plugin install ``` -------------------------------- ### opentabs tool list examples Source: https://opentabs.dev/docs/reference/cli Examples of listing all tools, filtering by plugin, and outputting full schemas as JSON. The --json flag is useful for programmatic consumption. ```bash # List all tools opentabs tool list # Filter to one plugin opentabs tool list --plugin slack # Full schemas as JSON opentabs tool list --json ``` -------------------------------- ### Clone and Install Dependencies Source: https://opentabs.dev/docs/contributing/dev-setup Clones the OpenTabs repository and installs dependencies. The npm install command resolves platform packages via the workspaces field in the root package.json. Plugins in plugins/ are standalone with their own node_modules and are not part of the workspace. ```bash git clone https://github.com/opentabs-dev/opentabs.git cd opentabs npm install ``` -------------------------------- ### Install the OpenTabs CLI Source: https://opentabs.dev/docs/quick-start Install the OpenTabs CLI globally using npm. Requires Node.js 22+. ```bash npm install -g @opentabs-dev/cli ``` -------------------------------- ### opentabs tool schema examples Source: https://opentabs.dev/docs/reference/cli Examples of retrieving schemas for specific tools. Returns the tool's name, description, and full JSON Schema for input parameters. ```bash opentabs tool schema slack__send_message opentabs tool schema browser_list_tabs ``` -------------------------------- ### OpenTabs configuration example Source: https://opentabs.dev/docs/reference/configuration Example configuration for OpenTabs. Defines local plugins, permissions for Slack and browser tools, and settings for Jira. The permissions use 'ask', 'auto', and 'off' levels. ```json { "localPlugins": [ "../plugins/my-plugin", "/Users/you/projects/opentabs-plugin-jira" ], "permissions": { "slack": { "permission": "ask", "tools": { "send_message": "auto", "delete_message": "off" } }, "browser": { "permission": "ask", "tools": { "browser_screenshot_tab": "auto", "browser_execute_script": "off" } } }, "settings": { "jira": { "instanceUrl": { "prod": "https://mycompany.atlassian.net" } } } } ``` -------------------------------- ### CLI mode commands for tool discovery and invocation Source: https://opentabs.dev/docs/reference/mcp-server Bash commands for using the `opentabs` CLI to list tools, view schemas, and call tools. Requires the server running via `opentabs start`. Includes examples for listing all tools, filtering by plugin, viewing a schema, and calling a tool with JSON arguments. ```bash # Discover tools opentabs tool list opentabs tool list --plugin slack # View a tool's input schema opentabs tool schema slack__send_message # Call a tool opentabs tool call slack__send_message '{"channel":"C123","text":"hello"}' ``` -------------------------------- ### opentabs config set examples Source: https://opentabs.dev/docs/reference/cli Examples of setting various configuration values: tool permissions, plugin permissions, server port, and local plugin paths. The --force flag allows adding paths that do not yet exist. ```bash # Set a tool to auto-approve (no confirmation prompt) opentabs config set tool-permission.slack.send_message auto # Disable a tool entirely opentabs config set tool-permission.slack.send_message off # Set a plugin default to require approval for all its tools opentabs config set plugin-permission.slack ask # Change the server port opentabs config set port 3000 # Register a local plugin opentabs config set localPlugins.add /path/to/my-plugin # Register a local plugin path that does not yet exist opentabs config set localPlugins.add /future/path/my-plugin --force # Unregister a local plugin opentabs config set localPlugins.remove /path/to/my-plugin ``` -------------------------------- ### Example dev server output Source: https://opentabs.dev/docs/contributing/dev-setup Shows the labeled output from the three processes when running npm run dev: tsc reports 0 errors, extension rebuilds and installs, and MCP server runs on http://localhost:9515. ```bash [tsc] Found 0 errors. Watching for file changes. [ext] Rebuilding extension... [ext] Extension built and installed. [mcp] MCP server running on http://localhost:9515 ``` -------------------------------- ### Start the MCP server in production mode Source: https://opentabs.dev/docs/reference/cli Starts the MCP server in production mode. Options include `--port`, `--background`, `--show-config`, and `--stdio`. ```bash opentabs start [options] ``` -------------------------------- ### opentabs doctor usage examples Source: https://opentabs.dev/docs/reference/cli Examples of running the opentabs doctor command, including with a custom port. ```bash opentabs doctor opentabs doctor --port 3000 ``` -------------------------------- ### isReady() example implementation Source: https://opentabs.dev/docs/sdk/plugin-class Example implementation of isReady() that checks for an auth token stored on the page global. Returns true if the token exists, false otherwise. ```typescript async isReady(): Promise { // Check for an auth token that the app stores on login const token = getPageGlobal('__APP__.authToken') as string | undefined; return token !== undefined; } ``` -------------------------------- ### opentabs logs usage examples Source: https://opentabs.dev/docs/reference/cli Examples of using opentabs logs with various options: show recent lines, follow in real time, specify line count, and filter by plugin. ```bash # Show recent log lines and exit opentabs logs # Follow logs in real time opentabs logs --follow # Show last 100 lines and follow opentabs logs --lines 100 -f # Show only Slack plugin logs opentabs logs --plugin slack ``` -------------------------------- ### Example: sendMessage tool using defineTool Source: https://opentabs.dev/docs/sdk/tools Complete example of a tool that sends a Slack message. Imports from '@opentabs-dev/plugin-sdk', uses zod for input/output validation, and throws ToolError.internal on failure. ```typescript import { defineTool, postJSON, ToolError } from '@opentabs-dev/plugin-sdk'; import type { ToolHandlerContext } from '@opentabs-dev/plugin-sdk'; import { z } from 'zod'; export const sendMessage = defineTool({ name: 'send_message', displayName: 'Send Message', description: 'Send a message to a Slack channel by name or ID.', icon: 'message-square', input: z.object({ channel: z.string().describe('Channel name or ID'), text: z.string().describe('Message text'), }), output: z.object({ ok: z.boolean(), ts: z.string().describe('Message timestamp ID'), }), async handle(params, context?: ToolHandlerContext) { const result = await postJSON<{ ok: boolean; ts: string }>( '/api/chat.postMessage', { channel: params.channel, text: params.text }, ); if (!result || !result.ok) { throw ToolError.internal('Failed to send message'); } return { ok: result.ok, ts: result.ts }; }, }); ``` -------------------------------- ### opentabs plugin install Source: https://opentabs.dev/docs/reference/cli Install a plugin from npm. Alias: opentabs plugin add. The name can be shorthand, full package name, or scoped package. Shorthand resolves to @opentabs-dev/opentabs-plugin-slack first, then opentabs-plugin-slack. Runs npm install -g and notifies the MCP server via POST /reload if running. ```bash opentabs plugin install ``` -------------------------------- ### Build Slack plugin Source: https://opentabs.dev/docs/contributing/dev-setup Install dependencies and build the Slack plugin, which provides more tools. ```bash cd plugins/slack npm install npm run build ``` -------------------------------- ### Start OpenTabs dev server Source: https://opentabs.dev/docs/install Starts the MCP server with the dev proxy for hot reload. Rebuilding platform packages automatically restarts the worker process. ```bash npm run dev ``` -------------------------------- ### onNavigate implementation example Source: https://opentabs.dev/docs/sdk/lifecycle-hooks Example implementation of onNavigate that extracts a project ID from the URL using a regular expression. The hook receives the new URL (window.location.href) after navigation. ```typescript class MyPlugin extends OpenTabsPlugin { private currentProjectId: string | null = null; override onNavigate(url: string) { // Track which project the user is viewing const match = url.match(/\/projects\/(\w+)/); this.currentProjectId = match?.[1] ?? null; } // ... abstract properties and methods } ``` -------------------------------- ### opentabs plugin configure jira Source: https://opentabs.dev/docs/reference/cli Example of configuring the jira plugin interactively. ```bash opentabs plugin configure jira ``` -------------------------------- ### opentabs config show examples Source: https://opentabs.dev/docs/reference/cli Examples of the opentabs config show command: default output, JSON output, and showing the secret. The secret is redacted by default unless --show-secret is used. ```bash opentabs config show opentabs config show --json opentabs config show --show-secret ``` -------------------------------- ### opentabs tool call examples Source: https://opentabs.dev/docs/reference/cli Examples of calling tools with no arguments, with JSON arguments, using --params, and targeting a specific tab with --tab-id. The --params flag takes precedence over the positional JSON argument. ```bash # Call a tool with no arguments opentabs tool call browser_list_tabs # Call with JSON arguments opentabs tool call slack__send_message '{"channel":"C123","text":"hello"}' # Use --params flag instead opentabs tool call slack__send_message --params '{"channel":"C123","text":"hello"}' # Target a specific tab opentabs tool call slack__send_message '{"channel":"C123","text":"hi"}' --tab-id 42 ``` -------------------------------- ### getConfig usage example Source: https://opentabs.dev/docs/sdk/utilities Example of using getConfig to read a plugin setting, importing from the SDK and casting the result. The key must match a field name in the plugin's configSchema. ```typescript import { getConfig } from '@opentabs-dev/plugin-sdk'; const instanceUrl = getConfig('instanceUrl') as string | undefined; ``` -------------------------------- ### onActivate() implementation example Source: https://opentabs.dev/docs/sdk/lifecycle-hooks TypeScript class implementing onActivate() to set up a keyboard shortcut listener and clean it up in onDeactivate(). The example shows the use of the 'override' keyword, which is required because the scaffolded tsconfig.json enables noImplicitOverride. ```typescript class MyPlugin extends OpenTabsPlugin { private cleanup?: () => void; override onActivate() { // Set up a keyboard shortcut listener const handler = (e: KeyboardEvent) => { if (e.key === 'Escape') { // Handle escape key } }; document.addEventListener('keydown', handler); this.cleanup = () => document.removeEventListener('keydown', handler); } override onDeactivate() { this.cleanup?.(); } // ... abstract properties and methods } ``` -------------------------------- ### onToolInvocationEnd implementation example Source: https://opentabs.dev/docs/sdk/lifecycle-hooks Example implementation of onToolInvocationEnd that logs warnings for failures or slow tools. The success parameter is true if handle() resolved, false if it threw. The durationMs is wall-clock time in milliseconds. ```typescript class MyPlugin extends OpenTabsPlugin { override onToolInvocationEnd(toolName: string, success: boolean, durationMs: number) { if (!success) { log.warn(`Tool ${toolName} failed after ${durationMs}ms`); } else if (durationMs > 5000) { log.warn(`Tool ${toolName} took ${durationMs}ms — consider adding progress reporting`); } } // ... abstract properties and methods } ``` -------------------------------- ### Install plugin developer CLI Source: https://opentabs.dev/docs/reference/cli Installs the `opentabs-plugin` CLI globally via npm. Alternatively, it can be used as a local dev dependency via `npm run build` inside a plugin project scaffolded from `@opentabs-dev/create-plugin`. ```bash npm install -g @opentabs-dev/plugin-tools ``` -------------------------------- ### Example tool call with both parameters Source: https://opentabs.dev/docs/reference/mcp-server Demonstrates calling a plugin tool with both `instance` and `tabId` parameters. `instance` selects the target site, `tabId` targets a specific browser tab. ```json { "name": "jira_list_issues", "arguments": { "instance": "work", "tabId": 42, "project": "PLAT" } } ``` -------------------------------- ### opentabs stop usage examples Source: https://opentabs.dev/docs/reference/cli Examples of using 'opentabs stop' with and without the --port option. The command stops the server, waits up to 5 seconds for exit, and cleans up the PID file. If the server was not started with --background, it cannot be stopped this way. ```bash opentabs stop opentabs stop --port 3000 ``` -------------------------------- ### postJSON usage examples Source: https://opentabs.dev/docs/sdk/utilities Shows two usage patterns: a simple POST with type cast, and a POST with Zod schema validation. The Zod example imports z from 'zod', defines a schema, and passes it to postJSON to get a runtime-validated typed result. ```typescript const result = await postJSON<{ ok: boolean }>('/api/messages', { channel: 'general', text: 'Hello from OpenTabs!', }); // With Zod schema validation import { z } from 'zod'; const responseSchema = z.object({ ok: z.boolean(), ts: z.string() }); const result = await postJSON('/api/messages', { channel: 'general', text: 'Hi!' }, undefined, responseSchema); // result is typed as { ok: boolean; ts: string } — validated at runtime ``` -------------------------------- ### fetchJSON usage examples Source: https://opentabs.dev/docs/sdk/utilities Shows two usage patterns: a simple type cast without validation, and a type-safe usage with Zod schema validation. The Zod example imports z from 'zod', defines a schema, and passes it to fetchJSON to get a runtime-validated typed result. ```typescript // Simple usage with type cast interface Channel { id: string; name: string } const channels = await fetchJSON('/api/channels'); // Type-safe usage with Zod schema validation import { z } from 'zod'; const channelSchema = z.object({ id: z.string(), name: z.string() }); const channels = await fetchJSON('/api/channels', undefined, z.array(channelSchema)); // channels is typed as { id: string; name: string }[] — validated at runtime ``` -------------------------------- ### Build and publish plugin to npm Source: https://opentabs.dev/docs/guides/plugin-development Commands to build and publish the plugin. Run npm run build first, then npm publish. ```bash npm run build npm publish ``` -------------------------------- ### Example settings for Jira plugin with multiple instances Source: https://opentabs.dev/docs/reference/mcp-server Shows a user's `settings` configuration mapping instance names to URLs. When a plugin has two or more instances, the platform injects a required `instance` enum parameter into every tool's schema. ```json { "settings": { "jira": { "instanceUrl": { "work": "https://acme.atlassian.net", "personal": "https://me.atlassian.net" } } } } ``` -------------------------------- ### Verify OpenTabs installation Source: https://opentabs.dev/docs/install Commands to check the status of the OpenTabs installation and run diagnostics. ```bash opentabs status opentabs doctor ``` -------------------------------- ### Generate, preview, and check README Source: https://opentabs.dev/docs/reference/cli Shows the three readme invocations: generating `README.md`, previewing with `--dry-run`, and checking with `--check` for CI. ```bash # Generate README.md opentabs-plugin readme # Preview without writing opentabs-plugin readme --dry-run # Check if README is up to date (for CI) opentabs-plugin readme --check ``` -------------------------------- ### Build the plugin with npm run build Source: https://opentabs.dev/docs/first-plugin Compiles the plugin, generates the adapter bundle and tool manifest, and notifies the running MCP server. No restart is needed. ```bash npm run build ``` -------------------------------- ### waitForSelector usage examples Source: https://opentabs.dev/docs/sdk/utilities Examples of waiting for elements: one with default options and one with a custom timeout of 3000ms. ```typescript // Wait for the dashboard to load before interacting const dashboard = await waitForSelector('.dashboard-loaded'); // Short timeout for elements that should appear quickly const header = await waitForSelector('#app-header', { timeout: 3000 }); ``` -------------------------------- ### sleep usage examples with cancellation Source: https://opentabs.dev/docs/sdk/utilities Two usage examples for sleep: one waits 2 seconds between operations, and another demonstrates cancelling a sleep early with an AbortSignal. The second example shows that the sleep resolves or rejects after approximately 1 second when aborted. ```typescript // Wait 2 seconds between operations await doFirstThing(); await sleep(2000); await doSecondThing(); // Cancel a sleep early with an AbortSignal const controller = new AbortController(); setTimeout(() => controller.abort(), 1000); await sleep(5000, { signal: controller.signal }); // resolves/rejects after ~1s ``` -------------------------------- ### Build once and watch Source: https://opentabs.dev/docs/reference/cli Shows the two common build invocations: building once and watching for changes with `--watch`. The watch mode rebuilds automatically when files in `dist/` change. ```bash # Build once opentabs-plugin build # Watch and rebuild on changes opentabs-plugin build --watch ``` -------------------------------- ### waitUntil usage examples with polling and cancellation Source: https://opentabs.dev/docs/sdk/utilities Three usage examples for waitUntil: waiting for a page global, waiting for an element's content, and cancelling polling after 5 seconds with an AbortSignal. The examples show default interval and timeout, custom interval and timeout, and signal-based cancellation. ```typescript // Wait for a page global to be set await waitUntil(() => getPageGlobal('App.ready') === true); // Wait for an element to have specific content await waitUntil( () => getTextContent('.status-badge') === 'Connected', { interval: 500, timeout: 15_000 }, ); // Cancel polling after 5 seconds const controller = new AbortController(); setTimeout(() => controller.abort(), 5000); await waitUntil( () => getTextContent('.status') === 'Ready', { signal: controller.signal }, ); ``` -------------------------------- ### onToolInvocationStart(toolName) Source: https://opentabs.dev/docs/sdk/lifecycle-hooks Called before each tool.handle() execution. Receives the unprefixed tool name (e.g., 'send_message', not 'slack__send_message'). ```APIDOC ## onToolInvocationStart(toolName) ### Description Called before each `tool.handle()` execution. Receives the unprefixed tool name (e.g., `'send_message'`, not `'slack__send_message'`). ### Method onToolInvocationStart ### Signature ```typescript onToolInvocationStart?(toolName: string): void; ``` ### Parameters - **toolName** (string) - Required - The unprefixed tool name. ### Example ```typescript class MyPlugin extends OpenTabsPlugin { override onToolInvocationStart(toolName: string) { log.info(`Starting tool: ${toolName}`); } // ... abstract properties and methods } ``` ``` -------------------------------- ### Run OpenTabs diagnostic and status commands Source: https://opentabs.dev/docs/reference/troubleshooting Use `opentabs doctor` for a full setup diagnostic and `opentabs status` to check server status, plugins, tab states, and tool counts. These are the first commands to run when something breaks. ```bash opentabs doctor opentabs status ``` -------------------------------- ### Browser permission configuration example Source: https://opentabs.dev/docs/reference/configuration Uses the special plugin key 'browser' to set browser tools to ask by default, auto-approve browser_screenshot_tab, and disable browser_execute_script. ```json { "permissions": { "browser": { "permission": "ask", "tools": { "browser_screenshot_tab": "auto", "browser_execute_script": "off" } } } } ``` -------------------------------- ### opentabs config rotate-secret example Source: https://opentabs.dev/docs/reference/cli Example of rotating the secret with the required --confirm flag. The server notifies the Chrome extension via WebSocket, and the extension auto-reconnects with the new secret. ```bash # Rotate the secret opentabs config rotate-secret --confirm ``` -------------------------------- ### opentabs plugin list [options] Source: https://opentabs.dev/docs/reference/cli List installed plugins. Works in online mode (fetches from running server) and offline mode (reads from config and global npm packages). Alias: opentabs plugin ls. Options include --json, --port (default 9515), and -v/--verbose. ```bash opentabs plugin list [options] ``` -------------------------------- ### fetchText usage examples Source: https://opentabs.dev/docs/sdk/utilities Fetches raw text content such as diffs, logs, or plain-text API responses. The second example shows fetching a job log with a custom timeout of 60 seconds. ```typescript // Fetch raw text content — diffs, logs, plain-text API responses const diff = await fetchText('/api/pull-requests/42/diff'); // Fetch a job log with a custom timeout const log = await fetchText('/api/jobs/123/log', { timeout: 60_000 }); ``` -------------------------------- ### Build e2e-test plugin Source: https://opentabs.dev/docs/contributing/dev-setup Install dependencies and build the e2e-test plugin. The build command auto-registers the plugin in ~/.opentabs/config.json and calls POST /reload to notify the running MCP server. ```bash cd plugins/e2e-test npm install npm run build ``` -------------------------------- ### Inspect manifest pretty and JSON Source: https://opentabs.dev/docs/reference/cli Shows the two inspect invocations: pretty-printing the manifest and outputting raw JSON with `--json`. ```bash # Pretty-print the manifest opentabs-plugin inspect # Output raw JSON opentabs-plugin inspect --json ``` -------------------------------- ### getPageGlobal usage example Source: https://opentabs.dev/docs/sdk/utilities Example of using getPageGlobal to access deeply nested page globals, casting the result to the expected type. Shows how to retrieve an API token, user ID, and feature flags from globalThis. ```typescript // Access deeply nested page globals safely const token = getPageGlobal('TS.boot_data.api_token') as string | undefined; const userId = getPageGlobal('App.currentUser.id') as number | undefined; const config = getPageGlobal('__APP_CONFIG__.features') as Record | undefined; ``` -------------------------------- ### teardown() implementation example Source: https://opentabs.dev/docs/sdk/lifecycle-hooks TypeScript class implementing teardown() to clean up a global handle and polling interval set up in onActivate(). The example shows the use of the 'override' keyword, which is required because the scaffolded tsconfig.json enables noImplicitOverride. ```typescript class MyPlugin extends OpenTabsPlugin { private _pollInterval?: ReturnType; override onActivate() { // Expose a global handle and start polling (window as Record).__myPlugin = { active: true }; this._pollInterval = setInterval(() => { // poll for updates }, 5000); } override teardown() { // Clean up before the new adapter version is injected clearInterval(this._pollInterval); delete (window as Record).__myPlugin; } // ... abstract properties and methods } ``` -------------------------------- ### Update OpenTabs CLI Source: https://opentabs.dev/docs/reference/cli Checks the installed version against the latest published version on npm and runs `npm install -g @opentabs-dev/cli@` if an update is available. If the MCP server is running, it needs to be restarted to use the new version. ```bash opentabs update ``` -------------------------------- ### Scaffold plugin with npm create convention Source: https://opentabs.dev/docs/guides/plugin-development Use npm create to scaffold a plugin with @opentabs-dev/plugin. Equivalent to the npx command. ```bash npm create @opentabs-dev/plugin my-app -- --domain .example.com --display "My App" ```