custom-chrome-dev-mcp
Allows AI agents to drive a real Google Chrome browser through a Chrome extension, providing tools for navigation, tab management, accessibility-based perception, trusted user input (real clicks, typing, keystrokes), screenshots, and observability.
Click 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., "@custom-chrome-dev-mcpUse trusted input to fill the login form in the current tab with saved credentials and submit."
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.
Custom Chrome Dev MCP
A local-only MCP (Model Context Protocol) server that lets an MCP client - Claude Code, or anything else that speaks MCP - drive your real Chrome browser the way a person would. No telemetry, no third-party services, no cloud: everything runs on your machine behind a shared token.
It exposes 45 tools across navigation, tabs, perception, interaction, trusted input, observability, and capture.
Where this came from
This project is inspired by Chrome's official browser MCP - the Chrome DevTools MCP server published by the Chrome DevTools team, which first made the case that an AI agent should drive a browser through the DevTools Protocol rather than through scraped HTML.
We are replicating and imitating that idea, not shipping it. What we borrowed:
The premise - expose the browser to an agent as a set of MCP tools.
Accessibility-first perception - hand the model a compact a11y outline with stable element refs instead of a wall of raw HTML.
The Chrome DevTools Protocol as the input layer - real, trusted events instead of synthetic ones a page can spot and ignore.
Where this project deliberately diverges:
Chrome DevTools MCP | Custom Chrome Dev MCP | |
Browser | By default launches its own Chrome with a dedicated user-data-dir; can also attach to a running instance via | Only ever drives the Chrome you already have open |
Attachment | Connects to the browser over the DevTools Protocol endpoint | A Chrome extension living inside the browser, pointed at whatever tab you choose |
Primary goal | Debugging, inspecting, and profiling a page | Behaving like a human using that page |
That last row is the whole point of this repo. Chrome DevTools MCP is a debugging tool that happens to drive a browser; this is an imitation-of-a-person tool that happens to be useful for debugging.
⚠️ Not affiliated with, endorsed by, or supported by Google or the Chrome team. This is an independent reimplementation built to learn from and imitate their design. Use the official server if you want the supported thing.
Related MCP server: monkeysee
It deliberately keeps the styling of a human
Most browser automation is trivially detectable: synthetic events with
isTrusted=false, focus that never really moves, text that appears in a field all at
once, a pristine automation profile with no history. Every one of those is a signal.
This project tries to remove those signals:
Your real profile. Actions run in the Chrome you already use - your cookies, logins, extensions, and history. Nothing to fingerprint as "fresh automation".
Trusted input.
realClick,realType,press,hover, anddragdispatch through the DevTools Protocol, so the page receives events withisTrusted=true- the same flag a physical mouse and keyboard produce.Genuine focus. Clicking to focus a field really moves focus, in order, rather than assigning
.valuebehind the page's back.Real keystrokes.
pressemits properrawKeyDown/char/keyUpsequences with correct key codes and modifiers, not a single syntheticinputevent.Read-back verification.
fillconfirms the field actually holds the text, so the agent notices when a page silently rejected the input - as a person would.
The goal: a page should behave for the agent exactly as it behaves for someone sitting at the keyboard.
Fast synthetic tools (click, type) are still there - they're quicker and work on
most sites. When a page ignores them, reach for the trusted equivalents.
How it works
One transport. The MCP client talks to the server over stdio; the server relays to a Chrome extension over a local WebSocket owned by a small long-lived hub process.
MCP client 1 (Claude) <-stdio-> bin/custom-chrome-dev-mcp.js ─┐
MCP client 2 (Claude) <-stdio-> bin/custom-chrome-dev-mcp.js ─┼─ src/hub.js (127.0.0.1:9876)
MCP client N (Claude) <-stdio-> bin/custom-chrome-dev-mcp.js ─┘ │
│ WebSocket
▼
Chrome extension -> active tabWhy a separate hub process. Only one process can own port 9876, but you may
have several Claude sessions open and all of them may want the browser. So the socket
lives in src/hub.js rather than inside any one session. Each session connects to the
hub as role:"mcp", the extension connects as role:"extension", and the hub
multiplexes between them. The first session to start spawns the hub detached, so
it outlives that session; later sessions find it already listening.
Inside the extension there are three layers:
Walker (
page/walker.js) - injected into the page's ISOLATED world. Owns element resolution, the stableeNref map, and the fast synthetic DOM ops.CDP (
cdp/) -chrome.debuggerfor trusted input, page-contextevaluate, full-page screenshots, and the console/network buffers.Recording (
recording/) - CDP screencast frames encoded to.webmby aMediaRecorderin an offscreen document.
🔒 The extension authenticates to the hub with a shared token (
AUTH_TOKEN, identical insrc/config.jsandextension/src/config.js). The hub drops any peer that presents a different value.
Prerequisites
Requirement | Check | |
Node.js | 18 or newer (developed on 22) |
|
Chrome | Google Chrome or Chromium, any recent version |
|
An MCP client | Claude Code, or anything else that speaks MCP over stdio |
|
No global installs, no build step, no service to sign up for. Two runtime dependencies
(@modelcontextprotocol/sdk and ws) and everything stays on 127.0.0.1.
Local setup
Four steps, then a verification pass. Budget five minutes.
1. Clone and install
git clone <your-fork-url> custom-chrome-dev-mcp
cd custom-chrome-dev-mcp
npm installConfirm the tree is healthy before wiring anything to Chrome - the offline lane needs no browser and takes under a second:
npm testYou want 22 passed. If that fails, fix it before continuing; nothing downstream will
work.
2. Load the extension into Chrome
Open
chrome://extensions.Turn on Developer mode (top-right toggle).
Click Load unpacked and select the
extension/folder - the folder itself, notmanifest.jsoninside it.Custom-chrome-dev-mcp appears in the list.
⚠️ Load it into the Chrome profile you actually browse in. Chrome keeps extensions per profile, so an extension loaded into "Profile 4" is invisible to the window running under "Default". If tools later report no tabs, or the hub never logs
extension connected, this is the first thing to check.chrome://versionshows the active Profile Path.
The extension ID is pinned by the public key in extension/manifest.json, so it is
identical on every machine - nothing to copy between setups.
3. Register the MCP server with your client
Use the CLI - substitute the absolute path where you cloned the repo (pwd in the
project root prints it):
claude mcp add -s user custom-chrome-dev-mcp -- node /ABSOLUTE/PATH/TO/custom-chrome-dev-mcp/bin/custom-chrome-dev-mcp.js-s userregisters it for all your projects;-s locallimits it to this one.Register
bin/custom-chrome-dev-mcp.js- that file is the entry point. Pointing atsrc/server.jswill not work.The path must be absolute. A relative path resolves against whatever directory the client happened to launch from.
Confirm with
claude mcp list- you want a✔ Connectednext to it.
⚠️ Do not hand-edit
~/.claude.json. It is large, and one misplaced comma breaks Claude Code entirely. The command above edits it safely.
Add the server under mcpServers:
{
"mcpServers": {
"custom-chrome-dev-mcp": {
"command": "node",
"args": ["/ABSOLUTE/PATH/TO/custom-chrome-dev-mcp/bin/custom-chrome-dev-mcp.js"]
}
}
}4. Restart the MCP client
MCP clients enumerate tools once, at startup - a server registered mid-session is invisible until you restart. Restart Claude, and the 45 tools appear.
On restart the client launches the server, which spawns src/hub.js if nothing is
already listening on 127.0.0.1:9876.
5. Verify all three links in the chain
The stack is client → server → hub → extension → tab. Check it end to end rather than guessing which link is down.
# The hub is up, and the extension found it:
tail -f "$TMPDIR/custom-chrome-dev-mcp-hub.log"
# [hub] listening on 127.0.0.1:9876
# [hub] extension connected <- this line is the handshake succeeding
# Who owns the port (should be src/hub.js from THIS repo):
lsof -nP -iTCP:9876 -sTCP:LISTENThen ask your client for listTabs. A JSON array of your open tabs means every
link works. Follow it with screenshot - a PNG lands in ~/Downloads and comes
back inline.
For the extension's own console: chrome://extensions → Custom-chrome-dev-mcp →
service worker → Inspect. That is where extension-side errors surface; they
never reach the MCP client.
6. Change the shared token before real use
AUTH_TOKEN ships with a default value, defined identically in src/config.js and
extension/src/config.js. It is the only thing stopping another process on your
machine from driving your logged-in browser. Pick your own value, change it in both
files (an offline test asserts they match), and reload the extension.
After you change code
The two halves reload differently, and getting this wrong wastes more time than anything else in the project:
You edited | To pick it up |
Anything under | Click reload ↻ on the extension in |
Anything under | Restart the MCP client. The server process is long-lived and holds the old tool schemas. |
|
|
Troubleshooting
Symptom | Cause | Fix |
| Wrong path, or not the | Re-register with the absolute path to |
Tools missing from the client entirely | Registered mid-session | Restart the MCP client |
Hub log never says | Extension not loaded, loaded in a different Chrome profile, or | Check |
A tool call hangs, then times out | The service worker died, or an extension-side exception | Open the service worker console; click reload ↻ |
Port | A hub from another clone of this project is squatting the port |
|
An edit to | Chrome is still running the old build | Click reload ↻ |
|
| Edit the list - it ships with placeholder entries |
| The | Drop the guard, or point it at the real URL |
Screenshot path rejected | Writes are confined to the capture directory | Use a filename or a path inside it |
A tool targets the wrong tab | A background tab stole focus | Pin the working tab with |
Configuration
Both are optional environment variables read at startup by src/config.js.
Variable | Default | What it does |
|
| The only directory screenshots and recordings may be written to. |
|
| Hub port. Change it in |
Also worth changing for real use: AUTH_TOKEN, defined identically in
src/config.js and extension/src/config.js. Pick your own value - it is what stops
another local process from driving your browser.
Available tools (45)
Elements are targeted three ways: selector (CSS), ref (a stable eN id
from snapshotA11y), or name (accessible name, e.g. a button's label). "target"
below means any one of those three.
Universal params, accepted by every tool:
tabId- act on a specific tab instead of the ambient active one.frameId(fromlistFrames) - act inside a specific frame, including cross-origin iframes the top document cannot script.expectUrl- a guard: refuse the action unless the tab's URL contains this substring.
Pin a working tab for the whole session with useTab so a background tab (an
autoplaying video, a notification popup) can't steal focus and misdirect an action.
Navigation
Tool | Args | Description |
|
| Point the tab at a URL (replaces the page). |
|
| Open a URL in a new foreground tab, leaving the current page intact. |
| - | History back / forward. |
|
| Reload, optionally bypassing the cache. |
| - | The tab's URL / title (works on internal pages too). |
|
| Block until the tab finishes loading. |
Tabs & frames
Tool | Args | Description |
| - | Every open tab across all windows ( |
|
| Focus a tab and its window. |
|
| Close a tab by id. |
|
| Pin the working tab so every later tool targets it regardless of OS focus. Omit |
| - | Release the pin; tools revert to the active tab. |
| - | Every frame incl. cross-origin as |
Perception
Tool | Args | Description |
| - | Compact accessibility outline of visible interactive elements as |
| - | Raw |
| target |
|
| target, | An attribute, falling back to the live DOM property ( |
|
| text/href/value/visible for every match at once. |
| - |
|
Interaction - synthetic, fast
Untrusted events dispatched by the walker. Quick, and enough for most sites.
Tool | Args | Description |
| target | Bubbling |
| target, | Set a field's value via the native setter (handles |
| target, | Focus + set + read back. Throws if the text didn't stick. The reliable text-entry path - prefer it over click-then-type. |
| target, | Verify text (substring) and/or exact value without a screenshot → |
| target?, | Scroll an element into view, or the window ( |
| target, | Choose a |
| target, | Set a checkbox/radio, clicking only if it isn't already there. |
| target |
|
| target or | Poll until an element resolves or a text substring appears. |
Trusted input & emulation - CDP
Real events with isTrusted=true. These attach chrome.debugger, which shows a
persistent yellow "being debugged" banner on the tab.
Tool | Args | Description |
| target / | Trusted click, including right-click and double-click. |
| target?, | Trusted text insertion, focusing the target first if given. |
|
| Trusted keys and combos: |
| target / | Move the real mouse over an element to fire |
|
| Trusted press-move-release drag & drop. |
|
| Set files on an |
|
| Emulate a viewport / device for responsive checks. |
|
| Pre-arm an answer for the next |
| - | Detach the debugger and clear the banner. Re-attaches on the next CDP call. |
Observability - CDP, buffered per tab
Capture starts when the debugger attaches, so reload the page after the first CDP call if you want load-time activity.
Tool | Args | Description |
|
| Buffered console logs, warnings, errors, and uncaught exceptions. |
|
| Buffered requests: method, url, status, type, timing. |
|
| One request in full; |
|
| Run JS in the page's real context via CDP - bypasses the content-script CSP that blocks |
Capture
Saved into the capture directory (~/Downloads by default - see
Configuration).
Tool | Args | Description |
|
| Visible viewport as PNG/JPEG - saved to disk and returned inline with |
|
| The entire scrollable page beyond the viewport, via CDP. |
|
|
|
path is a filename or a path inside the capture directory. Missing subfolders
are created; anything resolving outside the directory is refused.
A first real run
Setup step 5 proves the wiring. This proves the interesting part - that a page sees a person rather than a script. Point your client at any page and ask for:
snapshotA11y- the compact outline, witheNrefs to target.realClick {ref:"e3"}- a trusted click. The tab grows a yellow "being debugged" banner; that is the CDP attach, and it is meant to be visible.evaluate {expression:"'ok'"}- page-context JS, bypassing the content-script CSP.screenshot- a PNG in your capture directory and returned inline.record {action:"start"}…record {action:"stop", path:"clip.webm"}- a.webmof the tab. No toolbar click and no user gesture needed; the toolbar icon is inert by design and starts nothing.detach- clears the banner.
To see the difference the trusted path makes, install a listener and compare:
// via evaluate
window.__e = []; document.querySelector("button")
.addEventListener("click", e => window.__e.push(e.isTrusted));click reports false; realClick reports true. That contrast is the whole point
of the project, and the browser test lane asserts on it directly.
Running the tests
The suite has two lanes, and the split is the point.
Offline lane - no browser, runs in CI
npm test # node test/run.mjs --lane=offlineCompletes in well under a second and needs nothing but Node. It runs a real MCP
handshake in-process against src/server.js (via the SDK's in-memory transport), so
it asserts on the surface the server actually publishes:
every published tool has an extension handler, and vice versa - the failure the mirrored architecture invites
no tool name is claimed by two handler groups (they merge by spread, so a duplicate would silently lose)
every tool carries a real description and the universal
tabId/frameId/expectUrlscopeevery tool is exercised by at least one test - add a tool without a test and CI fails, no browser required
the capture path allowlist really refuses
.., deep.., absolute paths, and symlinked escapes, tested against the real resolverthe ban list is checked by behaviour - it blocks what it claims to and doesn't over-block ordinary sites
the hub binds loopback only, the tokens match on both sides, the manifest requests no over-broad permissions, the toolbar icon is inert, and no
*.pemis committed
Browser lane - drives real Chrome
# 1. Disconnect the MCP client (close Claude Code, or disable this server for the run)
# 2. Free port 9876 - the hub is long-lived and outlives the session that spawned it
pkill -f src/hub.js
# 3. Start the suite; it binds 9876 itself and waits for the extension
npm run test:browser
# 4. Reload the extension in chrome://extensions so it connects to the suite⚠️ Step 1 is not optional. A connected MCP client respawns the hub every ~1.2s whenever it finds the socket gone, so it takes port 9876 straight back and the suite dies with
EADDRINUSE. Killing the hub while a client is still attached does not help - the client just starts another one.
The suite stands up a fixture server and a bridge speaking the same wire protocol as the real hub, so a passing run exercises the actual message contract. Each suite mirrors a tool group, and every test starts from a reset fixture page - no test inherits another's mutations.
At the end it prints tool coverage and fails if any of the 45 tools went unexercised.
Options
Command | Effect |
| offline lane only - the CI gate |
| browser lane only |
| both |
| list every suite and test without running |
| only tests whose suite/name matches |
Test layout
test/
├── run.mjs # CLI: lanes, filtering, coverage, reporting
├── lib/
│ ├── runner.js # suite registry, isolation, timeouts
│ ├── assert.js # assertions with diagnostic messages
│ ├── wait.js # eventually() - polling, not fixed sleeps
│ ├── mcp-probe.js # real in-process MCP handshake
│ ├── bridge.js # stands in for the hub; tracks tool coverage
│ ├── fixture-server.js # serves the fixture pages
│ └── page.js # the browser session + per-test reset
├── fixtures/
│ ├── index.html # the fixture page (a real file, with __reset())
│ └── frame.html # child frame, for frameId targeting
└── suites/
├── 01-contract.suite.js # offline
├── 02-security.suite.js # offline
├── 10-navigation.suite.js
├── 20-tabs.suite.js
├── 30-perception.suite.js
├── 40-interaction.suite.js
├── 50-trusted-input.suite.js
├── 60-observability.suite.js
└── 70-capture.suite.jsSecurity notes
This extension can drive your logged-in browser. Read this section.
Loopback only. The hub binds
127.0.0.1, so it is not reachable from the LAN - only from processes on this machine.Token handshake. A peer must present
AUTH_TOKENon connect or the hub drops it. Change it from the shipped default (identical constant insrc/config.jsandextension/src/config.js) - it is what stops another local process from driving your browser.File writes are confined to the capture directory.
src/capture/capture-path.jsresolves every requested path and refuses anything outside it, including via..traversal and via symlinked subdirectories. This matters more than it looks: arbitrary-path writes are effectively code execution.Host ban list.
BANLISTinextension/src/config.jsblocks navigation and scripting on sensitive domains (banking, PayPal, Gmail). Adjust it to your needs. Note: screenshots and recording capture rendered pixels and are not filtered by the ban list.The debugger banner is a feature. CDP tools attach
chrome.debugger, showing a persistent yellow "being debugged" bar. That is your visible signal that something is driving the tab.detachremoves it.evaluateruns arbitrary JS in the page's real context.Internal pages are off limits - the extension cannot script
chrome://orchrome-extension://URLs.The signing key is not in this repo. The extension ID is pinned by the public
keyinextension/manifest.json; the matching private key must stay outside version control (.gitignoreblocks*.pem). It is only needed to re-pack a.crxunder the same ID - loading unpacked does not use it.
Architecture
The server and the extension are mirrored. Every tool group in src/tools/ has a
handler file of the same name in extension/src/handlers/. Adding a tool means
touching exactly that pair - its schema and docs on one side, its implementation on
the other.
Group | Server (schema + docs) | Extension (implementation) |
navigation |
|
|
tabs |
|
|
perception |
|
|
interaction |
|
|
trusted input |
|
|
observability |
|
|
capture |
|
|
Everything else is supporting infrastructure:
bin/custom-chrome-dev-mcp.js- the executable you register with your MCP client. It does nothing but start the server.src/config.js/extension/src/config.js- every tunable, one file per side.AUTH_TOKENand the port must match across the two.src/relay/hub-client.js- connects to the hub asrole:"mcp", spawns it when absent, and turns each tool call into a request/response over the socket.src/hub.js- the long-lived relay owningws://127.0.0.1:9876. Holds the one extension socket plus every session's client and multiplexes between them. Re-tags ids on the wire (they can collide across sessions) and self-exits if a hub already owns the port.src/capture/capture-path.js- the write allowlist. Every capture path goes through it.extension/src/connection.js- the hub socket plus the heartbeat. An MV3 service worker is torn down after ~30s idle, which silently drops the socket; a sub-30s heartbeat keeps both alive, and an alarm revives the worker after a hard kill.extension/src/tabs.js- which tab a call acts on (explicittabId> pinned tab > active tab), theexpectUrlguard, and the ban list check.extension/src/walker-bridge.js+extension/src/page/walker.js- the injected ISOLATED-world script with the stable element-ref system, and the only module that knows how to reach it.extension/src/cdp/-session.js(attach/detach,cdp(), element centres),keyboard.js(key names → CDP key events),dialogs.js(native dialog policy),buffers.js(console + network ring buffers, capped at 500/tab).extension/src/recording/-chrome.tabCaptureneeds a user gesture an MCP call never has, so recording uses CDP screencast instead: JPEG frames relayed to an offscreenMediaRecorder(the service worker has no DOM).test/- two-lane suite: an offline CI gate that needs no browser, and a browser lane that drives real Chrome. See Running the tests.
Project layout
.
├── bin/
│ └── custom-chrome-dev-mcp.js # executable entry - register THIS with your client
├── src/
│ ├── server.js # composes config + relay + tool registry
│ ├── config.js # port, token, capture dir, timeouts
│ ├── hub.js # long-lived relay owning :9876
│ ├── relay/
│ │ └── hub-client.js # session -> hub socket; call()
│ ├── capture/
│ │ └── capture-path.js # write allowlist for screenshots/recordings
│ └── tools/ # ONE FILE PER TOOL GROUP - the public surface
│ ├── index.js # the registry
│ ├── schemas.js # shared arg shapes + passthrough helper
│ ├── navigation.js
│ ├── tabs.js
│ ├── perception.js
│ ├── interaction.js
│ ├── trusted-input.js
│ ├── observability.js
│ └── capture.js
├── extension/ # Chrome MV3 extension
│ ├── manifest.json
│ └── src/
│ ├── background.js # service worker entry - wiring only
│ ├── config.js # token, banlist, buffer caps, asset paths
│ ├── connection.js # hub socket + MV3 keepalive heartbeat
│ ├── tabs.js # tab resolution, pinning, ban check
│ ├── walker-bridge.js # channel to the injected page script
│ ├── cdp/
│ │ ├── session.js # attach/detach, cdp(), element centres
│ │ ├── keyboard.js # key names -> CDP key events
│ │ ├── dialogs.js # native alert/confirm/prompt policy
│ │ └── buffers.js # console + network ring buffers
│ ├── recording/
│ │ ├── recorder.js # CDP screencast -> offscreen encoder
│ │ ├── offscreen.html
│ │ └── offscreen.js # MediaRecorder host
│ ├── page/
│ │ └── walker.js # injected DOM driver (ISOLATED world)
│ └── handlers/ # MIRRORS src/tools/ - one file per group
│ ├── index.js # the handler table + dispatch
│ ├── navigation.js
│ ├── tabs.js
│ ├── perception.js
│ ├── interaction.js
│ ├── trusted-input.js
│ ├── observability.js
│ └── capture.js
└── test/ # two lanes: offline (CI) + browser
├── run.mjs # CLI entry
├── lib/ # runner, assertions, bridge, fixtures, session
├── fixtures/ # the fixture pages, as real files
└── suites/ # one suite per tool groupCredits
Inspired by Chrome DevTools MCP from the Chrome DevTools team. Independent reimplementation, not affiliated with, endorsed by, or supported by Google.
License
MIT. Copyright (c) 2026 Haba Andrei.
Use it, fork it, ship it. The only condition is that the copyright notice and the permission notice travel with any substantial copy.
This server cannot be installed
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 Servers
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to control and interact with the user's real Chrome browser session, leveraging existing logins, cookies, and extensions for AI-driven automation.5MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to drive a real, logged-in Chrome browser for web automation tasks like navigation, clicking, typing, and screenshotting.11MIT
- FlicenseNot gradedqualityCmaintenanceDrive your real, signed-in Chrome browser from any MCP client, enabling browser automation such as navigation, clicking, typing, and screenshots through standard MCP tools.1
- AlicenseCqualityAmaintenanceMCP server for browser automation that drives Chrome via an extension, preserving login state and offering 45 tools for navigation, interaction, scraping, and screenshots.534MIT
Related MCP Connectors
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Hosted real Google Chrome MCP with per-user persistent state. Navigate, click, type, screenshot.
Stealth web browser for agents: search, fetch, click, download and type in persistent MCP sessions.
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/HabaAndrei/custom-chrome-dev-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server