Call MyTools directly with WebMCP
WebMCP is an emerging web standard that lets a page hand an AI agent a list of callable functions instead of a screen to interpret. A page registers tools on document.modelContext — each with a name, a description and a JSON schema — and an agent running in that browser can list them and call them.
MyTools registers three site-wide tools on every page, and three more on each of its 55 tool pages: read the state, run the operation, save the result. The work still happens in the browser on the user's own machine. WebMCP changes who presses the button, not where the file goes.
Where this works, and how settled it is
ChatGPT's browser calls these tools today. OpenAI has added WebMCP support to the browser built into the ChatGPT desktop app, so the tools below are callable there with no flag, no trial token and no setup on your side. MyTools has been driven that way in the wild: a crash specific to that browser was reported by someone whose agent was already using these tools, and fixed in August 2026.
In Chrome it is an origin trial. The trial runs from Chrome 149 to Chrome 156, roughly to the end of 2026. MyTools carries a token for its production origin, so in a supporting Chrome the tools are there with no flag to set. If the trial ends without the API shipping, document.modelContext disappears from Chrome and these tools go with it — which is why the URL entry point below is not going anywhere.
The specification is a draft, not a ratified standard. WebMCP is a Draft Community Group Report from the W3C Web Machine Learning Community Group, edited by engineers at Google and Microsoft, and explicitly not on the W3C standards track. The shape has already moved once: tools were registered on navigator.modelContext before the API moved to document.modelContext. If you are working from older material, check that first.
Feature-detect, do not assume. document.modelContext is either there or it is not, and with more than one implementation arriving on its own schedule that is the only test worth making. Never sniff the user agent for it. Where it is missing nothing on this site breaks — the tools simply do not exist, and every page still works as a page.
There is a fallback that works everywhere. Where WebMCP is unavailable, drive the site through its URL entry point instead: 50 of the 55 tools open with the file already loaded from a URL you build yourself. The two mechanisms cover the same operations; only the ergonomics differ.
Testing locally, in a Chrome without the trial token, enable chrome://flags/#enable-webmcp-testing.
Further reading — The draft specification · Chrome's WebMCP documentation
Three tools on every page
These are registered site-wide, including on pages that are not tools at all — the homepage, an article, this page. They are how an agent finds its way to the right tool.
find_mytools_tools — Search the catalogue. Takes query, category, inputType and limit, all optional, and returns matching tools with their slug, page path and whether they accept a file URL. Read-only. The output is capped, so narrow the search rather than asking for everything.
open_mytools_tool — Navigate to a tool, ready to use. Takes slug — required, as returned by find_mytools_tools — plus optional urls to load remote files straight in, and carryResult, which hands the files the current tool just produced to the tool being opened instead of arriving at an empty upload screen.
suggest_mytools_pipeline — Given a tool slug and the names of the files it produced, list the tools those files can go to next. Only compatible destinations come back: a batch is never offered to a single-file tool, and no tool is offered a format it cannot open.
Three more on every tool page
All 55 tools carry the same triplet, named from the tool's slug with hyphens turned into underscores. On /pdf/rotate-pdf those are get_rotate_pdf_state, run_rotate_pdf and download_rotate_pdf.
get_<tool>_state — What is loaded, what the settings are set to, and a hint naming the call to make next. Read it before running anything: it is where the page counts, durations and pixel dimensions come from, and those are what make arguments meaningful.
run_<tool> — Do the work. Arguments differ per tool and are described in its schema; anything you omit keeps what is set on screen. The call does not return until the operation has finished, so there is nothing to poll — on a long video encode it simply takes as long as the encode takes.
download_<tool> — Save the result to the user's device. It is registered only once there is a result, so its presence in the tool list is the signal that the work is done. Tools that produce several files take an index to save one, or zip to save them all as one archive.
Three tools end on a published URL rather than a file — the two Facebook posters and the YouTube uploader — so they register no download tool. They also refuse to act when nobody is signed in: the login opens a popup that only a real click can open.
A worked example
Rotating a PDF that lives at a URL, end to end. Every response below is the real output of these tools, not a sketch of one.
1. Find the tool.
find_mytools_tools({ query: "rotate pdf", inputType: "application/pdf", limit: 3 })
→ { "total": 55, "matched": 1, "tools": [
{ "slug": "rotate-pdf", "title": "Rotate PDF",
"description": "Rotate PDF pages in one click",
"multiple": true, "byUrl": true } ] }2. Open it with the file already loaded. The page-specific tools change with the page, so read the tool list again afterwards.
open_mytools_tool({ slug: "rotate-pdf",
urls: ["https://example.com/rental-application.pdf"] })
→ "Opened Rotate PDF with 1 file(s) loading from URL. Everything is processed
locally in the browser. The page-specific tools available to you have changed."3. Read the state. The page count comes from the PDF itself, which is what makes a page range worth sending.
get_rotate_pdf_state({})
→ { "phase": "configure",
"pdfs": [ { "name": "rental-application.pdf", "pages": 2, "rotations": [0, 0] } ],
"saving": false, "result": null,
"hint": "Call run_rotate_pdf with a rotation, optionally narrowed with pages,
to turn the loaded PDFs." }4. Run it. The call returns when the rotation is done, and download_rotate_pdf now exists.
run_rotate_pdf({ rotation: 90 })
→ "Rotated 1 PDF(s) by 90°. Call download_rotate_pdf to save it."5. Save it. The file goes to the user's device; you never receive the bytes.
download_rotate_pdf({})
→ "Saving rental-application-rotated.pdf to the user's device."Handing a decision back to the user
Not every argument should be yours to choose. Which part of a photo to keep, which pages of a scan matter, how loud is loud enough — those need eyes on the file. These tools are built so you can stop, let the user decide, and carry on. get_<tool>_state reports what is on screen right now, including a change the user just made with the mouse, and every argument you omit from run_<tool> keeps its on-screen value. Omit them all and the run uses exactly what they set.
The image cropper, with a real user drag partway through the sequence:
get_crop_image_state({})
→ … "source": { "width": 6240, "height": 4160 },
"selection": { "x": 1459, "y": 420, "width": 3330, "height": 3328 }
← the user drags the box over what they want to keep
get_crop_image_state({})
→ … "selection": { "x": 2910, "y": 831, "width": 3330, "height": 3329 }
run_crop_image({})
→ "Cropped to 3330×3329 pixels out of 6240×4160 (5507 KB, image/jpeg).
Call download_crop_image to save it."Say what you need in the same turn you open the tool — "drag the box over the part you want to keep, then tell me to go" — and read the state again when they answer. Nothing about the page is locked while you wait; the user is working in a normal browser tab.
This is the line between a tool page and an API. Work nobody needs to look at belongs behind an API call, and putting a browser in front of it would be pure overhead. A page earns its place when a person has to see the file to decide something — and WebMCP is what keeps an agent useful across that moment, doing the loading, measuring, converting and saving on either side of a judgement it should not be making.
Four things that shape how these behave
Output is capped at about 1500 characters. So a state response is a summary, not a dump. Long lists are trimmed from the end and marked as trimmed, and file contents never appear in one. If you need the whole catalogue rather than a search result, fetch capabilities.json instead.
No bytes cross the boundary. You cannot hand a tool a file and you never receive one. Files enter through a URL the browser fetches, and leave through download_<tool>, which triggers an ordinary browser download to the user's machine. Everything you exchange with these tools is text.
Calls can be cancelled. Each execution gets an AbortSignal. Cancelling a run stops the work rather than orphaning it — a video encode is terminated, not left running in a worker — and comes back as a cancellation rather than a failure.
The tool list changes as you navigate. Only the current page's tools are registered. Opening a different tool unregisters the previous page's triplet and registers the new one, so re-read the tool list after every open_mytools_tool rather than assuming what you saw before is still there.
Questions worth having answered
Which MyTools tools can an agent call directly?
faq.coverage.answer
Does this only work in Chrome?
No. The browser built into the ChatGPT desktop app supports WebMCP, and Chrome exposes it to origin-trial participants such as MyTools through Chrome 156. The specification is a W3C community group draft that any browser with agentic capabilities can implement, so treat availability as something to detect at runtime rather than a fixed list.
Is an API key or an account needed?
No. There is no sign-up, no login, no key and no quota. If the browser exposes WebMCP, the tools are there on first visit.
Does calling run_<tool> upload the file to a server?
No. The work runs in the browser and MyTools has no server-side file storage. The one exception is loading a file from a URL: our server fetches the URL you supply so the browser can work on the bytes, and does not persist it.
What happens if the browser does not support WebMCP?
Nothing breaks. document.modelContext is simply absent and no tools are registered; the pages work as ordinary pages. Fall back to the URL entry point, which needs no browser support at all.
Can several tools be chained without downloading in between?
Yes. Call suggest_mytools_pipeline with the slug and the names of the files just produced to see what accepts them, then open_mytools_tool with carryResult, and the next tool opens with those files already loaded.
Can an agent and a person work on the same tool at once?
faq.together.answer