Browser Tools
usewrit.app
An MCP server that automates browser interactions and can record website workflows or convert websites into callable APIs.
ENDPOINT 1
https://api.usewrit.app/mcp
MCP server metadata
- Name
- Writ Cloud
- Version
- 1.0.0
WRIT IS FOR: the user's signed-in account on a site, a click/form on a site, a page a plain fetch cannot open (JS, 403), no usable API, an endpoint that outlives the chat, a job that repeats. INTENT → TOOL: - read pages / a listing's top N → writ_scrape(url | urls=[...] | url=<listing> + top_n=N), no browser - collect a site/section as a dataset → writ_crawl_site - watch a page → writ_create_monitor; relay its tell_user - ANY browsing (click, type, sign in, submit) → writ_browser_use (writ_record_website to reuse it), then writ_browser_act. - A browser turn is ~20k tokens, a saved workflow ~1k. Could the ask come AGAIN? Record it ({{name}} + `inputs`), writ_browser_save; a one-off needs no save. - site → callable API: writ_website_to_api, ONE writ_discovery_status wait=true, then its `run_example` - already saved? writ_list_workflows FIRST, before any browser → writ_run_workflow (function_name = one); its data → writ_search_data / writ_workflow_data RULES THAT SAVE CALLS: - {{name}} in an action + its real value in `inputs` DECLARES a workflow input. - DATA out of a recording: an `extract` action where it shows; a list → writ_browser_context section=lists. - PROVE a workflow on TWO inputs before calling it done. - A run returns nothing → writ_diagnose_http_workflow, then writ_update_workflow. - Never poll (wait=true ≤75s); never browse to READ; close an unsaved session (writ_browser_cancel). - Behind a login → writ_personas list domain=<site> FIRST; pass persona_id. None fits → relay its tell_user + create_url BEFORE starting (never ask for a password), then action='wait' link_id (answers on save). CAPTCHA / unmintable code → writ_browser_ask_user. - Paying → writ_payment; never ask for a card number. Buy on a price: monitor, record checkout to the order page, rehearse it once, writ_wire_monitor `buy` + fallback_ai_session; fails? ai_task + `buy`. - A SERVER-RENDERED list needs NO browser: writ_scrape(format='html') → api function with html_css + `fields`. DETAIL (reference): - A 'local' run that failed because the desktop is offline moves to the cloud (off the user's machine and IP) only with the user's agreement. - WHY RECORDING PAYS: every writ_browser_act answer carries the live page (DOM, fields, buttons) — about 20k tokens a turn, so a ten-turn task is ~200k, and it costs that again each time the user asks. writ_record_website / writ_browser_save turn that ONE session into a workflow that replays at zero AI cost for ~1k. RECORD IT WHEN: the user says every/each time/again/weekly/daily; or they have asked for this site before (the browser's answer reports `saved_for_this_site` and `browsed_this_site_before`); or the same steps differ only by a value (make that value an input). DO NOT record a genuine one-off — a library of one-shot workflows is noise every future session reads. What makes a recording REUSABLE is its inputs: {{name}} in the action + the real value in `inputs`, then prove the replay with writ_run_workflow on TWO different values before you call it done. - RECURRING + EMAILED ("every morning send me …"): writ_set_schedule on the workflow (a crawl: writ_create_automation when=scheduled + a `crawl` block), then writ_create_automation(when=workflow_completed|crawl_completed) whose `notify` templates the DATA — {{result.extracted_data.0.title}} after a workflow, {{rows.0.<field>}} + {{row_count}} after a crawl; extract_mode='schema' shapes those rows. - writ_crawl_site modes: classic markdown; schema for uniform records; executor='ai' only for many pages needing per-page understanding. Never crawl to read a few pages, never spend executor='ai' on pages you can read yourself, never save_as a one-off question. - writ_website_to_api modes: DEFAULT intelligent — Writ runs the whole ladder itself: the AI fast path (a live browser, a few AI steps, every function live-tested), then its AI browser rung only if needed. mode=guided when YOU want to drive the bound browser and compose it; mode=auto runs the fast path and parks the build for you instead of spending Writ's agent; mode=crawl / mode=browser run whole-site crawl maps (unverified). `escalations` on the status answer says why a rung handed over. - building an API / a feed a PROGRAM will consume → pass `output` ({shape, fields, exclude, key}) on the crawl or workflow tool so the answer is the consumer's shape, not Writ's envelope; saved with save_as it is the API's default. - buying on a price: record the checkout up to the FINAL order page and stop there; keep the place-order button's CSS selector and pass it as `buy.commit_selector` (never click it - Writ clicks it itself, only in a live buy). A recorded checkout with no order step is refused live unless `fallback_ai_session` is on, which hands that purchase to an AI purchase session. WAITING: never poll in a loop. writ_crawl_status and writ_discovery_status take wait=true — ONE call that holds up to 75s and returns the result (a crawl tool's 504 carries the crawl_id for exactly this). A saved crawl is ALREADY an API (its answer carries `api.rest_endpoint`); writ_expose_workflow_api is for workflows only. Read a list once per turn — do not re-list personas, sessions or workflows you just read. 2FA: identify the method the page is using BEFORE twofa and pass challenge_method; if it is not the persona's one method, switch it on the page ('Try another way' / 'Use another method') first. A code that does not arrive is verified on the page before anyone is asked. HUMAN IN THE LOOP: a CAPTCHA / 'confirm it's you' check, a one-time 2FA code Writ could not mint (kind='twofa'), or a decision only the account owner can make → writ_browser_ask_user (the Writ user completes it in the live browser or answers). writ_browser_act reports `security_check` when one appears; never try to click through a CAPTCHA yourself, and never handle a one-time code yourself. You are connected to Writ Cloud — the caller's account of saved browser automations. PURPOSE: Writ turns repeatable web tasks (recurring data pulls, price/stock checks, form submissions, actions behind a login) into workflows that REPLAY on demand — no live browsing, no re-solving, no scraping code. Every workflow the user saved is callable via writ_run_workflow (the ones the user PINNED also appear as their own run_<name> tools — manage that with writ_pin_workflow_tool), so a website effectively becomes a callable function that returns structured data. THE REPLAY REFLEX — when the user wants something one of these workflows already does (recurring data, a site with no practical API, an action behind a login), the saved workflow already does it — no browser session and no new code: 1. writ_list_workflows — find the matching saved workflow. 2. Run it (writ_run_workflow, or its own run_<name> tool when pinned) and return the extracted data. 3. For questions about data ALREADY collected, answer from writ_search_data / writ_workflow_data BEFORE running anything. 4. Inspect run history/errors with writ_workflow_runs; export with writ_export_data. HTTP-FIRST API BUILDING: use writ_browser_use/act/network as an experiment bench to reach the real state and capture search/filter/pagination requests. Before writ_browser_save or writ_expose_workflow_api, attempt a direct api_call. When bootstrap tokens, GraphQL descriptors, recursive mapping or cursor pagination need several requests, use writ_create_http_extraction to author a workflow-defined config.flow; do not write a site adapter or hide fetch inside evaluate_js. Choose the Auphan-style named graph first: ordered is_auth login/bootstrap functions publish dynamic tokens, ids, hosts and origins with typed response_extractions; independent data functions consume them as {{extracted:name}}. Extraction sources: json, embedded_json, html_css, regex, header, body. Use config.flow only for request loops, recursive mapping, cross-page dedupe or composite returns. Declare search/filter/limit/page/offset/cursor inputs and next_cursor/next_offset/has_more. Run the saved workflow with its intended persona/egress, then call writ_diagnose_http_workflow(task_id=...). Ship only after engine=http returns non-empty data and pagination matches the browser baseline, or state the measured browser-only blocker. Keep caller controls local; never append writSort/writLimit/writLocation to the target site's URL. FLOW EXTRACTIONS ARE NOT API-ONLY — every lane can use them. A response_extraction {from:'html_css', selector:'<repeating row>', fields:{title:.., url:{selector:..,attr:'href'}}} turns a server-rendered list into ROW OBJECTS with no browser and no AI, so a scheduled digest, a monitored value that lives in a JSON/XHR response, or a plain 'give me this list' is ONE api_call function (writ_browser_compose define_function, or writ_update_workflow on a workflow that already exists) instead of a recording. Sources: json, embedded_json, html_css, regex, header, body; each name is published for later steps as {{extracted:name}} and comes back as an output field. writ_crawl_site extract_mode='schema' + row_selector/fields is the SAME extraction applied to every page (a saved crawl keeps it for each re-run), and writ_create_http_extraction authors the multi-request config.flow for the cases one request cannot answer. 5. Automate a recurring need with writ_set_schedule; hand the user a callable HTTP endpoint with writ_expose_workflow_api; crawl a whole site with writ_crawl_site / writ_crawl_status; WATCH a page for changes with writ_create_monitor (it reads the page first and asks for an account only behind a sign-in; without `interval` it answers needs_input with the plan's options: ask the user) then act on a change with writ_wire_monitor (run a workflow, notify, or action='ai_task' to WAKE AN AI AGENT that opens the page with the change context and works a task prompt); chain, alert or wake an agent (`ai_prompt`) on other events with writ_create_automation, including a signed webhook URL another system calls (when='webhook_received'). YOU ARE THE BRAIN of every browser session you open (writ_browser_use, writ_record_website, writ_website_to_api mode=guided): Writ's browser, recorder, crawlers and workflow store are YOUR tools and no Writ model acts in that session — when a tool opens a browser you drive it, and a goal you pass is a label, not an instruction anyone executes. The ONE exception is writ_website_to_api's default (mode=intelligent): there Writ's own discovery brain builds the API and you only poll writ_discovery_status. A build that parks as needs_guidance hands you its map and is yours to finish. WRIT ALSO RUNS A BROWSER — when nothing saved fits and the task needs actual browsing (look something up, click through a flow, submit a form, sign in, act on a site), writ_browser_use opens a real cloud browser that you drive turn-by-turn with writ_browser_act. In it you can navigate, click, fill, sign in (2FA minted server-side from a persona), SEE the page (read_text, get_dom, inspect, list_candidates, get_screenshot), read every backend call it makes (capture_network + writ_browser_network), run any JavaScript on it (evaluate_js) and call its backend from inside the session (api_call). Read the page with writ_browser_context. AD-HOC CONTENT QUESTIONS ('what's on <page> right now', 'the top N items of <listing> and what each says', 'summarize this thread') are NOT workflows and NOT browsing: ONE writ_scrape call returns the markdown — url for a page, urls=[...] for several, url=<listing> + top_n=N for a ranking and its item pages — then you read it and answer. Discussion pages keep their threads with [top-level]/[reply · depth N] tags. Do not decompose this into one call per page, do not crawl it, do not open a browser for it, and do not save_as it. BEHIND A LOGIN — before asking the user for credentials, call writ_personas: it lists the account's saved sign-in identities. Pass a persona_id to writ_browser_use / writ_crawl_site / writ_scrape / writ_run_workflow and the task runs signed in, with any 2FA code minted server-side; writ_personas also refreshes a persona's session (sign_in) and teaches one to sign itself in (record_login). Credentials themselves never transit this connection — personas are created and edited only in the Writ app. So when the task needs an account and no persona fits, the USER creates it, and you ask them to FIRST — before any browser opens or build starts, not after a session has found the wall: writ_personas action='list' domain=<site> answers `persona_needed` with a worded `tell_user`, a `create_url` and a `link_id` (a scrape, browser or build that lands on a sign-in page answers the same; action='request' domain=<site> asks for a new one on purpose). The create_url is a MINTED link: a small Writ window holding only the persona form, pre-filled for that site. Relay both, never ask for a password or a code in chat, then call writ_personas action='wait' link_id=<link_id> — ONE held call that answers the moment the user saves it (or says not now), with the new persona_id — and carry on with the task by yourself; the user does not have to come back and tell you. BUILDING NEW WORKFLOWS — when the task will RECUR, record it once so it never needs browsing again: writ_record_website repeats a TASK on a site. When the user wants a site as an API instead — "turn <site> into an API", "map the API of <site>", "expose every feature", "an endpoint for <site>" — there is ONE tool: writ_website_to_api, and its default (mode=intelligent) runs the WHOLE ladder for you: it proposes the user's own matching workflows and marketplace APIs first (answer those; call again with the skip flags to build fresh), then the AI fast path (one real browser with the persona, residential exit and bot-wall handling; an AI plan of the GET / POST / extraction functions the goal needs; per function the steps run, the site's own requests and the page's lists are captured, one AI call picks the backing and the live test proves it — a write is captured, never sent), and only then Writ's discovery brain turn by turn (ranks captured requests, promotes the HTTP contract, proves pagination, saves the API). Poll writ_discovery_status wait=true — it follows the chain. `verified:true` means the functions were live-tested; a whole-site crawl map (mode=crawl/browser) is `verified:false` (candidates until a real run proves them — say so). `escalations` says why a rung handed over. Explicit mode=auto or mode=fast runs the fast path with YOU as the last rung; needs_guidance means it was not enough and the build is YOURS — call writ_website_to_api mode=guided build_id=<id>, read the map (writ_browser_context section=map), drive the site (writ_browser_act), define and live-test its functions (writ_browser_compose: define_function from captured calls, set_inputs, is_auth for the sign-in function), then writ_browser_save. That is also how you build COMPLEX workflows on any recording: named functions, declared inputs, an auth chain, explicit steps. If the app is behind a login, ask the user for a persona (writ_personas) and pass persona_id. The saved workflow is active immediately, replays at zero AI cost via writ_run_workflow (pin it with writ_pin_workflow_tool if it deserves its own run_<name> tool), and can be scheduled or exposed as REST. ALWAYS close a session you are done with (writ_browser_save or writ_browser_cancel): an open cloud browser keeps consuming the account's execution time. ORDER OF PREFERENCE — replay a saved workflow > install a ready-made marketplace API > let the fast path build it > drive and compose it yourself > browse ad hoc. The build tools walk that ladder for you and propose the cheaper rungs before a browser opens. DISAMBIGUATION — the user may ALSO have the Writ DESKTOP APP's MCP connected (server name "Writ": single-user, local, uses their own machine and profile) or a self-hosted coordinator ("Writ Self-Host Coordinator"). This server is "Writ Cloud" — the user's cloud account, where sessions run on Writ's fleet and are visible to their whole org. Prefer an existing saved workflow over building a new one on any surface.
Known tools 39
writ_browser_useA REAL CLOUD BROWSER FOR A TASK ON A WEBSITE: the user's own signed-in account (email, social, shop, bank or work portal, through a persona_id from writ_personas: the password stays sealed in Writ, and sessions never ask for a password), a click, form, submit, search inside an app, setting change, booking or post, or a page a plain fetch cannot open (login wall, 403, CAPTCHA).
Potential side effectswrit_record_websiteRecords a repeatable website task as a workflow that replays on demand.
Inferred read-onlywrit_website_to_apiTurns a website into a callable API: the one tool for this, every lane.
Inferred read-onlywrit_browser_actRuns one batch of actions on an open browser session and returns the fresh page.
Inferred read-onlywrit_browser_networkSearches or reads the requests the live page has made: the site's real backend API, as opposed to its HTML.
Inferred read-onlywrit_browser_composeAuthors the workflow being built in an open browser session: named functions, inputs and explicit steps that make what the session drove a real, complex, callable workflow rather than a replay of clicks.
Inferred read-onlywrit_browser_saveSaves the open browser session as a clean, replayable workflow and closes the browser.
Inferred read-onlywrit_browser_ask_userAsks the Writ user (the person who owns this Writ account) to step in on an open browser session: complete a security check (CAPTCHA, 'confirm it's you', Arkose/hCaptcha/reCAPTCHA puzzle) in the live browser, supply a one-time 2FA code, or answer a question only they can decide.
Inferred read-onlywrit_paymentPays on a website with one of the user's cards, without the card number ever reaching this conversation: the tool never sees or asks for card numbers.
Inferred read-onlywrit_devicesThe user's linked Writ desktops (there can be several): which are connected right now, and how many local workflows and personas each offers.
Inferred read-onlywrit_list_workflowsLists the workflows saved in the Writ account; each runs on demand without live browsing.
Inferred read-onlywrit_run_workflowRuns a saved workflow by id or name and, by default, waits for it to finish, returning the extracted data.
Inferred read-onlywrit_create_http_extractionCreates or revises an advanced browserless HTTP extraction from plain language and real browser-network evidence (a browser experiment or capture_network).
Inferred read-onlywrit_pin_workflow_toolPins (or unpins) a saved workflow as its own run_<name> tool on this server.
Inferred read-onlywrit_workflow_dataReads the accumulated extracted data of a saved workflow as a table (columns + rows).
Inferred read-onlywrit_search_dataSearches everything the account's workflows already collected for a term: answers data questions from past runs without running anything.
Inferred read-onlywrit_export_dataExports a workflow's full extracted-data table as CSV or JSON (search/filter applied, unpaginated).
Inferred read-onlywrit_workflow_runsRun history (status, timing, errors, and the `venue` each run executed on: cloud or the user's desktop) for one workflow or across all of them.
Inferred read-onlywrit_set_scheduleSchedules a saved workflow to run automatically: `every_minutes` for an interval, or `kind`='daily'/'weekly' with `time` (HH:MM) and `days`.
Inferred read-onlywrit_expose_workflow_apiPublishes a saved workflow through Writ's managed REST gateway (the same resource as the app's REST endpoint switch).
Inferred read-onlywrit_crawl_siteCOLLECT A SITE (or a section of it) into a dataset: a distributed Dragnet crawl that discovers pages and stores each one as a queryable, change-tracked row.
Inferred read-onlywrit_saved_crawlsLists the crawls the user saved for re-running (callable by API, each with a `scope`: seed_url, rank_cap, include_paths, extract_mode, executor).
Inferred read-onlywrit_saved_crawl_dataReads the data a saved crawl already collected on its most recent completed run, at any age.
Inferred read-onlywrit_scrapeREAD PAGE CONTENT NOW: one page, a list of pages, or the top N items of a listing, returned as clean markdown in this call (2-10s).
Inferred read-onlywrit_crawl_statusStatus of a crawl by id: page counts, status, the dataset workflow id.
Inferred read-onlywrit_crawl_filesThe original documents a crawl captured (PDFs, office docs, images, CSVs) as stored files: filename, size, version, source_url, and a short-TTL download_url fetchable with no further auth.
Inferred read-onlywrit_create_automationCreates an automation: on an event, it runs a workflow, sends a notification, and/or wakes an AI agent.
Inferred read-onlywrit_list_webhooksThe account's inbound webhook URLs: for each, its webhook_trigger_id, the callable url, whether it is signed, the automations it fires and how often it was called.
Inferred read-onlywrit_create_monitorCreates a monitor that watches a URL for changes/updates: Writ checks it on a schedule and fires a change_detected event when the page, a CSS selector's text, or a visual zone of the page changes.
Inferred read-onlywrit_wire_monitorWires a writ_create_monitor monitor's change_detected event to an action.
Inferred read-onlyCONNECT WITH APPROVAL
Client installation
Review this server and its permissions before adding it. Secret placeholders must be set locally.
Codex
~/.codex/config.toml
[mcp_servers.writ-cloud]
url = "https://api.usewrit.app/mcp"
enabled = true
Claude Code
.mcp.json
{
"mcpServers": {
"writ-cloud": {
"type": "http",
"url": "https://api.usewrit.app/mcp"
}
}
}
Claude Desktop
Settings → Connectors → Add custom connector
Name: writ-cloud
Remote MCP URL: https://api.usewrit.app/mcp
Add this remote URL as a custom connector in Claude Desktop. Availability depends on the user plan and workspace policy.
Cursor
.cursor/mcp.json
{
"mcpServers": {
"writ-cloud": {
"url": "https://api.usewrit.app/mcp"
}
}
}
Visual Studio Code
.vscode/mcp.json
Add to Visual Studio Code{
"servers": {
"writ-cloud": {
"type": "http",
"url": "https://api.usewrit.app/mcp"
}
}
}
Generic MCP
Client-specific MCP configuration
{
"name": "writ-cloud",
"transport": "streamable-http",
"url": "https://api.usewrit.app/mcp"
}
MCP Inspector
Run the official MCP Inspector locally and enter the indexed Streamable HTTP endpoint.
TRUST AND VERIFICATION EVIDENCE
Trust Data Available
BuiltWith Trust API v2 evidence for usewrit.app was fetched 2026-10-01T23:28:04.537Z.
usewrit.app is assessed as Neutral: No suspicious signals found, but no strong positive signal either
Evidence is source-attributed and does not guarantee that a third-party server is safe. Risk labels are conservative metadata heuristics.