Skip to main content
Glama
customaise

customaise

Official

@customaise/mcp

MCP server and CLI that connect AI coding agents to the Customaise Chrome extension. Manage UserScripts, build AgentScripts, call WebMCP tools inside the user's signed-in browser session, select DOM elements visually, and drive tabs. Drive it over stdio from an IDE, or as a customaise command from a shell.

21 tools, 5 resources plus a script resource template, WebSocket bridge between your agent and a real Chrome session, whichever door it arrives through.

Two ways in. customaise-mcp is the MCP server an IDE spawns over stdio. customaise is a CLI for agents that have a shell instead, driving the same tools through a resident daemon. Both go through the same cap enforcement and the same consent gate.

AI Agent ←(stdio)→ MCP Server ←(WebSocket)→ Customaise Extension

Speaks the MCP 2026-07-28 revision, negotiated per connection: a client on that revision gets the stateless flow with cacheable tools/list, and a client on the 2025 revisions keeps working unchanged. The package is 3.x precisely so nobody has to guess this from a 2.x version number.

Quick Start

1. Install Customaise

Install the Customaise Chrome extension on Chrome 147 or later, sign in, and turn on Agent Bridge in Settings → MCP & Terminal. Chrome 147 is the tested release baseline for extension 1.3.9.

2. Add to your IDE

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "customaise": {
      "command": "npx",
      "args": ["-y", "@customaise/mcp"]
    }
  }
}

Claude Code (one command, no file to edit):

claude mcp add customaise -- npx -y @customaise/mcp

Claude Desktop: install customaise.mcpb from the latest release. The bundle returns page content inline, which a chat client needs (see Chat clients and file-less agents). Or add it to claude_desktop_config.json with the same setting:

{
  "mcpServers": {
    "customaise": {
      "command": "npx",
      "args": ["-y", "@customaise/mcp"],
      "env": { "CUSTOMAISE_MCP_OUTPUT": "inline" }
    }
  }
}

Kiro (.kiro/mcp.json):

{
  "mcpServers": {
    "customaise": {
      "command": "npx",
      "args": ["-y", "@customaise/mcp"]
    }
  }
}

Codex (~/.codex/config.toml):

[mcp_servers.customaise]
command = "npx"
args = ["-y", "@customaise/mcp"]

Antigravity (mcp_config.json):

{
  "mcpServers": {
    "customaise": {
      "command": "npx",
      "args": ["-y", "@customaise/mcp"]
    }
  }
}

3. Done

Your agent can now read and edit UserScripts, build AgentScripts that expose WebMCP tools to it, select DOM elements visually, inspect the console, and take screenshots of the live tab.

Related MCP server: LoopIn

Tools (21)

Script Lifecycle

Tool

Description

list_scripts

List every script (UserScripts and AgentScripts) managed by the extension

import_script

Pull a script to a local file for editing

export_script

Push a local file to Customaise (validates and installs)

delete_script

Permanently delete a script

toggle_script

Enable or disable a script

Browser Context

Tool

Description

get_page_context

DOM snapshot of the current page

get_console_context

Console logs, errors, and GM_log output

list_tabs

List all open browser tabs

Tab Control

Tool

Description

open_tab

Open a new tab at a given URL

close_tab

Close a tab by ID

focus_tab

Switch focus to a tab by ID

reload_tab

Reload a tab to re-inject scripts

Visual DOM Targeting

Tool

Description

get_selected_elements

Get the DOM elements the user has visually selected, with stable, tiered selectors and screenshots

take_screenshot

Capture any tab (not just the visible one) as a viewport or full-page image

WebMCP Agent Tools

Tool

Description

list_webmcp_tools

List the WebMCP tools currently registered on a tab by AgentScripts

call_webmcp_tool

Call a WebMCP tool; prompt-gated tools block on user consent (see below)

UI Control & Batch

Tool

Description

toggle_ui

Show or hide the Customaise UI overlay

sync_scripts

Bulk export all scripts to a local directory

Script Decisions

Tool

Description

get_script_decisions

Read Script Decisions on this device: whether agents may manage it, saved provider keys, and each script's provider and state; with a script ID, its question lists and their hashes

set_script_decisions

Choose a script's provider (Jev or Decisions API) and which question lists are On, or switch it off. Needs the person to turn on Script Decisions under Full access, except off

Diagnostics

Tool

Description

get_bridge_status

Report extension attachment, plan tier, sign-in, remaining quota and the browser's agent permission mode, including whether agents may manage Script Decisions, when supported. Costs no quota itself.

Resources (5 plus a template)

Five resources and one script resource template that connected agents can read via resources/read. The two conventions handbooks define exactly how Customaise expects UserScripts and AgentScripts to be written. Agents should read the relevant handbook before touching a script.

URI

Description

customaise://scripts

Live JSON list of every script the extension manages (ID, name, enabled state, match patterns, shared flag)

customaise://scripts/{scriptId}

Full source and metadata for a specific script

customaise://conventions

Points at the right handbook for the script type you're working on

customaise://userscript-conventions

Full UserScript reference: file structure, IIFE pattern, GM_* APIs, symbol-level editing, @match and @namespace rules

customaise://agentscript-conventions

Full AgentScript reference: the // ==AgentScript== block, // @webmcp <tool> <permission> declarations, document.modelContext.registerTool(), consent model

customaise://script-decisions

Shared UserScript/AgentScript guide: Decisions API questions, the CM_decisions API, working example, device/provider setup, billing and failure handling

Script Decisions in UserScripts and AgentScripts

Script Decisions is a Power User capability and needs extension 1.3.8 or later. Read customaise://script-decisions over MCP or run:

customaise resource script-decisions

Use it for bounded text classification, relevance checks and scoring; use ordinary code for extraction, exact rules and actions. Both script engines declare @grant CM_decisions and call CM_decisions.create or createMany with Decisions API questions written out in the code. The resource contains a complete UserScript and instructions for wrapping the same helper in an AgentScript tool.

The user saves separate Jev/Decisions API keys on /account#script-decisions, enables the device in Your Devices (from another device when that browser is marked Operated by an AI agent), and selects a provider in the script's Decisions menu (its branch icon, or Quick Actions → Script Decisions). Requests then run automatically. Settings can pause the device without losing selections; Data & Analytics reports usage by device/provider. Provider charges and budgets are separate from Customaise browser AI tokens. MCP/CLI cannot supply keys or allow a device. WebMCP approval still applies independently to the containing tool.

create and createMany wait for the answers themselves. Preserve refusals and errors; do not resend uncertain work or switch providers automatically. Changing a script's code asks for its provider to be chosen again, unless an agent saved it under the grant below. See the Script Decisions guide.

Agents choosing providers

Settings → Agent permissions → Full access has a second part, Script Decisions. Only the person turns it on, through a protected confirmation in the extension; no MCP tool or CLI command can. While it is on, connected agents can choose a script's provider (Jev or Decisions API) on this device, switch its question lists On or Off, and resume a script the loop guard paused for repeating the same input (loop_repeat). Switching a script's provider off is always allowed. Provider keys, the device's Allow Script Decisions switch, daily limits, pausing the device, a runaway-loop pause (loop_runaway) and scripts shared with the person stay with the person; those refusals carry error type person_required (CLI exit 6), and the agent should tell the person the step rather than retry.

