customaise
OfficialClick on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@customaiselist my user scripts"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
@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.
19 tools, 5 resources, 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 ExtensionSpeaks 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 and enable MCP Bridge in Settings.
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/mcpClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}Windsurf (.windsurf/mcp.json):
{
"mcpServers": {
"customaise": {
"command": "npx",
"args": ["-y", "@customaise/mcp"]
}
}
}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: Chromanche
Tools (19)
Script Lifecycle
Tool | Description |
| List every script (UserScripts and AgentScripts) managed by the extension |
| Pull a script to a local file for editing |
| Push a local file to Customaise (validates and installs) |
| Permanently delete a script |
| Enable or disable a script |
Browser Context
Tool | Description |
| DOM snapshot of the current page |
| Console logs, errors, and |
| List all open browser tabs |
Tab Control
Tool | Description |
| Open a new tab at a given URL |
| Close a tab by ID |
| Switch focus to a tab by ID |
| Reload a tab to re-inject scripts |
Visual DOM Targeting
Tool | Description |
| Get the DOM elements the user has visually selected, with bulletproof selectors and screenshots |
| Capture any tab (not just the visible one) as a viewport or full-page image |
WebMCP Agent Tools
Tool | Description |
| List the WebMCP tools currently registered on a tab by AgentScripts |
| Call a WebMCP tool; prompt-gated tools block on user consent (see below) |
UI Control & Batch
Tool | Description |
| Show or hide the Customaise UI overlay |
| Bulk export all scripts to a local directory |
Diagnostics
Tool | Description |
| Report extension attachment, plan tier, sign-in, and remaining daily and weekly quota. Costs no quota itself. |
Resources (5)
Five resources any connected agent 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 |
| Live JSON list of every script the extension manages (ID, name, enabled state, match patterns, shared flag) |
| Full source and metadata for a specific script |
| Points at the right handbook for the script type you're working on |
| Full UserScript reference: file structure, IIFE pattern, |
| Full AgentScript reference: the |
WebMCP Tool Calls & Consent (HITL)
AgentScripts register tools on web pages via navigator.modelContext.registerTool(...). 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: every call surfaces an in-browser consent modal and blocks until the user approves or denies. Up to 5 minutes. Design for this. Don't chain prompt-gated calls in tight loops, and treat a longcall_webmcp_toolas 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 live in chrome.storage.local on the user's device; the MCP server has no visibility into them.
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_toolresponse 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/progresson any request that carried aprogressToken, 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_toolreturns 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
└── ...Where are the files saved?
The MCP server writes .customaise/ to its current working directory (usually your project root in Cursor or Windsurf).
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" }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 bulletproof tiered selectors (stable IDs → data attributes → ARIA → semantic classes → structural positioning) so targeting survives 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 resultAgentScript
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 navigator.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 consentFile Sync
Use sync_scripts to bulk-export every script to a local directory:
sync_scripts({ directory: "~/customaise-scripts" })This creates:
One
.user.jsfile 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
sync_scriptsexports all scripts to a directory.Edit any
.user.jsfile in your IDE.export_scriptwith the file path andscriptIdfrom the manifest updates that script.Omit
scriptIdwhen callingexport_scriptto 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 |
|
| WebSocket server port |
| (empty) | Comma-separated list of extra extension IDs allowed to connect. Needed for unpacked dev builds with a non-standard extension ID |
| (unset) | Set to |
| (cwd) | Absolute path where |
|
| 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 |
|
| Loopback port the daemon serves the CLI on. Distinct from |
|
| Where |
|
| 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 |
|
| Ceiling on an inline |
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:
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.Per install. Set
CUSTOMAISE_MCP_OUTPUT=inlinein the server's env. The.mcpbbundle ships with this set, because that bundle is installed into Claude Desktop and nowhere else. For an IDE, put it in theenvblock of your MCP config. For the CLI, exporting it in your shell is enough: thecustomaisebinary reads it and forwards it per call, so it does not matter that the resident daemon was started earlier without it.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.
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.
Publishing the public mirror
This package is developed in a private monorepo and mirrored to
getcustomaise/customaise-mcp,
which is what package.json repository points at and what MCP scanners
and directories read. Keep them in step with the sync script rather than by
hand: the previous hand-copy shipped 7 of 21 source files, so the published
repo did not compile and carried none of the test suites.
npm run mirror:plan # what would be published, as JSON
npm run mirror:verify -- ../customaise-mcp # drift report, exit 1 if adrift
npm run mirror:apply -- ../customaise-mcp # copy the plan over a checkoutmirror:apply writes into a clone, deletes files this package no longer
ships, and leaves the repo's own .github/ furniture alone. It never
pushes. Review git diff in the checkout and push yourself.
The plan is built from git ls-files, so anything uncommitted is invisible
to it. The script refuses to run while untracked files exist under mcp/
rather than publishing a tree that is missing them. src/__tests__/public-mirror.test.ts
guards the shape of the plan in CI; the drift check needs a checkout and so
stays a release step.
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) andchrome-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.
Defense in depth: every prompt-permissioned tool still requires your explicit approval in the Customaise consent modal before running.
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, so the first call shows you what the agent built. Choosing "Always allow" stores an override and it never prompts again. An agent that could clear its own gate would not be gated, and the whole point of the consent modal is that it lives somewhere the calling agent cannot reach.
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.
CLI
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 toldcustomaise 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 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 | stopWithout 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 by the user |
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.
Requirements
Node.js ≥ 20
Chrome with the Customaise extension installed (≥ 1.2.3 for the v2 bridge protocol; older extensions still work but don't surface the cap-usage display)
MCP Bridge enabled in Customaise Settings (free, signed-in)
Plan tiers
The MCP 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 MCP Bridge is enabled in extension Settings.
The extension connects automatically within a few seconds.
Port conflict on 4050
Set a different port:
CUSTOMAISE_WS_PORT=4051 npx @customaise/mcp.
Scripts not running after export
Call
reload_tabto trigger script re-injection.Check the
@matchpattern 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. Most common: the global AgentScripts toggle in Customaise Settings is off, or the
@matchpattern doesn't cover the URL. Seecustomaise://agentscript-conventionsfor the full list.
License
MIT
Available Tools
19 toolscall_webmcp_toolADestructive
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.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Tab ID to execute on. Defaults to active tab. | |
| toolArgs | No | JSON object of arguments for the tool | |
| toolName | Yes | The EXACT name of the WebMCP tool to invoke |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Behavioral transparency is excellent. The description discloses that interactive tools trigger a native user prompt, that approval can take minutes, that the server sends progress notifications, that a fixed-timeout client may falsely report failure while the tool still runs, and that re-issuing side-effecting calls is dangerous. This goes well beyond the annotations and directly informs safe agent behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the primary purpose in the first sentence. The subsequent sentences are longer but each earns its place by explaining approval latency, progress notifications, timeout failure, and safe recovery behavior. No sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the generic nature of the tool, the description covers the most important contextual risks: side effects, non-idempotence, approval delays, and timeout handling. It does not describe return values or how to enumerate valid WebMCP tools, but the sibling list_webmcp_tools and the schema's exact-name requirement cover part of that gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add parameter-specific meaning beyond the schema, but it also does not need to: toolName, tabId, and toolArgs are already described adequately in the input schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: "Execute a registered WebMCP tool directly on the target browser tab." This clearly differentiates the tool from siblings like list_webmcp_tools, which only lists available tools, and from browser-control actions like focus_tab or reload_tab.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for when this tool is invoked and what conditions apply, including interactive approval and timeout behavior. It lacks an explicit "when not to use" statement or named alternative, but the timeout guidance about checking outcomes before re-issuing side-effecting calls provides practical usage direction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_tabADestructiveIdempotent
Close a specific browser tab. Defaults to the active tab if no tabId is provided.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | The ID of the tab to close |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructive behavior (destructiveHint=true) and non-read-only status, so the description does not need to restate that closing destroys a tab. It adds meaningful behavioral context beyond annotations by explaining the active-tab fallback when tabId is omitted.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence that front-loads the core purpose and immediately states the key optional-parameter behavior. There is no filler or repetition of structured annotation fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-optional-parameter destructive action, the description covers what the tool does and the critical edge case (no tabId). Annotations cover the destructive and non-read-only nature, and no output schema is expected for this simple close operation. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, and the tabId parameter is adequately described as 'The ID of the tab to close' in the schema. The tool description adds only the fallback behavior tied to omitting tabId, not new parameter-level semantics, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Close a specific browser tab.' It clearly distinguishes this tool from siblings like open_tab, reload_tab, and focus_tab by naming the action it performs. The default behavior for absent tabId is also stated plainly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear invocation context: use a tabId to target a specific tab, or omit it to close the active tab. It does not explicitly enumerate alternatives or when-not-to-use scenarios, but the verb and sibling set make the intended use obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_scriptADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| scriptId | Yes | The ID of the script to delete |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark destructiveHint=true and readOnlyHint=false, but the description adds meaningful context beyond those flags: deletion is irreversible and ownership restricts deletability. This is valuable behavioral detail not available from the schema or annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three concise sentences with the core action front-loaded and important caveats following immediately. Every sentence adds useful information with no filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive operation with rich annotations and clear descriptions of ownership constraints, this is complete. The description covers the action, irreversibility, and the key edge cases an agent needs to avoid calling delete_script incorrectly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single parameter `scriptId` is already described as 'The ID of the script to delete'. The tool description adds no further parameter-level meaning, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (delete), resource (UserScript or AgentScript from Customaise), and permanence. The scope is clear enough to distinguish from related script tools like import_script, export_script, and toggle_script.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit when-not-to-use guidance: shared/subscribed scripts cannot be deleted via MCP and must be unsubscribed in the extension UI. It also clarifies that owned forks created via import_script(fork:true) are deletable, giving the agent a clear decision rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
export_scriptADestructiveIdempotent
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. 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 UserScripts: Must use an IIFE with named functions for symbol-level editing, `// @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` regardless. Must NOT use IIFEs. CAN use GM_* APIs for persistence, networking, and observability alongside `navigator.modelContext.registerTool()`.| Name | Required | Description | Default |
|---|---|---|---|
| filePath | Yes | Local file path containing the userscript source code | |
| scriptId | No | ID of an existing script to update. Omit to create a new script. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description details the sanitization pipeline (syntax checking, AST validation, security analysis), explains what happens on success vs failure, and reveals the read-only nature of shared/subscribed scripts. It also states that 'allow' resolves as 'prompt' in AgentScripts, which is important behavioral nuance. However, it does not describe exactly what 'destructiveHint: true' implies (e.g., what happens to the previous version on update), and it doesn't mention whether the export overwrites or versions existing scripts. Given annotations already signal destructive/idempotent hints, the description adds substantial context beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear paragraphs and front-loaded purpose. It is longer than ideal, but every sentence adds necessary guidance—especially the script-type reminders. The formatting is scannable with line breaks. Slightly long, but justified by the complexity of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description provides a complete operating picture: purpose, validation pipeline, success/failure behavior, shared-script restrictions, fork workaround, and detailed requirements for both UserScripts and AgentScripts. With no output schema, the description does an excellent job of explaining what to expect (detailed diagnostics on failure, ready-to-execute on success). The contextual signals and sibling list leave few gaps; an agent has enough to select and invoke this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents filePath and scriptId. The description adds critical behavioral meaning to scriptId (update existing vs create new) and clarifies the filePath is 'local file path'. This meaningfully supplements the schema, especially by explaining the update semantics and the fork workflow.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Export' with a specific resource (script from a local file into Customaise), and immediately distinguishes it from import_script (which forks shared scripts). It also explains the create-vs-update behavior via scriptId, so there is no ambiguity about what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use this tool (export a local script, update an existing script via scriptId) and provides an explicit alternative path for shared/subscribed scripts (call import_script with fork:true). It lacks a fully comprehensive when-not-to-use statement for all sibling tools, but the key exclusion—overwriting shared/subscribed scripts—is clearly covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
focus_tabAIdempotent
Bring a specific browser tab to the front and make it active.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | Yes | The ID of the tab to focus |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the concrete behavior—bringing a tab to the front and activating it—which goes beyond the abstract annotations (idempotentHint, destructiveHint). But it does not mention failure behavior for invalid tab IDs or any prerequisites such as the tab being in the same window, leaving some behavioral gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single 11-word sentence that front-loads the action and includes no filler. Every word contributes to the meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one required parameter, a fully described schema, and no output schema, the information provided is sufficient for an agent to invoke it correctly. The sibling tool list_tabs implies where tab IDs come from, completing the context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already provides 100% coverage: tabId is a number described as 'The ID of the tab to focus'. The description adds no additional detail about the parameter itself, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Bring'), a resource ('a specific browser tab'), and the outcome ('to the front and make it active'). This clearly distinguishes it from sibling tools like open_tab (creating/opening a new tab) and close_tab/reload_tab.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied: you use this when you have an existing tab ID and want to bring that tab to the foreground. However, there is no explicit guidance about when not to use it or which alternative to choose (e.g., open_tab for new tabs), so the agent must infer the appropriate context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_bridge_statusARead-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, and how much of the MCP cap is left today and this week. Costs NO cap units, because it reads state the server already holds rather than calling the browser. Check this before a long run so you find out you have three calls left now rather than mid-task.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (readOnlyHint=true, idempotentHint=true, destructiveHint=false), the description discloses that the tool consumes zero cap units and reads state already held by the server rather than calling the browser. This is meaningful behavioral context an agent would not otherwise know.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler: the first captures the tool's full semantic scope, and the second adds cost behavior plus a practical checkpoint. The structure front-loads the core purpose and supports quick agent scanning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter status tool with no output schema, the description is complete: it lists every reported aspect, explains the cap-cost behavior, and gives a concrete when-to-call scenario. An agent has enough to invoke it correctly and interpret its purpose.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters and the schema is trivially 100% covered with no properties. No parameter documentation is needed, so the baseline of 4 for parameterless tools applies; the description correctly focuses on outputs and usage instead.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Report the bridge's own state,' and enumerates the exact state fields it returns (extension attached, plan tier, signed-in status, remote approvals, MCP cap usage). This clearly distinguishes it from sibling tools that operate on tabs, scripts, or WebMCP actions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit guidance: 'Check this before a long run' and explains the economic rationale by noting it costs no cap units. It does not mention when-not-to-use or name an alternative, but for a unique status check the main use case is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_console_contextAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| level | No | Filter by log level. Default: all | |
| tabId | No | Tab ID to get logs from. Defaults to the active tab. | |
| output | No | Where 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". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses a critical side effect beyond the annotations: it writes a full log file to .customaise/console-context.json by default and returns only counts plus the path. It also clarifies that inline output writes nothing to disk. This meaningfully complements the readOnlyHint: false annotation without contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: purpose, recommended usage, side effect, return behavior, and fallback guidance. It is front-loaded with the core purpose before the operational details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Since there is no output schema, the description correctly explains what the tool returns: counts plus the file path by default, or the whole log inline. It also gives enough operational detail for an agent to use the tool safely and effectively without needing more documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all three parameters with 100% coverage, so the baseline is 3. The description adds practical meaning to the output parameter by explaining why you might choose inline instead of file, which goes beyond the schema's enum descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: getting console logs from the browser, including errors, warnings, and userscript GM_log output. It clearly distinguishes the tool's purpose from sibling tools by describing what type of data it retrieves and when to use it.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly recommends using this tool after reload_tab to check for script runtime errors. It also provides clear context for choosing output modes, including when to use inline versus file output. However, it does not name or exclude an alternative sibling tool explicitly.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_page_contextAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Tab ID to inspect. Defaults to the active tab. | |
| output | No | Where 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". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description fully discloses the non-obvious side effect that contradicts what 'get' suggests: 'WRITES A FILE by default' to .customaise/page-context.json, returns only a summary plus path, and explains why (keeping large payloads out of the context window). It also gives the recovery path (view_file/grep_search, or output: "inline" to write nothing). This aligns with readOnlyHint=false and adds context beyond what annotations provide, with no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is about 90 words and front-loads the core purpose before the caveats. Each sentence earns its place: what, when, side effect, path, and fallback. The 'WRITES A FILE' emphasis is effective at flagging the side effect, though behavior of the output parameter is described both here and in the schema, adding slight redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description carries the burden of explaining the return contract, and it does: summary plus path by default, full snapshot for 'inline', exact file location, and how to read it. The only minor gap is that it doesn't describe the structure or size of the snapshot file itself, which could matter for very large pages.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value beyond the schema by explaining how to consume the file output ('Read the file with view_file or grep_search') and the scenario justifying the 'inline' mode (chat client without filesystem tool), enriching the output parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource: 'Get a DOM snapshot of the current page including URL, title, page structure, and visible elements.' This clearly distinguishes it from siblings like get_console_context (console vs page) and get_selected_elements (selection vs whole page), so an agent can tell them apart without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear usage context: 'Use this to understand the page layout before writing userscripts that manipulate it.' It also offers conditional routing guidance ('If you have no filesystem tool, pass output: "inline"'), but it does not explicitly name alternatives or state when not to use this tool versus sibling inspection tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_selected_elementsAIdempotent
Get DOM elements that the user has visually selected in the browser for a specific script. Returns each selection's bulletproof 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.
| Name | Required | Description | Default |
|---|---|---|---|
| scriptId | No | Script ID to get selections for. Omit to get all scripts' selections. | |
| directory | No | Workspace directory for .dom.md files. Required if writeFiles is true. | |
| writeFiles | No | If true, writes .dom.md context files to the workspace directory. Default: false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses the key side effect beyond annotations: file writes only happen when writeFiles: true, and otherwise no filesystem access is needed. It also explains real-time auto-push behavior when MCP is connected, adding useful behavioral context not captured by the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then expands into optional file-writing and MCP integration. It is a bit longer than strictly necessary, but each sentence contributes functional guidance, so the length is justified.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description compensates by summarizing what is returned: selectors, element context, and user comments. It covers the main side effects and usage conditions. It could be more precise about the response shape or error cases, but the core information an agent needs to call it correctly is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds meaning by explaining that the response itself contains the selections, that writeFiles triggers .dom.md file creation, and that directory is tied to that behavior. This goes beyond the raw schema wording.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Get DOM elements that the user has visually selected in the browser for a specific script.' It clearly specifies what is returned (selectors, element context, user comments) and distinguishes itself from file-based retrieval by noting it returns data directly in the response.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use the tool: 'Use this tool to retrieve selections if the auto-pushed files are missing or to get the raw JSON data.' It also explains the alternative auto-push mechanism and points to CM_findElement for downstream targeting, providing clear decision context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| fork | No | When 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. | |
| filePath | Yes | Local file path inside your workspace to write the script to (e.g., ./customaise-scripts/my-script.agent.js). Do NOT use /tmp. | |
| scriptId | Yes | The 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, it discloses that fork always creates a new script, clears subscription/publish links, lands the script disabled, and returns the new scriptId rather than the original. These are side effects an agent cannot infer from readOnlyHint=false or destructiveHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
While long, the description is organized into scannable paragraphs and bullets with no redundant filler; every block adds decision-relevant information. The critical fork behavior is front-loaded before the detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutating tool with no output schema, it explains the key return semantics (returned scriptId is the new script), the file write target, and the error path for subscribed scripts without fork. This gives an agent enough to call and continue the edit/export workflow safely.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all three parameters, and the description adds meaningful operational nuance: what 'fork' means for owned vs shared sources, the lineage/publishedShareId clearing, and the D10 disabled-landing behavior. It also reinforces the filePath rule about workspace-relative paths, which is directly actionable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource ('Import a Customaise script... to a local file for editing') and clearly identifies the output as full source with metadata block. The contrast with export_script in the first paragraph distinguishes it from the obvious sibling without ambiguity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names export_script as the follow-up for pushing changes, and specifies the exact condition for using fork (subscribed/shared sources) plus the refusal behavior when fork is omitted. This tells an agent not just what the tool does but when it is the right call.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_scriptsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description adds meaningful behavioral context beyond those: it discloses that isShared scripts cannot be imported, exported, or deleted directly, and explains how to work around that (fork or UI unsubscribe). With no output schema present, the description also carries the burden of describing return fields, which it does thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each earning its place: the first states the primary action and output, the second explains the shared-script constraint, and the next two give targeted next steps. It is front-loaded with the main purpose and contains no fluff or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a parameterless read-only tool with no output schema, the description is fully complete: it specifies what the tool returns, identifies the isShared edge case, and covers the two relevant follow-up actions (forking and unsubscribing). An agent has everything needed to invoke it correctly and interpret its results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so the baseline is 4 and there are no parameter semantics to clarify. The description adds no parameter-related details because none exist, and no further compensation is needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'List all scripts (UserScripts & AgentScripts) installed in Customaise', and enumerates the exact returned fields (IDs, names, enabled status, match patterns, shared status). This clearly differentiates it from sibling list tools like list_tabs and list_webmcp_tools, which target different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear contextual guidance: it explains that shared scripts are read-only subscriptions and explicitly directs the agent to import_script with fork:true for editing and to the extension UI for uninstalling. It does not explicitly contrast with sibling listing tools, but the usage context is unambiguous and names an alternative tool where relevant.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_tabsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds the concrete output fields but no additional behavioral traits beyond what the annotations establish, so it does not need to over-explain.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no fluff. It leads with the core action and output fields, then immediately states the practical use case for finding tab IDs.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter read-only listing tool, the description is complete. It names the output fields (IDs, URLs, titles, active status) and explains why that output matters by linking to sibling tools. No output schema exists, but the description covers the essential return information.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics for the description to clarify. The schema is complete and the description adds all relevant context about what the tool returns.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb, 'List', and identifies the resource, 'all open browser tabs', along with the exact fields returned: IDs, URLs, titles, and active status. It clearly distinguishes this tool from action-oriented siblings like open_tab, close_tab, and reload_tab.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context: use this tool to find a tab ID for downstream tools like reload_tab or take_screenshot. It does not explicitly discuss when not to use it or compare it to alternative list tools, but there is no real sibling alternative for listing tabs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_webmcp_toolsARead-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.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Tab ID to query. Defaults to the active tab. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds significant behavioral detail beyond the readOnlyHint/idempotentHint annotations: it discloses that each entry carries a permission field, that 'prompt' blocks on a consent modal for up to 5 minutes, and that 'deny' fails immediately. It also advises the agent to proactively inform the user about calls requiring approval, which is beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and purpose, followed by targeted behavioral guidance. Every sentence adds value, including the permission-field warning, without redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple optional-parameter list tool with no output schema, the description adequately explains what the tool returns conceptually (entries with permission fields) and how to act on it. It does not enumerate all potential output fields, but the key decision-relevant information is present.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents the single optional tabId parameter with 100% coverage. The description mentions the tab target but does not add format, default, or usage details beyond the schema, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('List'), a resource ('WebMCP tools'), and a scope ('for a specific browser tab'). It also names the verification use case, which clearly distinguishes it from sibling tools like call_webmcp_tool, list_scripts, and get_bridge_status.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use it: to verify that an exported AgentScript is correctly registering its tools on the target page. It gives clear context but does not explicitly state when not to use it or name alternative tools, so it misses the exclusionary guidance needed for a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | The URL to open in the new tab | |
| active | No | Whether 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. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description reveals that the tab opens in the background by default to avoid disrupting the user, which is behavior not captured by readOnlyHint, openWorldHint, or destructiveHint. It also discloses the return value. This is useful behavioral context that annotations alone do not provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise, front-loaded with the core action, and each sentence adds distinct value: what it does, the default behavior and rationale, and the return value. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple two-parameter action tool with full schema coverage and relevant annotations, the description is complete: it covers behavior, default semantics, return value, and user impact. No output schema is required since the return type is mentioned explicitly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the parameters are fully documented in the schema. The description adds a brief user-context rationale for the background default, but largely reiterates what the schema already states, so it does not significantly elevate parameter understanding beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Open') and resource ('a new browser tab') with the specified URL, which distinguishes it from sibling tools like close_tab, list_tabs, and focus_tab. It also mentions returning the new tab ID, adding useful purpose specificity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context on default behavior (background opening) and explains when the 'active' parameter should be set to true, helping the agent decide appropriate usage. It does not explicitly reference alternative sibling tools, but the context is sufficient for this simple operation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
reload_tabAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Tab ID to reload. Defaults to the active tab. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses two important behaviors: it waits for the page to fully load before returning, and it waits for AgentScript/WebMCP tools to re-register. This is genuinely useful stateful behavior that an agent could not infer from the schema or annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences with no filler: purpose, usage context, and blocking behavior are each given exactly one sentence. The most important information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single optional-parameter utility, the description covers what it does, when to use it, and its blocking/registration behavior. No return value or output schema is needed for an operation whose main result is the reload itself.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the only parameter, tabId, is already documented as defaulting to the active tab. The tool description adds no additional parameter semantics, which is acceptable given the high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource — 'Reload a browser tab' — and adds the precise purpose 'to re-inject updated userscripts.' This clearly distinguishes it from siblings like open_tab, close_tab, and focus_tab.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly says to use this tool after export_script to see the effect of changes, giving a concrete workflow context. It does not mention when not to use it or name alternatives, so it falls just short of full usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sync_scriptsADestructiveIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| directory | Yes | Local directory to export scripts to (e.g., ./customaise-scripts/) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes well beyond the destructiveHint/readOnlyHint annotations by detailing the exact side effects: it writes many files, overwrites matching local files, permanently loses unexported local edits, and creates a .customaise-manifest.json. It also explains shared/subscribed script exclusion. This is precisely the kind of behavioral context that annotations alone cannot provide, and there is no contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: the action, the destructive warning with its consequence, the manifest artifact, the exclusion rule, and the recommended use case. The warning is front-loaded after the first sentence and uses clear emphasis without becoming filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter, bulk file-export tool, the description fully covers what the tool does, what it destroys, what it creates, what it excludes, and when to use it. There is no output schema, but the outcome is described through its filesystem effects and the manifest, so an agent has enough information to select, parameterize, and predict the operation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents the only parameter with 100% coverage, including an example value ('./customaise-scripts/'). The description reinforces that scripts go 'to a local directory' and adds file-extension details, but it does not materially deepen the meaning of the directory parameter beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence clearly states a specific verb ('Bulk export'), a resource ('all your own scripts from Customaise'), and a concrete result ('to a local directory as individual .user.js or .agent.js files'). It also distinguishes itself from siblings by emphasizing bulk operation over all own scripts and explicitly excluding shared/subscribed scripts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit intended use case ('set up a local workspace for editing scripts with your IDE') and makes the exclusion of read-only shared/subscribed scripts clear. However, it does not explicitly name a single-script alternative like export_script or state when not to use sync_scripts, so the routing guidance is strong but not fully explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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).
| Name | Required | Description | Default |
|---|---|---|---|
| tabId | No | Tab ID to screenshot. Defaults to the active tab. | |
| output | No | Where 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". | |
| filePath | No | Local file path to save the screenshot. Auto-generates a temp path if omitted. Ignored when output is "inline". | |
| fullPage | No | If true, capture the entire scrollable page (single tall PNG). If false or omitted, capture the visible viewport only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses side effects not inferable from annotations: writes a PNG file by default, returns a path rather than image bytes, and shows a transient Chrome devtools notice for background/full-page captures. This complements the readOnlyHint=false annotation rather than contradicting it.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and focus-stealing constraint, then covers full-page capture, file behavior, inline fallback, and the transient notice. Each sentence adds distinct information and the length is proportionate to the tool's behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no output schema, the description adequately covers return behavior in both output modes and the key side effect of writing to disk. Defaults such as active tab, visible viewport, and file output are specified either in the description or schema, so an agent has what it needs to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema already documents all parameters at 100% coverage, so the baseline is 3; the description adds useful behavior around filePath auto-generation and inline image attachment. It clarifies what output modes return without repeating schema syntax.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific action (capture a screenshot), a resource (browser tab), and a notable constraint (without stealing focus). It is clearly distinct from sibling tab tools like reload_tab and close_tab, even though no alternative screenshot tool exists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit selection guidance: default viewport vs fullPage: true, and file output vs inline output with the condition 'If you have no filesystem tool'. This tells an agent exactly when to use each mode.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
toggle_scriptAIdempotent
Enable or disable a userscript. Disabled scripts are not injected into matching pages. Use this to temporarily turn off a script without deleting it.
| Name | Required | Description | Default |
|---|---|---|---|
| enabled | Yes | true to enable, false to disable | |
| scriptId | Yes | The ID of the script to enable/disable |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate a non-read-only, idempotent, non-destructive mutation. The description adds a behavioral consequence beyond the schema: disabled scripts are not injected into matching pages. This gives agents useful context about the real effect of disabling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, each earning its place: the action, the behavioral effect, and the intended use case. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple toggle tool with two required parameters and annotations covering mutability, idempotence, and destructiveness, the description is complete enough for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, and both parameters are clearly described in the schema itself. The description adds no new parameter-level detail, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb pair (enable/disable) with a clear resource (userscript), and distinguishes itself from deletion by explicitly noting this does not delete the script. This is enough to separate it from delete_script and list_scripts.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states the intended use case: temporarily turning off a script without deleting it. It does not enumerate alternatives or explicit when-not-to-use conditions, but the contrast with deletion makes the primary usage context clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
toggle_uiAIdempotent
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.
| Name | Required | Description | Default |
|---|---|---|---|
| panel | No | Panel to open: "scripts", "chat", "settings" | |
| tabId | No | Tab ID to toggle UI on. Defaults to the active tab. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description frames the tool as a visibility toggle: 'Show or hide' and 'make the Customaise interface visible or dismiss it.' A toggle is inherently non-idempotent because the effect of a second call depends on the current state. This directly contradicts the annotation idempotentHint: true, which tells the agent that repeated identical calls produce the same outcome. An agent could call the tool twice expecting no change and end up reversing the UI state.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact at two sentences and front-loads the core action. There is slight redundancy between 'Show or hide' and 'make the Customaise interface visible or dismiss it,' which prevents a perfect conciseness score.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a small tool with two optional parameters and no output schema, the description covers what it acts on, where it acts, when to use it, and the optional panel behavior. It does not explain return values, but that is not critical for a UI toggle tool. The main contextual gap is the misleading idempotence annotation, already captured in behavioral transparency.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the parameters are already fully documented: panel has its allowed values and tabId defaults to the active tab. The description mostly restates this ('active tab', 'Optionally specify which panel to open') without adding new semantic detail beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a concrete action ('Show or hide') on a specific resource ('the Customaise UI overlay on the active tab'). It also distinguishes itself from sibling tools like toggle_script by making clear it controls the UI overlay, not a script. The mention that AI agents cannot click the extension icon directly adds useful purpose context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit use case: make the Customaise interface visible or dismiss it, including why this tool is necessary for AI agents. It does not enumerate when-not-to-use cases or explicitly contrast with alternatives such as toggle_script, so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
19 tool updates
v3.2.0- First observed
call_webmcp_tool - First observed
close_tab - First observed
delete_script - First observed
export_script - First observed
focus_tab - First observed
get_bridge_status - First observed
get_console_context - First observed
get_page_context - First observed
get_selected_elements - First observed
import_script - First observed
list_scripts - First observed
list_tabs - First observed
list_webmcp_tools - First observed
open_tab - First observed
reload_tab - First observed
sync_scripts - First observed
take_screenshot - First observed
toggle_script - First observed
toggle_ui
TDQS
Each tool maps to a distinct action, and the long descriptions clearly disambiguate edge cases like shared scripts and import/export direction. The only real risk is that import_script, export_script, and sync_scripts all move files in different directions and could be confused if an agent reads only the names.
The set overwhelmingly follows a snake_case verb_noun pattern: list_*, get_*, toggle_*, *_tab, *_script. The main deviation is that sync_scripts and list_webmcp_tools use plurals, and 'export' appears in both directions across export_script and sync_scripts.
At 19 tools this sits in the 16-25 range that feels heavy for an MCP surface. The breadth is defensible because script editing, browser tab control, context capture, and WebMCP execution all need coverage, but the count is still on the high side.
The script lifecycle (list, import, export, delete, toggle, sync, fork) and tab lifecycle (list, open, close, reload, focus, screenshot) are both well covered. Minor gaps remain around creating a brand-new script without a local file and unsubscribing from shared scripts, but these are workaroundable via export_script and the extension UI.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Live browser debugging for AI assistants — DOM, console, network via MCP.
A paid remote MCP for AI agent browser DevTools MCP, built to return verdicts, receipts, usage logs,
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Your org's AI agents, tasks, runs, search, and brain files as MCP tools and resources.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to programmatically control and automate VSCode by interacting with its UI, executing commands, and inspecting the DOM structure. It supports advanced workflows like UI testing, extension development, and debugging through a standalone VSCode instance.108MIT
- FlicenseNot gradedqualityDmaintenanceLets any MCP-capable coding agent drive your real, logged-in Chrome through a local MCP server and MV3 extension.5-
- AlicenseNot gradedqualityCmaintenanceLets AI coding agents control and inspect a live Chrome browser via MCP, providing Chrome DevTools capabilities for automation, debugging, and performance analysis.17Apache 2.0
- AlicenseNot gradedqualityDmaintenanceBridges a browser extension with an AI agent via MCP, enabling the agent to capture and act on UI elements, styles, and accessibility data from web pages.18ISC
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/getcustomaise/customaise-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server