
Pre-computed navigation paths for public websites, built to cut token usage when agents interact with browser automation. Instead of exploring a site's UI from scratch each time, your agent gets direct shortcuts (like jumping straight to YouTube search results) and step-by-step cheatsheets for common tasks (sharing a Notion doc, triaging Linear bugs). The system learns from actual agent runs and drops paths that stop working. During beta it's free with no auth required. Connect via the streamable HTTP transport and skip the expensive exploration phase when automating repetitive web workflows. Best for agents that hit the same public sites repeatedly where you're paying for redundant navigation tokens.
$ npx add-mcp https://api.bowmark.ai/mcp/registry --name bowmark --header 'Authorization: Bearer ${API_TOKEN}'Run in your terminal. add-mcp asks which agents to add it to, then asks for each value it needs. Add -g to install it for every project.
Review the command, arguments and environment values before installing. MCP servers run with your local permissions.
Claude Code
$ claude mcp add --transport http bowmark https://api.bowmark.ai/mcp/registry --header 'Authorization: YOUR_AUTHORIZATION'Run in your terminal. Add --scope user to make it available in every project.
Verified live against the running server on Nov 6, 2026.
get_library**Use this whenever a task touches a live website.** It answers whether Bowmark can already DO the thing: current prices, real availability or stock, a site search, a quote or a fare, a configurator, a booking, anything behind a form or a filter. **Behind a LOGIN it works only...3 params**Use this whenever a task touches a live website.** It answers whether Bowmark can already DO the thing: current prices, real availability or stock, a site search, a quote or a fare, a configurator, a booking, anything behind a form or a filter. **Behind a LOGIN it works only...
minimalbooleanqueriesarrayquerystringrun**Executes the task on the real websites** and returns the result. Call `get_library` FIRST, then start with `run({ script })` — never add `runId`. THE SCRIPT is a plain async JavaScript body, not a wrapping function. `bowmark` is a ready global: `await bowmark.<capability>.<f...3 params**Executes the task on the real websites** and returns the result. Call `get_library` FIRST, then start with `run({ script })` — never add `runId`. THE SCRIPT is a plain async JavaScript body, not a wrapping function. `bowmark` is a ready global: `await bowmark.<capability>.<f...
egressstringdefault · linkrunIdstringscriptstringrun_viewUsed by the inline run view to draw a run's progress. You do not need to call this — `run` returns the result.2 paramsUsed by the inline run view to draw a run's progress. You do not need to call this — `run` returns the result.
runIdstringscriptstringjig_openMake the user a "jig": their own copy of a website, running through Bowmark, that you curate as they talk to you. Asked for "a jig of YouTube", build a page that LOOKS like that site with Bowmark's logo where the site's would be, filled by Bowmark library functions as this use...6 paramsMake the user a "jig": their own copy of a website, running through Bowmark, that you curate as they talk to you. Asked for "a jig of YouTube", build a page that LOOKS like that site with Bowmark's logo where the site's would be, filled by Bowmark library functions as this use...
htmlstringjigIdstringslugstringstateobjecttemplatestringyoutube-feed · amazon-searchtitlestringjig_listThe jigs this user has, newest change first: id, slug, title, the built-in it started from, and when it last changed. A copy of someone's published jig also has `forkedFrom` ({ listingId, versionNo }) and `updateAvailable` (the newer version number, or null). Call it when the...The jigs this user has, newest change first: id, slug, title, the built-in it started from, and when it last changed. A copy of someone's published jig also has `forkedFrom` ({ listingId, versionNo }) and `updateAvailable` (the newer version number, or null). Call it when the...
No parameters. Call it with no arguments.
jig_searchSearch the public jigs other people published: "is there a jig for my Amazon orders?". Call it BEFORE building a page from scratch. Leave `q` empty for the newest. Pass `site` (a host like youtube.com) for the jigs of one site. Results: id, title, tagline, slug, ownerHandle, s...4 paramsSearch the public jigs other people published: "is there a jig for my Amazon orders?". Call it BEFORE building a page from scratch. Leave `q` empty for the newest. Pass `site` (a host like youtube.com) for the jigs of one site. Results: id, title, tagline, slug, ownerHandle, s...
cursorstringlimitintegerqstringsitestringjig_publishPublish the user's jig (name it by `jigId` or your jig's `jigSlug`) as a listing others can get: it snapshots the page and state AS THEY ARE NOW into version N+1, and later edits stay private until you publish again. Call with `dryRun: true` first and show the user what would...14 paramsPublish the user's jig (name it by `jigId` or your jig's `jigSlug`) as a listing others can get: it snapshots the page and state AS THEY ARE NOW into version N+1, and later edits stay private until you publish again. Call with `dryRun: true` first and show the user what would...
changelogstringdefaultStateobjectdescriptionstringdetailsOnlybooleandryRunbooleanextraSitesarrayhandlestringjigIdstringjigSlugstringscreenshotsarrayslugstringtaglinestringtitlestringvisibility*stringpublic · unlistedjig_set_handleClaim the user's public handle: the @name in the links to pages they publish, bowmark.ai/jigs/@<handle>/<slug>. It is PUBLIC and PERMANENT: it can never be changed or released. Ask the user which one they want BEFORE calling, suggesting one from their name, and never choose it...1 paramsClaim the user's public handle: the @name in the links to pages they publish, bowmark.ai/jigs/@<handle>/<slug>. It is PUBLIC and PERMANENT: it can never be changed or released. Ask the user which one they want BEFORE calling, suggesting one from their name, and never choose it...
handlestringjig_getCopy someone's published jig into THIS user's account, from its current version. The copy is the user's own: it runs as them with their logins, never the author's, and can call only the functions its listing lists. Name it by `listing`: its id, `@handle/slug`, or its store URL...2 paramsCopy someone's published jig into THIS user's account, from its current version. The copy is the user's own: it runs as them with their logins, never the author's, and can call only the functions its listing lists. Name it by `listing`: its id, `@handle/slug`, or its store URL...
anotherbooleanlisting*stringjig_updateChange a page you opened with `jig_open`: merge `state` into its state (a key set to null is removed), replace its `html` or `title`, or change part of the html with `edits` ([{ find, replace }], each find exactly once) instead of resending the whole page. The open page update...8 paramsChange a page you opened with `jig_open`: merge `state` into its state (a key set to null is removed), replace its `html` or `title`, or change part of the html with `edits` ([{ find, replace }], each find exactly once) instead of resending the whole page. The open page update...
editsarrayhtmlstringjigId*stringmergedFromintegerreplaceStatebooleanslugstringstateobjecttitlestringjig_pull_updateFor a jig the user got from someone's listing (`jig_list` shows `updateAvailable`): the three pages a merge needs. `base` is the version their copy came from, `theirs` the author's newest, `mine` their copy now. Writes nothing. If `edited` is false, save `theirs` as is. Otherw...1 paramsFor a jig the user got from someone's listing (`jig_list` shows `updateAvailable`): the three pages a merge needs. `base` is the version their copy came from, `theirs` the author's newest, `mine` their copy now. Writes nothing. If `edited` is false, save `theirs` as is. Otherw...
jigId*stringjig_viewUsed by an open jig to pick up its latest state. You do not need to call this.3 paramsUsed by an open jig to pick up its latest state. You do not need to call this.
cachebooleanjigId*stringsinceintegerjig_cacheUsed by an open jig to save a call's last good result. You do not need to call this.3 paramsUsed by an open jig to save a call's last good result. You do not need to call this.
jigId*stringkey*stringvaluevaluejig_seenUsed by an open jig to report what it shows. You do not need to call this.3 paramsUsed by an open jig to report what it shows. You do not need to call this.
eventstringjigId*stringsnapshotvaluejig_perfUsed by an open jig to report how fast it loaded. You do not need to call this.2 paramsUsed by an open jig to report how fast it loaded. You do not need to call this.
jigId*stringreportvaluejig_lookSee what an open jig is showing the user right now — the items on screen, which view they are on — plus what they just did on it (watched, hid, searched) and its current state. Call it before you curate: when the user says "clear the slop" or "why is this here", look first, th...1 paramsSee what an open jig is showing the user right now — the items on screen, which view they are on — plus what they just did on it (watched, hid, searched) and its current state. Call it before you curate: when the user says "clear the slop" or "why is this here", look first, th...
jigId*stringjig_callUsed by an open jig to call the library. You do not need to call this — use `run`.6 paramsUsed by an open jig to call the library. You do not need to call this — use `run`.
callsarraycancelarrayjigId*stringrefstringrunIdstringtimeoutMsintegersession_callRuns ONE library function in a Bowmark session, so a flow that needs several calls in the SAME session can finish: a booking that texts the user a code, a cart filled over several steps, a form that waits on an answer from the user. `run` cannot do these, because every run sta...3 paramsRuns ONE library function in a Bowmark session, so a flow that needs several calls in the SAME session can finish: a booking that texts the user a code, a cart filled over several steps, a form that waits on an answer from the user. `run` cannot do these, because every run sta...
argsarraypath*arraysessionIdstringsession_closeEnds a session `session_call` opened and frees what it held. Pass the `sessionId`. Closing one that is already closed is harmless.1 paramsEnds a session `session_call` opened and frees what it held. Pass the `sessionId`. Closing one that is already closed is harmless.
sessionId*stringreportRecord what was missing, wrong, or incomplete so Bowmark can build it. Call it yourself, in the same turn, without asking your user first: it changes nothing on any website or account, costs the user nothing, and is the only way the gap gets fixed. Call it whenever a `run` err...2 paramsRecord what was missing, wrong, or incomplete so Bowmark can build it. Call it yourself, in the same turn, without asking your user first: it changes nothing on any website or account, costs the user nothing, and is the only way the gap gets fixed. Call it whenever a `run` err...
report*stringrunIdstringget_usageSee the real cost of calls on this account, itemized by resource (provider calls, browser sessions, IP leases) and aggregated in dollars. Pass no arguments to see this month; pass `month: '2026-09'` to see a past month (format `YYYY-MM`). Returns `totalUsd` and line items with...1 paramsSee the real cost of calls on this account, itemized by resource (provider calls, browser sessions, IP leases) and aggregated in dollars. Pass no arguments to see this month; pass `month: '2026-09'` to see a past month (format `YYYY-MM`). Returns `totalUsd` and line items with...
monthstringllm_pollLets this chat answer the AI calls an open Bowmark page makes, so they cost nothing. Returns up to 5 pending jobs ({ jobId, system, prompt, toolName, inputSchema, leaseSeconds }); waits up to waitSeconds (max 15) when there are none. Answer each with llm_answer. Calling this m...1 paramsLets this chat answer the AI calls an open Bowmark page makes, so they cost nothing. Returns up to 5 pending jobs ({ jobId, system, prompt, toolName, inputSchema, leaseSeconds }); waits up to waitSeconds (max 15) when there are none. Answer each with llm_answer. Calling this m...
waitSecondsnumberllm_answerAnswers one job from llm_poll. `answer` must be an object matching that job's inputSchema. A wrong shape is refused with the reason and the job stays open, so correct it and call again.2 paramsAnswers one job from llm_poll. `answer` must be an object matching that job's inputSchema. A wrong shape is refused with the reason and the job stays open, so correct it and call again.
answervaluejobId*stringllm_detachDetaches this chat at once, so open Bowmark pages' AI calls go back to Bowmark's own model instead of waiting for this chat.Detaches this chat at once, so open Bowmark pages' AI calls go back to Bowmark's own model instead of waiting for this chat.
No parameters. Call it with no arguments.
supportChat live with a Bowmark support agent about a problem you reported. Use it only after your user said yes to talking to support. Pass the `reportId` that `report` returned. Your first call opens the chat: put a short hello and what you need in `message`. Each call posts your `...3 paramsChat live with a Bowmark support agent about a problem you reported. Use it only after your user said yes to talking to support. Pass the `reportId` that `report` returned. Your first call opens the chat: put a short hello and what you need in `message`. Each call posts your `...
afterintegermessagestringreportId*stringlist_secretsList the stored secrets this account holds, by NAME. Returns name, type, which hosts each may be used against, when it expires and when it was last used — never a value, and no Bowmark endpoint returns one. **Call this BEFORE `request_secret`.** A secret the user has already s...List the stored secrets this account holds, by NAME. Returns name, type, which hosts each may be used against, when it expires and when it was last used — never a value, and no Bowmark endpoint returns one. **Call this BEFORE `request_secret`.** A secret the user has already s...
No parameters. Call it with no arguments.
request_secretCreate a named, empty slot for a secret and get back a link the user opens to fill it in. They type the value on a Bowmark page and choose how long it lives, from 5 minutes to never. It is encrypted in their own browser before it leaves, so nothing on the way — this connection...3 paramsCreate a named, empty slot for a secret and get back a link the user opens to fill it in. They type the value on a Bowmark page and choose how long it lives, from 5 minutes to never. It is encrypted in their own browser before it leaves, so nothing on the way — this connection...
hostsarrayname*stringtype*stringpassword · username · totpSeed · apiKey · recoveryCodes · cookieget_secret_linkReturn the dashboard link for one stored secret this account holds, so you can answer "where is my Acme password?" with somewhere to go. **It returns a URL, never a value** — opening it requires the user to be signed in and to confirm who they are, and only their own browser c...1 paramsReturn the dashboard link for one stored secret this account holds, so you can answer "where is my Acme password?" with somewhere to go. **It returns a URL, never a value** — opening it requires the user to be signed in and to confirm who they are, and only their own browser c...
name*stringlist_connectionsList the saved logins this account already holds, one entry per login: its `id` (name it in a signed-in call as `{ connection: id }`), the site, which account on that site, whether it works right now (`usable`), and when it was made, last used and last checked. **Call this bef...List the saved logins this account already holds, one entry per login: its `id` (name it in a signed-in call as `{ connection: id }`), the site, which account on that site, whether it works right now (`usable`), and when it was made, last used and last checked. **Call this bef...
No parameters. Call it with no arguments.
add_connectionGet a sign-in link for one site, so the user can sign Bowmark in to it right now, before any run needs it. Pass the site as a domain (`youtube.com`), a URL, or a provider id. **Call this whenever the user asks to log in, sign in, connect or link an account on a site** — never...2 paramsGet a sign-in link for one site, so the user can sign Bowmark in to it right now, before any run needs it. Pass the site as a domain (`youtube.com`), a URL, or a provider id. **Call this whenever the user asks to log in, sign in, connect or link an account on a site** — never...
connectionstringsite*stringwait_for_sign_inWait until the user finishes a sign-in link, so you know the moment they are done without asking them. Pass `ref`: `meta.handoff.ref` from a paused run, or `ref` from `add_connection`. **Call it right after you give the user the link, in the same turn.** Write the link in your...2 paramsWait until the user finishes a sign-in link, so you know the moment they are done without asking them. Pass `ref`: `meta.handoff.ref` from a paused run, or `ref` from `add_connection`. **Call it right after you give the user the link, in the same turn.** Write the link in your...
ref*stringwaitMsnumberlease_ipSome sites (LinkedIn, marked 📍 in `get_library`) only accept a login from the address it signed in from. A dedicated IP is one address that only this account uses, and once the account holds one, every sign-in link and every later call on that login uses it automatically. Cal...4 paramsSome sites (LinkedIn, marked 📍 in `get_library`) only accept a login from the address it signed in from. A dedicated IP is one address that only this account uses, and once the account holds one, every sign-in link and every later call on that login uses it automatically. Cal...
anotherbooleanconfirmPriceCentsnumbercountrystringtermDaysnumberdelete_connectionStart deleting a saved login by the `id` `list_connections` returned. **This does not delete anything by itself:** a delete cannot be undone, so the USER confirms it, signed in on their Bowmark dashboard. It returns `confirmUrl` — give that link to the user; it opens a "Delete...1 paramsStart deleting a saved login by the `id` `list_connections` returned. **This does not delete anything by itself:** a delete cannot be undone, so the USER confirms it, signed in on their Bowmark dashboard. It returns `confirmUrl` — give that link to the user; it opens a "Delete...
id*stringlogout_connectionSign a saved login out by the `id` `list_connections` returned. Bowmark drops the cookies it held, and where the site supports it (`siteLogout: "supported"` in the reply) the session is ended ON THE SITE too — `siteSignedOut: true` means Bowmark checked the site no longer acce...1 paramsSign a saved login out by the `id` `list_connections` returned. Bowmark drops the cookies it held, and where the site supports it (`siteLogout: "supported"` in the reply) the session is ended ON THE SITE too — `siteSignedOut: true` means Bowmark checked the site no longer acce...
id*stringSponsors
BOWMARK_API_KEY*secretRequired. Your Bowmark API key. Sign up at https://bowmark.ai/sign-up, then create a key at https://bowmark.ai/dashboard/keys. Your first $10 of usage is free.
Ask for prices, listings, profiles or reviews by name (Amazon, LinkedIn, YouTube, Airbnb and more) and get typed results back. Every account starts with a free $10.
@bowmark/mcp