MCP

CLI

get_script_decisions({ scriptId? })

customaise decisions [id]

set_script_decisions({ scriptId, provider, sets? })

customaise decisions set <id> <jev|openai-decisions|off> [--sets HASH,HASH]

sets names the question lists to switch On by the hashes get_script_decisions returns for one script; every other list goes Off. When an agent saves a script with export_script while Script Decisions is on for agents, Customaise signs its provider again for the new code if it was current for the code just replaced, and scriptDecisions in the result says whether it was kept and, if not, why. Without the grant the person chooses the provider again after the edit. Both tools need extension 1.4.0 or later; an older extension answers extension_outdated.

Updating to MCP/CLI 3.2.9 and extension 1.4.0

The CLI and Desktop bundle ship the same tested runtime dependencies. Runtime dependencies are bundled in the npm tarball so fresh installs retain those versions. Contributors should use npm ci; dependency updates belong in package-lock.json and must pass the packaged-release checks before publication.

Update both the extension and the companion for the latest permission controls and status reporting. The npm package contains both customaise-mcp and the customaise CLI; Claude Desktop uses the matching 3.2.9 .mcpb bundle. Restart all MCP clients and any running Customaise CLI daemon after updating. Relay protocol 2 is unchanged from 3.2.3. The tool surface grows to 21 with get_script_decisions and set_script_decisions.

The AgentScript handbook now teaches document.modelContext, the WebMCP standard name that extension 1.4.0 provides; navigator.modelContext still works in every version. Both handbooks note that Chrome withholds secure-context APIs on plain http pages other than localhost, and the UserScript handbook describes @connect as 1.4.0 reads it. Read customaise://agentscript-conventions or customaise://userscript-conventions, or run customaise resource <name>, before editing a script. The migration reference covers moving a library from Tampermonkey. Customaise provides every GM API and metadata key Tampermonkey supports on Chrome.

Agent permissions and Full access

Settings → Agent permissions offers Use tool permissions (the default) and Full access. A user-confirmed Full access grant lets eligible Prompt tools run without repeated Customaise approvals in that browser profile, including new and updated tools. Saved Deny rules, undeclared tools, disabled scripts and URL restrictions still apply. Saved per-tool choices are preserved; turning Full access off restores them. The grant stays on until disabled or the user signs out, is not synced, and does not enable Chrome DevTools access. Browsers configured to accept approvals only from another device cannot enable Full access locally.

get_bridge_status and customaise doctor expose agentPermissions with mode, revision, scope, locked and scriptDecisions (whether agents may manage Script Decisions; false from an extension before 1.4.0). Older extensions may return no status. There is no MCP/CLI command to grant Full access or its Script Decisions part: the person controls both in the extension. The interactive bottom bar exposes active permissions, DevTools, bridge and sync controls; Appearance can keep them visible while off as well.

A temporary account-verification failure is reported as unknown/verifying, not a confirmed Free subscription. Calls that cannot safely verify access fail with retryable entitlement_unavailable and do not consume Free quota. Wait for verification to recover before retrying; a genuine subscription change still applies normally. Tool actions are never replayed automatically. Structured permission refusal details and CLI exit codes survive leader/follower forwarding.

Customaise also syncs explicit per-tool Allow/Prompt/Deny choices with each script. Update and finish syncing the browser holding those choices before removing its profile, and use the updated extension when restoring. Previously discarded local-only choices cannot be recovered from older cloud snapshots. Resetting a tool to its script default syncs too; older clients without this field do not erase the saved choices.

Save deadlines and recovery

export_script reports an operation ID and stages such as normalization, Monaco queue/setup, resources and persistence. The extension bounds the whole save to 90 seconds, including waiting for the offscreen document. Cancellation and transport timeouts propagate through both leader and follower processes. Work cancelled before persistence cannot later publish. Concurrent preparations and storage revisions are checked again at the commit boundary.

After a timeout, use get_bridge_status({ scriptId, operationId }), with the IDs from the error, or customaise doctor --script ID --operation ID. This authenticated read costs no quota, including when the normal quota is exhausted. committed means there is a retained commit receipt; matchesCurrentCode says whether that version remains current. not_committed identifies a known attempt that has not written. unknown means there is insufficient retained proof: inspect the current script before retrying. A submitted Chrome storage write cannot be recalled. Its receipt is stored with the script and survives a browser restart. Only the latest receipt per script is durable; recent operation stages are retained in memory for up to 15 minutes (128 entries, 32 running saves).

For edits, pass the codeHash returned by import_script as export_script.expectedCodeHash to reject a save based on an outdated import. Update all MCP processes together: internal leader/follower relay protocol 2 adds cancellation ownership. The extension wire protocol is unchanged by it; the full save contract requires extension 1.3.4.

AgentScripts register tools on web pages via document.modelContext.registerTool(...), the WebMCP standard name; navigator.modelContext, its earlier name, also works and is the one Customaise before 1.4.0 accepts. Each tool is declared in the AgentScript's // @webmcp <toolName> <permission> header with one of three permissions:

  • allow: tool executes immediately. ~50 to 100ms round-trip per call (the extension still runs permission checks).

  • prompt: in the default tool-permissions mode, each call surfaces an in-browser consent modal and blocks until the user approves or denies. User-enabled Full access lets eligible Prompt tools run without that modal; Deny rules and separate DevTools requirements still apply. Up to 5 minutes. Design for this. Don't chain prompt-gated calls in tight loops, and treat a long call_webmcp_tool as normal.

  • deny: tool is suppressed and calls fail immediately.

"Always allow" and "Always deny" buttons on the consent modal persist the decision per-script per-tool until the user resets it in extension Settings. These overrides are stored with the script and included in encrypted sync when enabled. The extension evaluates them for each call; MCP cannot set them or grant itself Full access.

Remote approvals (optional)

If the user has Power User and has enabled Remote HITL Approvals on their Customaise account page, prompt-gated calls are also mirrored there. They can approve or deny from any signed-in browser, including a phone. Either the extension modal or the remote surface can resolve; first signed decision wins. From the MCP client's perspective this is transparent: call_webmcp_tool simply returns the result when any authorised surface approves, or an error if denied or timed out.

What MCP clients see

  • A prompt-gated call_webmcp_tool response may take up to 5 minutes. Surface a pending state to the end user rather than timing out aggressively.

  • While it waits, the server sends notifications/progress on any request that carried a progressToken, one per extension of the consent budget. A client that resets its request timeout on progress (the MCP SDK does, so does Claude Code) waits with the user. Claude Desktop and Cursor cap a tool call at a fixed 60 seconds at the time of writing and will report the call failed while the user can still approve it; the tool description tells the agent not to blindly re-issue a call with side effects when that happens.

  • If the user denies, call_webmcp_tool returns an error. The MCP server does not retry.

  • Tool-call arguments transit HTTPS in plaintext to our backend and land KMS-encrypted at rest in Firestore. Metadata (toolName, scriptName, origin) stays plaintext. See the Customaise Privacy Policy.

