{"id":49626528,"url":"https://github.com/getcustomaise/customaise-mcp","last_synced_at":"2026-05-05T08:00:16.478Z","repository":{"id":346251110,"uuid":"1189158451","full_name":"getcustomaise/customaise-mcp","owner":"getcustomaise","description":"MCP server bridging AI coding agents (Cursor, Claude Code, Codex, Windsurf, Kiro, Antigravity) to the Customaise Chrome extension. 18 tools: UserScripts, AgentScripts, WebMCP calls with HITL consent, visual DOM targeting, tab control.","archived":false,"fork":false,"pushed_at":"2026-04-19T22:40:37.000Z","size":44,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T00:33:26.286Z","etag":null,"topics":["agentscripts","ai-tools","antigravity","browser-automation","chrome-extension","claude-code","codex","cursor","customaise","hitl","kiro","mcp","model-context-protocol","userscripts","webmcp","windsurf"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@customaise/mcp","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/getcustomaise.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-23T03:12:55.000Z","updated_at":"2026-04-19T22:40:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/getcustomaise/customaise-mcp","commit_stats":null,"previous_names":["getcustomaise/customaise-mcp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/getcustomaise/customaise-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getcustomaise%2Fcustomaise-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getcustomaise%2Fcustomaise-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getcustomaise%2Fcustomaise-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getcustomaise%2Fcustomaise-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/getcustomaise","download_url":"https://codeload.github.com/getcustomaise/customaise-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/getcustomaise%2Fcustomaise-mcp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32640538,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-04T10:08:07.713Z","status":"online","status_checked_at":"2026-05-05T02:00:06.033Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentscripts","ai-tools","antigravity","browser-automation","chrome-extension","claude-code","codex","cursor","customaise","hitl","kiro","mcp","model-context-protocol","userscripts","webmcp","windsurf"],"created_at":"2026-05-05T08:00:15.552Z","updated_at":"2026-05-05T08:00:16.449Z","avatar_url":"https://github.com/getcustomaise.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @customaise/mcp\n\nMCP server that connects AI coding agents to the [Customaise](https://customaise.com) Chrome extension. Manage UserScripts, build AgentScripts, call WebMCP tools inside the user's signed-in browser session, select DOM elements visually, and drive tabs directly from your IDE.\n\n**18 tools, 5 resources, WebSocket bridge** between your IDE and a real Chrome session.\n\n```\nAI Agent ←(stdio)→ MCP Server ←(WebSocket)→ Customaise Extension\n```\n\n## Quick Start\n\n### 1. Install Customaise\nInstall the [Customaise Chrome extension](https://customaise.com) and enable **MCP Bridge** in Settings.\n\n### 2. Add to your IDE\n\n**Cursor** (`.cursor/mcp.json`):\n```json\n{\n  \"mcpServers\": {\n    \"customaise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@customaise/mcp\"]\n    }\n  }\n}\n```\n\n**Claude Desktop** (`claude_desktop_config.json`):\n```json\n{\n  \"mcpServers\": {\n    \"customaise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@customaise/mcp\"]\n    }\n  }\n}\n```\n\n**Windsurf** (`.windsurf/mcp.json`):\n```json\n{\n  \"mcpServers\": {\n    \"customaise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@customaise/mcp\"]\n    }\n  }\n}\n```\n\n**Kiro** (`.kiro/mcp.json`):\n```json\n{\n  \"mcpServers\": {\n    \"customaise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@customaise/mcp\"]\n    }\n  }\n}\n```\n\n**Codex** (`~/.codex/config.toml`):\n```toml\n[mcp_servers.customaise]\ncommand = \"npx\"\nargs = [\"-y\", \"@customaise/mcp\"]\n```\n\n**Antigravity** (`mcp_config.json`):\n```json\n{\n  \"mcpServers\": {\n    \"customaise\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@customaise/mcp\"]\n    }\n  }\n}\n```\n\n### 3. Done\nYour 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.\n\n## Tools (18)\n\n### Script Lifecycle\n| Tool | Description |\n|------|-------------|\n| `list_scripts` | List every script (UserScripts and AgentScripts) managed by the extension |\n| `import_script` | Pull a script to a local file for editing |\n| `export_script` | Push a local file to Customaise (validates and installs) |\n| `delete_script` | Permanently delete a script |\n| `toggle_script` | Enable or disable a script |\n\n### Browser Context\n| Tool | Description |\n|------|-------------|\n| `get_page_context` | DOM snapshot of the current page |\n| `get_console_context` | Console logs, errors, and `GM_log` output |\n| `list_tabs` | List all open browser tabs |\n\n### Tab Control\n| Tool | Description |\n|------|-------------|\n| `open_tab` | Open a new tab at a given URL |\n| `close_tab` | Close a tab by ID |\n| `focus_tab` | Switch focus to a tab by ID |\n| `reload_tab` | Reload a tab to re-inject scripts |\n\n### Visual DOM Targeting\n| Tool | Description |\n|------|-------------|\n| `get_selected_elements` | Get the DOM elements the user has visually selected, with bulletproof selectors and screenshots |\n| `take_screenshot` | Capture the visible tab, optionally highlighting specific elements |\n\n### WebMCP Agent Tools\n| Tool | Description |\n|------|-------------|\n| `list_webmcp_tools` | List the WebMCP tools currently registered on a tab by AgentScripts |\n| `call_webmcp_tool` | Call a WebMCP tool; prompt-gated tools block on user consent (see below) |\n\n### UI Control \u0026 Batch\n| Tool | Description |\n|------|-------------|\n| `toggle_ui` | Show or hide the Customaise UI overlay |\n| `sync_scripts` | Bulk export all scripts to a local directory |\n\n## Resources (5)\n\nFive 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.\n\n| URI | Description |\n|-----|-------------|\n| `customaise://scripts` | Live JSON list of every script the extension manages (ID, name, enabled state, match patterns, shared flag) |\n| `customaise://scripts/{scriptId}` | Full source and metadata for a specific script |\n| `customaise://conventions` | Points at the right handbook for the script type you're working on |\n| `customaise://userscript-conventions` | Full UserScript reference: file structure, IIFE pattern, `GM_*` APIs, symbol-level editing, `@match` and `@namespace` rules |\n| `customaise://agentscript-conventions` | Full AgentScript reference: the `// ==AgentScript==` block, `// @webmcp \u003ctool\u003e \u003cpermission\u003e` declarations, `navigator.modelContext.registerTool()`, consent model |\n\n## WebMCP Tool Calls \u0026 Consent (HITL)\n\nAgentScripts register tools on web pages via `navigator.modelContext.registerTool(...)`. Each tool is declared in the AgentScript's `// @webmcp \u003ctoolName\u003e \u003cpermission\u003e` header with one of three permissions:\n\n- **`allow`**: tool executes immediately. ~50 to 100ms round-trip per call (the extension still runs permission checks).\n- **`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 long `call_webmcp_tool` as normal.\n- **`deny`**: tool is suppressed and calls fail immediately.\n\n\"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.\n\n### Remote approvals (optional)\n\nIf 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.\n\n### What MCP clients see\n\n- A prompt-gated `call_webmcp_tool` response may take up to 5 minutes. Surface a pending state to the end user rather than timing out aggressively.\n- If the user denies, `call_webmcp_tool` returns an error. The MCP server does not retry.\n- 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](https://customaise.com/privacy).\n\n## Visual DOM Selection\n\nUsers can visually select elements in the browser, and the extension pushes context files to your workspace in real time:\n\n```\n.customaise/dom-context/\u003cscript-name\u003e/\n├── element-name.dom.md          # Selectors, element context, user comments\n├── element-name.screenshot.png  # Cropped screenshot of the selected element\n└── ...\n```\n\n\u003e [!NOTE]\n\u003e **Where are the files saved?**\n\u003e The MCP server writes `.customaise/` to its current working directory (usually your project root in Cursor or Windsurf).\n\u003e 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:\n\u003e\n\u003e ```json\n\u003e \"env\": { \"CUSTOMAISE_WORKSPACE\": \"/absolute/path/to/your/project\" }\n\u003e ```\n\nUse `get_selected_elements` to retrieve selections programmatically, or read the pushed `.dom.md` files directly from the workspace.\n\nEach selection includes **bulletproof tiered selectors** (stable IDs → data attributes → ARIA → semantic classes → structural positioning) so targeting survives page updates.\n\n## Workflows\n\n### UserScript\n\n```\n1. get_page_context       → understand the target page\n2. User selects elements  → .dom.md files auto-pushed to workspace\n3. Write .user.js file    → AI writes the script using IDE tools\n4. export_script          → Customaise validates and installs\n5. reload_tab             → re-inject the script\n6. get_console_context    → check for errors\n7. take_screenshot        → verify the visual result\n```\n\n### AgentScript\n\n```\n1. Read customaise://agentscript-conventions   → get the structure right before writing\n2. get_page_context                            → find stable selectors on the target page\n3. Write .agent.js file                        → declare tools via // @webmcp, register with navigator.modelContext.registerTool()\n4. export_script                               → Customaise validates and injects\n5. reload_tab                                  → the AgentScript registers its tools in the page\n6. list_webmcp_tools                           → confirm tools surfaced\n7. call_webmcp_tool                            → invoke one; prompt-gated calls wait for user consent\n```\n\n## File Sync\n\nUse `sync_scripts` to bulk-export every script to a local directory:\n\n```\nsync_scripts({ directory: \"~/customaise-scripts\" })\n```\n\nThis creates:\n- **One `.user.js` file per script.** Filename is derived from the script name (lowercase, hyphens, e.g. `my-cool-script.user.js`).\n- **`.customaise-manifest.json`**: maps filenames to script IDs for round-trip editing.\n\n### Manifest format\n\n```json\n{\n  \"dark-mode-fix.user.js\": \"vm_script_1774225715376_lus75sdzn\",\n  \"my-cool-script.user.js\": \"vm_script_1774225800123_abc12defg\"\n}\n```\n\n### Round-trip\n\n1. `sync_scripts` exports all scripts to a directory.\n2. Edit any `.user.js` file in your IDE.\n3. `export_script` with the file path and `scriptId` from the manifest updates that script.\n4. Omit `scriptId` when calling `export_script` to create a new script instead.\n\n### File watcher (auto-export)\n\nOnce `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.\n\n## Configuration\n\n| Environment Variable | Default | Description |\n|---------------------|---------|-------------|\n| `CUSTOMAISE_WS_PORT` | `4050` | WebSocket server port |\n| `CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS` | _(empty)_ | Comma-separated list of extra extension IDs allowed to connect. Needed for unpacked dev builds with a non-standard extension ID |\n| `CUSTOMAISE_MCP_ALLOW_INSECURE` | _(unset)_ | Set to `1` to disable the origin allowlist. **Tests only.** Emits a loud warning at startup |\n| `CUSTOMAISE_WORKSPACE` | _(cwd)_ | Absolute path where `.customaise/` files should be written. Useful for IDEs that don't set cwd to the project root (Claude Desktop, Antigravity) |\n\n## Security Boundary\n\nThe MCP server listens on `ws://localhost:4050` in plaintext on your loopback interface. The connection is authenticated by an **HTTP Origin header allowlist**:\n\n- **Allowed**: `chrome-extension://anmpijcpaobaabcdncjjmnhdeibipmko` (production) and `chrome-extension://ijjaffggglamocdapoihpkcpealflopp` (staging). Chrome stamps this header automatically on WebSocket handshakes from extension service workers; you don't configure anything.\n- **Rejected**: regular web pages (`https://...`), unknown extension IDs, and handshakes with no Origin header. Returns HTTP 403.\n\n**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.\n\n**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.\n\n**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, so only install AgentScripts from sources you trust.\n\n**Dev builds**: if you load an unpacked extension with a custom key, set `CUSTOMAISE_MCP_EXTRA_EXTENSION_IDS=\u003cyour-extension-id\u003e` in the MCP server's env.\n\n## Requirements\n\n- **Node.js** ≥ 18\n- **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)\n- **MCP Bridge** enabled in Customaise Settings (free, signed-in)\n\n## Plan tiers\n\nThe 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.\n\nWhen the cap fires, the server returns a JSON-RPC error in the implementation-defined `-32029` slot with 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 `-32028 MCP_AUTH_REQUIRED`.\n\n## Troubleshooting\n\n**\"Customaise extension is not connected\"**\n- Make sure Chrome is running with the Customaise extension.\n- Check that MCP Bridge is enabled in extension Settings.\n- The extension connects automatically within a few seconds.\n\n**Port conflict on 4050**\n- Set a different port: `CUSTOMAISE_WS_PORT=4051 npx @customaise/mcp`.\n\n**Scripts not running after export**\n- Call `reload_tab` to trigger script re-injection.\n- Check the `@match` pattern covers the current URL.\n\n**`call_webmcp_tool` hangs for minutes**\n- 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.\n\n**`call_webmcp_tool` returned an error like \"consent denied\"**\n- 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.\n\n**`list_webmcp_tools` returns empty after a reload**\n- Walk the conventions handbook's troubleshooting checklist. Most common: the global AgentScripts toggle in Customaise Settings is off, or the `@match` pattern doesn't cover the URL. See `customaise://agentscript-conventions` for the full list.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetcustomaise%2Fcustomaise-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgetcustomaise%2Fcustomaise-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgetcustomaise%2Fcustomaise-mcp/lists"}