Visual DOM Selection

Users can visually select elements in the browser, and the extension pushes context files to your workspace in real time:

.customaise/dom-context/<script-name>/
├── element-name.dom.md          # Selectors, element context, user comments
├── element-name.screenshot.png  # Cropped screenshot of the selected element
└── ...
NOTE

Where are the files saved? The MCP server writes .customaise/ to its current working directory (usually your project root in Cursor). If you are using a global IDE like Claude Desktop, it defaults to your home directory (~/.customaise/). To force a specific project folder, set CUSTOMAISE_WORKSPACE in your MCP config:

"env": { "CUSTOMAISE_WORKSPACE": "/absolute/path/to/your/project" }
NOTE

From the CLI, the directory you ran the command in wins over both. The daemon is long-lived and was started from whatever directory you happened to be in the first time, so it takes the caller's word for it on every command. CUSTOMAISE_WORKSPACE still beats a plain cwd for IDE servers, unchanged.

Use get_selected_elements to retrieve selections programmatically, or read the pushed .dom.md files directly from the workspace.

Each selection includes stable, tiered selectors (stable IDs → data attributes → ARIA → semantic classes → structural positioning) so targeting is more likely to survive page updates.

Workflows

UserScript

1. get_page_context       → understand the target page
2. User selects elements  → .dom.md files auto-pushed to workspace
3. Write .user.js file    → AI writes the script using IDE tools
4. export_script          → Customaise validates and installs
5. reload_tab             → re-inject the script
6. get_console_context    → check for errors
7. take_screenshot        → verify the visual result

AgentScript

1. Read customaise://agentscript-conventions   → get the structure right before writing
2. get_page_context                            → find stable selectors on the target page
3. Write .agent.js file                        → declare tools via // @webmcp, register with document.modelContext.registerTool()
4. export_script                               → Customaise validates and injects
5. reload_tab                                  → the AgentScript registers its tools in the page
6. list_webmcp_tools                           → confirm tools surfaced
7. call_webmcp_tool                            → invoke one; prompt-gated calls wait for user consent

File Sync

Use sync_scripts to bulk-export every script to a local directory:

sync_scripts({ directory: "~/customaise-scripts" })

This creates:

  • One .user.js file per script. Filename is derived from the script name (lowercase, hyphens, e.g. my-cool-script.user.js).

  • .customaise-manifest.json: maps filenames to script IDs for round-trip editing.

Manifest format

{
  "dark-mode-fix.user.js": "vm_script_1774225715376_lus75sdzn",
  "my-cool-script.user.js": "vm_script_1774225800123_abc12defg"
}

Round-trip

  1. sync_scripts exports all scripts to a directory.

  2. Edit any .user.js file in your IDE.

  3. export_script with the file path and scriptId from the manifest updates that script.

  4. Omit scriptId when calling export_script to create a new script instead.

File watcher (auto-export)

Once sync_scripts has been called, the MCP server watches the directory for .user.js changes. Saving a file in your IDE pushes it to Customaise automatically, no manual export_script needed.

Configuration

Environment Variable

Default

Description

CUSTOMAISE_WS_PORT

4050

WebSocket server port. The extension always connects to 4050, so change this only for tests

CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS

(empty)

Comma-separated list of extra extension IDs allowed to connect. Needed for unpacked dev builds with a non-standard extension ID

CUSTOMAISE_MCP_ALLOW_INSECURE

(unset)

Set to 1 to disable the origin allowlist. Tests only. Emits a loud warning at startup

CUSTOMAISE_WORKSPACE

(cwd)

Absolute path where .customaise/ files should be written. Useful for IDEs that don't set cwd to the project root (Claude Desktop, Antigravity)

CUSTOMAISE_CONFIG_DIR

~/.config/customaise

Where the CLI keeps its daemon connection file and remembered tab. Delete this directory to remove everything the CLI stores; uninstalling the extension does not, because these live outside the browser profile

CUSTOMAISE_CLI_SCOPE

(empty)

Optional Bot/session name separating remembered tabs within the same working directory. Remembered tabs are always scoped to the working directory; this adds isolation for Bots sharing one directory

CUSTOMAISE_HTTP_PORT

4051

Loopback port the daemon serves the CLI on. Distinct from CUSTOMAISE_WS_PORT, which is the extension's WebSocket bridge

CUSTOMAISE_MCP_OUTPUT

file

Where get_page_context, get_console_context and take_screenshot put their full payload, and call_webmcp_tool a result over CUSTOMAISE_MCP_INLINE_MAX_KB, when the call does not say. file writes to disk and returns a summary plus the path; inline writes nothing and returns the whole payload (for the screenshot, the image itself) in the response. Set this to inline for a client with no filesystem tool. See Chat clients and file-less agents

CUSTOMAISE_MCP_INLINE_MAX_KB

64

Ceiling on an inline JSON payload. Over it, lists are shortened (never the JSON itself, so it still parses) and the response reports exactly what was dropped

CUSTOMAISE_MCP_INLINE_IMAGE_MAX_KB

1536

Ceiling on an inline take_screenshot image, in KB of base64. Over it the capture is saved to a file instead, because half an image is not an image

Chat clients and file-less agents

get_page_context, get_console_context and take_screenshot spool their full payload to a file by default and hand back a summary plus a path. That is the right shape for an IDE agent: a DOM snapshot is routinely hundreds of KB and belongs on disk rather than in a context window.

It is a dead end for a chat client. Claude Desktop runs this server over stdio, so the write succeeds, but the model on the other end has no filesystem tool with which to open what was written. It receives a path it can never read.

Three ways out, in the order they are consulted:

  1. Per call. Pass output: "inline" and the full payload comes back in the response, with nothing written to disk. All three tools say so in their own descriptions and in every file-mode response, so an agent that hits the dead end can recover on its own in one extra call.

  2. Per install. Set CUSTOMAISE_MCP_OUTPUT=inline in the server's env. The .mcpb bundle ships with this set, because that bundle is installed into Claude Desktop and nowhere else. For an IDE, put it in the env block of your MCP config. For the CLI, exporting it in your shell is enough: the customaise binary reads it and forwards it per call, so it does not matter that the resident daemon was started earlier without it.

  3. Default. file, unchanged.

take_screenshot is the same flag with a different payload: output: "inline" attaches the capture to the response as an MCP image block rather than writing a PNG and returning its path, so a multimodal chat client can actually see it. An image cannot be shortened the way a snapshot can, so a capture over CUSTOMAISE_MCP_INLINE_IMAGE_MAX_KB (1536 KB of base64) falls back to a file and tells the caller to retry with fullPage: false, which is usually small enough, or to raise the ceiling.

call_webmcp_tool follows the same setting for a result too large to send back, and only for one: a result within CUSTOMAISE_MCP_INLINE_MAX_KB always comes back exactly as the page's tool returned it. Over it, file writes the whole result to .customaise/tool-results/ in the workspace, which keeps the newest 20, and returns the path with the result's small values (an id, a count, a next step) so the agent can act without opening the file. inline returns it in the response with long lists shortened. Neither asks for the tool to run again, because running a page's tool again can repeat what it did.

Inline JSON responses are capped at CUSTOMAISE_MCP_INLINE_MAX_KB (64 KB by default). Over the cap the payload is shortened by trimming lists, not by truncating the JSON text, so what arrives still parses and still has every key and nesting level. The response carries truncated: true and an omitted array naming each shortened list and how many items it lost.

There is deliberately no client detection here. clientInfo.name is a guessing game, and the roots capability says the client declares project directories, not that the model can read them. It is also unavailable on 2026-07-28 connections. An explicit flag with a self-advertising fallback beats a heuristic that is confidently wrong.

Source

This repository mirrors the package source from Customaise's own monorepo at each release.

Security Boundary

The MCP server listens on ws://localhost:4050 in plaintext on your loopback interface. The connection is authenticated by an HTTP Origin header allowlist:

  • Allowed: chrome-extension://anmpijcpaobaabcdncjjmnhdeibipmko (production) and chrome-extension://ijjaffggglamocdapoihpkcpealflopp (staging). Chrome stamps this header automatically on WebSocket handshakes from extension service workers; you don't configure anything.

  • Rejected: regular web pages (https://...), unknown extension IDs, and handshakes with no Origin header. Returns HTTP 403.

What this stops: a malicious webpage opening new WebSocket('ws://localhost:4050') and calling WebMCP tools behind your back. This is the most likely abuse vector.

What this does NOT stop: a malicious native process running as your user. Node's ws client (and most HTTP libraries) lets callers forge any Origin header. If you can't trust processes running as your OS user, the threat model is already broader than this bridge.

Approval modes: tools whose effective permission remains prompt require your approval in the Customaise consent modal. The default mode follows saved tool rules. A user-enabled Full access grant can allow eligible Prompt tools in this browser profile, including new and updated tools, while saved Deny rules stay blocked.

Tools declared allow run without asking, with one exception that matters here: a script written through this bridge or the customaise CLI does not get to grant itself allow. Its self-declared allow resolves as prompt in the default mode. A saved user Allow override or a user-enabled Full access grant can permit the call without prompting; the script cannot create either grant itself. Choosing "Always allow" stores an override and it never prompts again. The MCP tool API cannot resolve the consent modal. Remote approvals route prompts away from the requesting browser, but the backend authenticates the signed-in account and accepts a client-supplied device claim; this is not proof of a separate human or physical device. An agent with account credentials or full OS access needs independent account/OS access restrictions.

Scripts you wrote yourself, and scripts you subscribed to from the marketplace, are unaffected: allow means allow. For marketplace scripts that means the old advice still holds, so only subscribe to AgentScripts from sources you trust.

Dev builds: if you load an unpacked extension with a custom key, set CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS=<your-extension-id> in the MCP server's env.

Sharing scripts

Open Quick Actions → Share Script on an owned UserScript or AgentScript. Publish & share keeps the hosted, read-only subscription flow with publisher updates. Send creates a 24-hour link to an independent editable copy. Sending requires Power User; receiving works with a free signed-in account. There is no MCP/CLI Send or Publish command.

Send copies start disabled, keep their own edits and saved selectors, and remain after link expiry or Stop this send, without publisher updates. Refresh link for 24 hours replaces the active snapshot with the current saved script; merely opening or copying a URL does not extend its deadline. Anyone with the active link can preview source. Review source and selectors before sending: secrets embedded there remain included. Saved account keys, GM values, browser logins, tool approvals and Script Decisions provider choices are not copied. Each recipient configures their own access and provider. Fork a subscription before modifying or sending an independent copy.

CLI

Let an agent set up the CLI

In extension Settings → MCP & Terminal → Quick Setup → Terminal, copy the setup prompt for Codex, Claude Code or another shell agent. The Grok Bot tab has a prompt for installing the CLI on the Bot's own computer. Both prompts verify Node.js, install the current published package, run doctor, add the project primer with init, and read the conventions before script work. The CLI guide and Grok Bot guide provide the same prompts.

Terminal setup

For an agent with a terminal rather than an MCP client.

npm i -g @customaise/mcp     # both binaries on PATH
customaise doctor            # bridge, sign-in, tier, quota, and whether
                             # "Allow user scripts" is on. Costs no quota.
customaise init              # writes AGENTS.md in this project, so the next
                             # agent finds the CLI without being told
customaise scripts list
customaise scripts install ./my-tool.agent.js
customaise scripts get mcp_script_123 -o ./my-tool.agent.js
customaise scripts enable mcp_script_123      # or disable
customaise scripts fork shared_abc -o ./mine.agent.js
customaise scripts rm mcp_script_123
customaise sync ./customaise-scripts          # bulk export your scripts
customaise decisions                         # Script Decisions: agent access, keys, script states
customaise decisions set mcp_script_123 jev  # needs Script Decisions on for agents; off always works
customaise tabs
customaise tab reload 42
customaise use --tab 42                      # remember it for later commands
customaise tools                             # WebMCP tools on that tab
customaise call my_tool --args '{"q":"hi"}'
customaise context page                      # DOM snapshot
customaise shot -o ./page.png
customaise tab list                          # every short verb has a noun-verb form: tab list|shot|use
customaise schema                            # the whole command tree as JSON, for an agent to read
customaise daemon status | stop

customaise use --tab N remembers the tab for the current working directory. Bots sharing a directory can set distinct CUSTOMAISE_CLI_SCOPE values before both use and later commands. Scheduled routines should pass --tab N explicitly and verify the tab URL each run, since the browser itself remains shared and a tab can close or navigate. This scoping does not isolate browser logins or files. After upgrading from the former global remembered-tab file, select the tab once in each workspace; the global choice is not copied into every Bot's workspace.

Without a global install, npx -p @customaise/mcp customaise <verb> works but costs roughly half a second of package resolution per command against about fifty milliseconds installed. For anything in a loop, install it.

Output contract. JSON on stdout, always, so it pipes. Diagnostics on stderr. --pretty indents the JSON; -h or --help prints usage, and customaise schema prints the whole command tree as JSON for an agent to read. Exit codes are the interface:

Code

Meaning

0

success

2

usage error

3

daemon or extension unreachable, including after signing out or with "Allow user scripts" off

4

signed in, but the token expired or could not be refreshed

5

free-tier cap reached

6

consent denied, or a change only the person can make (person_required)

7

consent expired unanswered

8

rejected by Customaise (diagnostics in the payload)

Two things make 3 more common than it looks. Signing out of Customaise tears the bridge down deliberately, so it reports 3, not 4. And the "Allow user scripts" toggle on the Customaise card in chrome://extensions resets on every Chrome restart; while it is off, scripts install fine and no tool ever registers, so doctor reports 3 rather than claiming a healthy setup that cannot run anything. 4 is the narrower case: the bridge is up and the token behind it went stale. Both mean stop, and both are worth telling the user about, but only 3 is worth checking Chrome over.

Codes 5, 6 and 7 are deliberately distinct: an agent that cannot tell a cap from a refusal from a timeout retries into a wall. Code 8 is the one to handle first when installing scripts: the sanitization pipeline refused the file and the diagnostics say what to change, where a 1 means something broke and rewriting the script will not help.

The daemon. Started on first use, and it holds the WebSocket to the extension so commands do not each pay for a reconnect. It binds 127.0.0.1 only and authenticates the CLI with a token in a 0600 file that exists only while the endpoint is live. customaise daemon stop ends it.

When several customaise-mcp processes share a machine, the first to bind :4050 leads and the rest relay through it, so one extension serves every IDE and every shell at once. That seam carries its own protocol version: a process built against different frames is refused rather than served, with an error naming both versions and which one to restart (-40033). Package versions may differ freely; only a change to the frames themselves moves it. A leader that sees a follower from a newer package steps down and rejoins behind it, so a resident daemon can never pin the machine to an old version.

Custom HTTP clients: workspace and resource limits

The loopback daemon requires x-customaise-token and an absolute x-customaise-workspace on every HTTP request, including negotiation. The CLI supplies these automatically. A missing, relative or malformed workspace returns HTTP 400 before dispatch; requests never inherit another caller's directory. An explicitly declared filesystem root is honored, with ordinary filesystem permissions still applying. This header chooses the output directory; it is not an OS sandbox for clients that share the same daemon token.

For Unicode paths, send encodeURIComponent(absolutePath) as the workspace and x-customaise-workspace-encoding: uri. The daemon decodes once; raw headers without that encoding retain literal percent signs. New daemons advertise workspaceEncoding: "uri" in daemon.json. The CLI uses that capability and asks you to stop an older daemon before using a path it cannot represent safely.

The daemon admits at most 16 concurrent HTTP requests and remembers up to 256 workspaces active in the last 15 minutes. New requests above either limit receive HTTP 429 before tool dispatch. Uploads are limited to 8 MiB and 30 seconds; responses to 32 MiB cumulatively and requests to 10 minutes, including streamed output. These transport limits do not raise the smaller limits of individual tools. At most 64 TCP connections are accepted, with a 15-second header timeout. SSE progress streams immediately, and slow readers apply backpressure instead of causing the daemon to buffer the entire response.

An oversized upload receives HTTP 413; a stalled upload receives HTTP 408. Pre-dispatch errors include outcome: "not_dispatched". Once a tool has been submitted, a response failure or disconnect may leave its outcome unknown: check what happened before retrying a mutating tool. If a response exceeds its limit after streaming starts, the transport closes with an error rather than returning a truncated success. Disconnects and the request deadline propagate cancellation; a handler that ignores cancellation retains its admission slot until it settles, so a stream of replacements cannot create unbounded background work.

Requirements

  • Node.js ≥ 20

  • Chrome 147 or later with Customaise (1.4.0 is the tested pair for 3.2.9), signed in, with Agent Bridge on.

Plan tiers

The Agent Bridge is free for any signed-in Customaise user. Free use is capped at 50 calls per UTC day and 150 calls per rolling 7-day window. Power User unlocks unlimited MCP. The cap covers every successful tool dispatch (built-in tools and WebMCP calls alike); failed calls and protocol-level traffic don't count.

When the cap fires, the server returns a JSON-RPC error with code -40029 and a human-readable message + structured data carrying scope, used/limit, and reset timestamp. IDEs that surface tool errors render the message verbatim. Sign-in is required regardless of tier; without a fresh Firebase ID token the server returns -40028 MCP_AUTH_REQUIRED. Branch on structuredContent.error.type, never on the number: the codes moved once already (3.2.0 took them out of the range the 2026-07-28 specification reserved for itself; the old -3202x values are still accepted from older extensions), the type strings did not.

Troubleshooting

"Customaise extension is not connected"

  • Make sure Chrome is running with the Customaise extension.

  • Check that Agent Bridge is on in Settings → MCP & Terminal.

  • The extension connects automatically within a few seconds.

Port conflict on 4050

  • The extension always connects to localhost:4050. Find what holds the port with lsof -i :4050 and stop it. CUSTOMAISE_WS_PORT is for tests.

Scripts not running after export

  • Call reload_tab to trigger script re-injection.

  • Check the @match pattern covers the current URL.

call_webmcp_tool hangs for minutes

  • The tool is prompt-gated. The user has to approve in the browser, or remotely if Remote HITL Approvals is on. 5-minute budget before auto-deny. Surface a pending state rather than timing out.

call_webmcp_tool returned an error like "consent denied"

  • Expected when the user denied the modal, the 5-minute budget expired, or a previous "Always deny" override was set on that tool. The user can reset per-tool overrides in extension Settings.

list_webmcp_tools returns empty after a reload

  • Walk the conventions handbook's troubleshooting checklist. Check Chrome's Allow user scripts setting with customaise doctor, the intended script's enable switch in Scripts, and whether its @match covers the URL. Reload the page after installing or changing the script. See customaise://agentscript-conventions for the full list.

License

MIT

Available Tools

21 tools
call_webmcp_toolA
Destructive

Execute a registered WebMCP tool directly on the target browser tab. If the tool is interactive (trust level), the user will be natively prompted by CustomAIse to approve the execution before it returns. Approval can take minutes when the user is away from the browser (remote approvals on a phone). This server sends progress notifications while it waits, so a client that resets its timeout on progress will wait with it. A client that caps tool calls at a fixed 60 seconds regardless will report this call as failed while the user can still approve it and the tool can still run; if that happens, do not blindly re-issue a call with side effects. Check the outcome first with a read-only tool or the page itself. A result over 64 KB WRITES A FILE by default: the whole result goes to .customaise/tool-results/ in your workspace, which keeps the newest 20, and this call returns the path with the result's small values. If you have no filesystem tool, pass output: "inline" to get it in the response with long lists shortened instead.

NameRequiredDescriptionDefault
tabIdNoTab ID to execute on. Defaults to active tab.
outputNoWhere a result over the inline budget (64 KB by default) goes; a smaller result always comes back in this response as the tool returned it. "file" (default) writes it whole to .customaise/tool-results/ in your workspace and returns its path, its small values and the size of the rest. "inline" writes nothing and returns it in this response, with long lists shortened to fit. Use it when you have no filesystem tool to read the file with, such as a chat client. "auto" follows the CUSTOMAISE_MCP_OUTPUT environment variable, falling back to "file".
toolArgsNoJSON object of arguments for the tool
toolNameYesThe EXACT name of the WebMCP tool to invoke
close_tabA
DestructiveIdempotent

Close a specific browser tab. Defaults to the active tab if no tabId is provided.

NameRequiredDescriptionDefault
tabIdNoThe ID of the tab to close
delete_scriptA
DestructiveIdempotent

Permanently delete a script (UserScript or AgentScript) from Customaise. This action cannot be undone. NOTE: Shared/subscribed scripts cannot be deleted via MCP — the user must unsubscribe from the extension UI. Forks created via import_script(fork:true) are owned scripts and CAN be deleted via MCP.

NameRequiredDescriptionDefault
scriptIdYesThe ID of the script to delete
export_scriptA
Destructive

Export a script from a local file into Customaise. The file will be validated through Customaise's sanitization pipeline (syntax checking, AST validation, security analysis). If valid, the script is installed and ready to execute on matching pages. If invalid, detailed diagnostics explain exactly what to fix. Pass scriptId to update an existing script instead of creating a new one. Pass expectedCodeHash from import_script to reject stale edits. Save progress includes an operation ID and stage. A timeout may leave the outcome unknown: query get_bridge_status with the scriptId and operationId from the error before retrying. The extension enforces a 90-second save deadline and cancels work that has not reached persistence. A storage write already submitted cannot be recalled; its commit receipt resolves that uncertainty. For a script that uses CM_decisions, scriptDecisions in the result says whether its Script Decisions provider stays chosen for the new code, and if not, why and what to do. NOTE: You cannot overwrite a shared/subscribed script — they are read-only. If you need to edit a shared script, first call import_script with fork:true (creates an editable independent copy), then export to that copy's scriptId.

Reminder for new UserScripts: Prefer named functions in an IIFE for symbol-level editing; preserve valid imported source, `// @namespace https://customaise.com`, and standard directives (@name, @match, @grant).
Reminder for AgentScripts: MUST use `// ==AgentScript==` block, MUST explicitly declare tools via `// @webmcp <toolName> <permission>` (e.g. `// @webmcp my_tool prompt`). Permissions: allow (autonomous), prompt (interactive), deny (blocked). Prefer `prompt`: in a script you write, `allow` resolves as `prompt` before user grants are applied; a saved Allow rule or user-enabled Full access can permit it. Prefer named top-level functions and top-level tool registration for symbol editing; IIFEs are supported. CAN use GM_* APIs for persistence, networking, and observability alongside `document.modelContext.registerTool()`.
NameRequiredDescriptionDefault
filePathYesLocal file path containing the userscript source code
scriptIdNoID of an existing script to update. Omit to create a new script.
expectedCodeHashNoSHA-256 from import_script. Reject the save if the installed source has changed since that read.
focus_tabA
Idempotent

Bring a specific browser tab to the front and make it active.

NameRequiredDescriptionDefault
tabIdYesThe ID of the tab to focus
get_bridge_statusA
Read-onlyIdempotent

Report the bridge's own state: whether the extension is attached, the plan tier, whether you are signed in, whether remote approvals are enabled, the browser's agent permissions (agentPermissions: Full access, and scriptDecisions, whether agents may choose Script Decisions providers), and how much of the MCP cap is left today and this week. Costs NO cap units. Without scriptId it reads cached bridge state; with scriptId it queries the browser for the latest save status and durable commit receipt. After a timeout, inspect that status before retrying. Unknown means no retained proof, not proof of failure. Check this before a long run so you find out you have three calls left now rather than mid-task.

NameRequiredDescriptionDefault
scriptIdNoOptionally inspect the latest save for this script; reads the browser without spending a cap unit.
operationIdNoSave operation ID from export progress or a timeout. Requires scriptId.
get_console_contextA
Idempotent

Get console logs from the browser, including errors, warnings, and userscript GM_log output. Use after reload_tab to check for script runtime errors. WRITES A FILE by default: the full log data goes to .customaise/console-context.json in your workspace and this call returns counts plus the path. Read the file with view_file or grep_search. If you have no filesystem tool, pass output: "inline" to get the whole log in the response and write nothing to disk.

NameRequiredDescriptionDefault
levelNoFilter by log level. Default: all
tabIdNoTab ID to get logs from. Defaults to the active tab.
outputNoWhere the full payload goes. "file" (default) writes it to .customaise/ in your workspace and returns a summary plus the path, which keeps a large payload out of your context window. "inline" writes nothing and returns the whole payload in this response. Use it when you have no filesystem tool to read the file with, such as a chat client. "auto" follows the CUSTOMAISE_MCP_OUTPUT environment variable, falling back to "file".
get_page_contextA
Idempotent

Get a DOM snapshot of the current page including URL, title, page structure, and visible elements. Use this to understand the page layout before writing userscripts that manipulate it. WRITES A FILE by default: the full snapshot goes to .customaise/page-context.json in your workspace and this call returns a summary plus the path, so a large page does not fill your context window. Read the file with view_file or grep_search. If you have no filesystem tool, pass output: "inline" to get the whole snapshot in the response and write nothing to disk.

NameRequiredDescriptionDefault
tabIdNoTab ID to inspect. Defaults to the active tab.
outputNoWhere the full payload goes. "file" (default) writes it to .customaise/ in your workspace and returns a summary plus the path, which keeps a large payload out of your context window. "inline" writes nothing and returns the whole payload in this response. Use it when you have no filesystem tool to read the file with, such as a chat client. "auto" follows the CUSTOMAISE_MCP_OUTPUT environment variable, falling back to "file".
get_script_decisionsA
Read-onlyIdempotent

Read Script Decisions on this device: the typed decisions scripts make through @grant CM_decisions. Returns whether agents may manage it (agentAccess.scriptDecisions; the person turns it on under Full access in Customaise Settings, Agent permissions), sign-in and plan (Power User is required), whether this device is allowed (deviceEnabled) or paused (locallyPaused), which provider keys are saved, and every script that uses CM_decisions or has a provider: its provider (jev, openai-decisions or null) and state, one of ready, off, choose_again (its code or this device changed since the provider was chosen; reason says which), paused (pausedReason loop_repeat or loop_runaway) or invalid (issue). chosenByAgent marks a provider an agent chose. With scriptId it also returns that script's question lists (sets: hash, enabled, questions), the problems found in its code (issues, with line numbers) and today's decisions on this device (rowsToday). Use it before set_script_decisions, which names question lists by these hashes, and after export_script to check a script's provider. Reads only; nothing is sent to a provider. Needs extension 1.4.0 or later.

NameRequiredDescriptionDefault
scriptIdNoA script ID from list_scripts. Omit to list every script that uses CM_decisions or has a provider.
get_selected_elementsA
Idempotent

Get DOM elements that the user has visually selected in the browser for a specific script. Returns each selection's stable, tiered selectors, element context, and user comments. Returns the selections in this response, so it needs no filesystem access. WRITES FILES only when you pass writeFiles: true, which saves .dom.md context files under the directory you name. Use CM_findElement with the domId for precise targeting in scripts. When MCP is connected, .dom.md context files and screenshots are automatically pushed to the workspace (.customaise/dom-context//) in real-time as the user selects elements. Use this tool to retrieve selections if the auto-pushed files are missing or to get the raw JSON data.

NameRequiredDescriptionDefault
scriptIdNoScript ID to get selections for. Omit to get all scripts' selections.
directoryNoWorkspace directory for .dom.md files. Required if writeFiles is true.
writeFilesNoIf true, writes .dom.md context files to the workspace directory. Default: false.
import_scriptA

Import a Customaise script (UserScript or AgentScript) to a local file for editing. The file contains the full source with metadata block. After editing with your IDE tools, use export_script to push changes back.

Optional 'fork' flag (default false): when set to true, the script is FORKED into a new independent local copy BEFORE import, and the FORK is what gets written to the file. ALWAYS creates a new script — symmetric across source types, never a silent no-op:

  • Subscribed/shared sources: "Fork" verb. Clears the subscription link (no more publisher updates), captures forkedFrom lineage so a later publish can render "Forked from " on the marketplace.

  • Owned sources: "Duplicate" verb. Clears publishedShareId so the dup isn't tied to the original's published listing. Use when you want a remix while keeping the original intact. Forked/duplicated scripts land DISABLED in the user's library (D10 trust ceremony). The returned scriptId is the NEW script (not the original); the agent can immediately export back to it.

Without 'fork', subscribed scripts cannot be imported — they're read-only and the call refuses with a clear error pointing at fork:true. Owned scripts import normally (edit-in-place workflow).

IMPORTANT: Save files inside your current workspace or project directory (e.g., ./customaise-scripts/), never in /tmp.

NameRequiredDescriptionDefault
forkNoWhen true, fork the script into a new editable copy and import THAT copy. Always creates a new script (Fork for shared sources, Duplicate for owned). Required for subscribed/shared scripts. Default false.
filePathYesLocal file path inside your workspace to write the script to (e.g., ./customaise-scripts/my-script.agent.js). Do NOT use /tmp.
scriptIdYesThe ID of the script to import (get from list_scripts). When fork=true, this is the source script to fork from; the returned scriptId is the new fork.
list_scriptsA
Read-onlyIdempotent

List all scripts (UserScripts & AgentScripts) installed in Customaise with their IDs, names, enabled status, match patterns, and whether they are shared (subscribed). Scripts marked isShared are read-only subscriptions — they cannot be imported, exported, or deleted directly. To edit a shared script, call import_script with fork:true (creates an independent editable copy). To uninstall a shared script, the user must unsubscribe from the extension UI.

NameRequiredDescriptionDefault

No parameters

list_tabsA
Read-onlyIdempotent

List all open browser tabs with their IDs, URLs, titles, and active status. Use to find a specific tab ID for other tools like reload_tab or take_screenshot.

NameRequiredDescriptionDefault

No parameters

list_webmcp_toolsA
Read-onlyIdempotent

List all WebMCP tools currently registered by AgentScripts for a specific browser tab. Use this to verify that an exported AgentScript is correctly registering its tools on the target page. Each entry carries a permission field (allow / prompt / deny) telling you what will happen BEFORE you call it: prompt blocks on an in-browser consent modal for up to 5 minutes, deny fails immediately. Read it and tell the user which calls will need their approval, rather than discovering it mid-run.

NameRequiredDescriptionDefault
tabIdNoTab ID to query. Defaults to the active tab.
open_tabA

Open a new browser tab with the specified URL. Defaults to opening in the background so the user is not snatched away from the tab they are currently viewing. Returns the new tab ID.

NameRequiredDescriptionDefault
urlYesThe URL to open in the new tab
activeNoWhether the new tab should become the active tab. Defaults to false (opens in background). Set to true only when the agent genuinely needs the new tab brought to focus.
reload_tabA
Idempotent

Reload a browser tab to re-inject updated userscripts. Use after export_script to see the effect of your changes. Waits for the page to fully load before returning. If the tab has AgentScript (WebMCP) tools registered, automatically waits for them to re-register before returning.

NameRequiredDescriptionDefault
tabIdNoTab ID to reload. Defaults to the active tab.
set_script_decisionsA
Idempotent

Choose the Script Decisions provider for one script on this device: jev, openai-decisions (Decisions API), or off. Once a provider is chosen, the script's CM_decisions calls run without asking and are billed to the person's saved key for that provider, so choose one only when the person wants it. sets switches On exactly the question lists it names, by the hashes get_script_decisions returns for this scriptId, and every other list Off. Without sets, unchanged code keeps its On/Off choices and changed code switches every list On. Choosing a provider again also resumes a script the loop guard paused for repeating the same input (pausedReason loop_repeat).

Choosing jev or openai-decisions needs the person to have turned on Script Decisions under Full access in Customaise Settings, Agent permissions; only they can, in the extension. Switching a script off is always allowed. These stay with the person: provider keys, this device's Allow Script Decisions switch, daily limits, pausing this device, a script paused for a runaway loop (loop_runaway), and scripts shared with them. When the error type is person_required, tell the person the next step the message names and do not retry. Other refusals carry type rejected, not_found, auth_required or invalid_argument, with the precise reason in code. After service_unavailable or a timeout the outcome is uncertain: read the state with get_script_decisions before trying again. Returns the script's state as get_script_decisions does for one script. Needs extension 1.4.0 or later.

NameRequiredDescriptionDefault
setsNoHashes of the question lists to switch On, from get_script_decisions with this scriptId; every other list goes Off. Only with jev or openai-decisions. Omit to keep the current choices for unchanged code.
providerYesjev, openai-decisions (Decisions API), or off to switch the script provider off.
scriptIdYesThe script ID, from list_scripts or get_script_decisions.
sync_scriptsA
DestructiveIdempotent

Bulk export all your own scripts from Customaise to a local directory as individual .user.js or .agent.js files. WRITES MANY FILES and OVERWRITES existing ones: a local file whose name matches a script is replaced by the copy held in Customaise, so unexported local edits in that directory are lost. Creates a .customaise-manifest.json mapping filenames to script IDs. Shared/subscribed scripts are excluded (they are read-only). Use this to set up a local workspace for editing scripts with your IDE.

NameRequiredDescriptionDefault
directoryYesLocal directory to export scripts to (e.g., ./customaise-scripts/)
take_screenshotA

Capture a screenshot of a browser tab without stealing focus from the user. Defaults to the visible viewport. Set fullPage: true to capture the entire scrollable page as one tall image. WRITES A FILE by default: the PNG is saved to filePath, or to an auto-generated path in the system temp directory when filePath is omitted, and this call returns that path rather than the image. If you have no filesystem tool, pass output: "inline" and the image is attached to this response instead, with nothing written to disk. For background tabs and full-page captures, Chrome briefly displays its standard yellow developer-tools notice at the top of the target tab during capture; it clears automatically when capture completes (typically under one second).

NameRequiredDescriptionDefault
tabIdNoTab ID to screenshot. Defaults to the active tab.
outputNoWhere the full payload goes. "file" (default) writes it to filePath, or the system temp directory when filePath is omitted and returns a summary plus the path, which keeps a large payload out of your context window. "inline" writes nothing and returns the whole payload in this response. Use it when you have no filesystem tool to read the file with, such as a chat client. "auto" follows the CUSTOMAISE_MCP_OUTPUT environment variable, falling back to "file".
filePathNoLocal file path to save the screenshot. Auto-generates a temp path if omitted. Ignored when output is "inline".
fullPageNoIf true, capture the entire scrollable page (single tall PNG). If false or omitted, capture the visible viewport only.
toggle_scriptA
Idempotent

Enable or disable a userscript. Disabled scripts are not injected into matching pages. Use this to temporarily turn off a script without deleting it.

NameRequiredDescriptionDefault
enabledYestrue to enable, false to disable
scriptIdYesThe ID of the script to enable/disable
toggle_uiA
Idempotent

Show or hide the Customaise UI overlay on the active tab. Use this to make the Customaise interface visible or dismiss it — AI agents cannot click the extension icon directly. Optionally specify which panel to open.

NameRequiredDescriptionDefault
panelNoPanel to open: "scripts", "chat", "settings"
tabIdNoTab ID to toggle UI on. Defaults to the active tab.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv3.2.9
    • Changedcall_webmcp_tool1 field changed
      • addedInput schema / properties / output
        Added value: +{
        +  "description": "Where a result over the inline budget (64 KB by default) goes; a smaller result always comes back in this response as the tool returned it. \"file\" (default) writes it whole to .customaise/tool-results/ in your workspace and returns its path, its small values and the size of the rest. \"inline\" writes nothing and returns it in this response, with long lists shortened to fit. Use it when you have no filesystem tool to read the file with, such as a chat client. \"auto\" follows the CUSTOMAISE_MCP_OUTPUT environment variable, falling back to \"file\".",
        +  "enum": [
        +    "auto",
        +    "file",
        +    "inline"
        +  ],
        +  "type": "string"
        +}
    • Addedget_script_decisions
    • Addedset_script_decisions
  2. 2 tool updatesv3.2.3
    • Changedexport_script1 field changed
      • addedInput schema / properties / expectedCodeHash
        Added value: +{
        +  "description": "SHA-256 from import_script. Reject the save if the installed source has changed since that read.",
        +  "pattern": "^[a-f0-9]{64}$",
        +  "type": "string"
        +}
    • Changedget_bridge_status2 fields changed
      • addedInput schema / properties / operationId
        Added value: +{
        +  "description": "Save operation ID from export progress or a timeout. Requires scriptId.",
        +  "maxLength": 128,
        +  "minLength": 1,
        +  "type": "string"
        +}
      • addedInput schema / properties / scriptId
        Added value: +{
        +  "description": "Optionally inspect the latest save for this script; reads the browser without spending a cap unit.",
        +  "maxLength": 256,
        +  "minLength": 1,
        +  "type": "string"
        +}
  3. 19 tool updatesv3.2.0
    • First observedcall_webmcp_tool
    • First observedclose_tab
    • First observeddelete_script
    • First observedexport_script
    • First observedfocus_tab
    • First observedget_bridge_status
    • First observedget_console_context
    • First observedget_page_context
    • First observedget_selected_elements
    • First observedimport_script
    • First observedlist_scripts
    • First observedlist_tabs
    • First observedlist_webmcp_tools
    • First observedopen_tab
    • First observedreload_tab
    • First observedsync_scripts
    • First observedtake_screenshot
    • First observedtoggle_script
    • First observedtoggle_ui

TDQS

A4.2/5.0

Scored across 21 tools

Disambiguation4/5

Most tools target a clearly distinct resource+action (tab ops, script lifecycle, context capture, Script Decisions, WebMCP). The main friction is the import_script/export_script pair, whose verbs are inverted relative to common intuition (import = download to local file, export = upload into Customaise), and sync_scripts is a bulk variant of the same flow, so an agent must read descriptions carefully. get_bridge_status vs get_script_decisions also overlap slightly on state reporting, but descriptions delineate them.

Naming Consistency5/5

Every name is snake_case verb_noun (list_tabs, open_tab, close_tab, focus_tab, reload_tab, get_page_context, set_script_decisions, take_screenshot, call_webmcp_tool). The verb vocabulary is reused predictably across resources (list_/get_/toggle_/delete_). No camelCase or stylistic mixing anywhere.

Tool Count4/5

21 tools is on the heavy side but the surface spans five genuine sub-domains (tab control, script lifecycle, page/console context, WebMCP execution, Script Decisions), roughly 4 tools each. Each tool maps to a distinct operation with no obvious redundancy, though the set is near the upper bound of comfortable scoping.

Completeness4/5

Script lifecycle is well covered (list, create/update via export, fork/duplicate via import, delete, toggle, bulk sync) and tab/context/WebMCP/Decisions all have read+act pairs. Minor gaps: no way to navigate an existing tab to a new URL, no publish/share-to-marketplace operation, and no direct inline source read without writing a file.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

  • Dubsado MCP server for ChatGPT, Claude and any AI agent: create project, send form, send invoice, record payment and list unpaid invoices in your own Dubsado account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Dubsado yourself; Cotlet does not store your password and you need no Dubsado API key. About the official Dubsado API: Dubsado has no public API (checked 11 Oct 2026). Its only official connection is Zapier, on the Premier plan: five triggers and one action, Create Project. Setup and FAQ: https://cotlet.dev/integrations/dubsado-api-mcp-server

    https://cotlet.dev/mcp/v1/dubsado
  • ConnectWise MCP server for ChatGPT, Claude and any AI agent: list tickets, read ticket notes, update ticket, add ticket note, log time entry and create ticket in your own ConnectWise account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to ConnectWise yourself; Cotlet does not store your password and you need no ConnectWise API key. About the official ConnectWise API: ConnectWise PSA, formerly ConnectWise Manage, has a REST API, but no documented ConnectWise-hosted MCP server (checked 5 Nov 2026). To use the API you register on the ConnectWise Developer Network, get a ClientId and create an API member with a public and a private key. Setup and FAQ: https://cotlet.dev/integrations/connectwise-api-mcp-server

  • SuiteDash MCP server for ChatGPT, Claude and any AI agent: create contact, create project, create invoice, add task and send portal message in your own SuiteDash account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to SuiteDash yourself; Cotlet does not store your password and you need no SuiteDash API key. About the official SuiteDash API: SuiteDash has a Secure API for Super Admins and Admins, with monthly call caps, but its Zapier app only covers contacts, companies, projects and tasks (checked 11 Oct 2026). No official endpoint or Zapier action creates invoices, records payments, sends portal messages or shares files. Setup and FAQ: https://cotlet.dev/integrations/suitedash-api-mcp-server

  • Agile CRM MCP server for ChatGPT, Claude and any AI agent: get campaign report, add contacts to campaign, list contacts, add contact tags, list deals, move deal to milestone, add note and create task in your own Agile CRM account. Cotlet works in the account through your Cloud Browser, a real Chrome where you sign in to Agile CRM yourself; Cotlet does not store your password and you need no Agile CRM API key. About the official Agile CRM API: Yes, Agile CRM has a REST API on all plans, with a daily call cap by plan and no official MCP server (checked 22 Oct 2026). It covers contacts, companies, deals, tasks, notes, events, tracks and enrolling a contact in a campaign, but not campaign reports or bulk actions. Setup and FAQ: https://cotlet.dev/integrations/agile-crm-api-mcp-server

Related MCP Servers