[{"data":1,"prerenderedAt":544},["ShallowReactive",2],{"i-simple-icons:github":3,"i-lucide:arrow-right":8,"doc-\u002Fdocs\u002Fwebmcp":10,"docs-sidebar":482,"i-lucide:file-text":540,"i-lucide:arrow-left":542},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"M12 .297c-6.63 0-12 5.373-12 12c0 5.303 3.438 9.8 8.205 11.385c.6.113.82-.258.82-.577c0-.285-.01-1.04-.015-2.04c-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729c1.205.084 1.838 1.236 1.838 1.236c1.07 1.835 2.809 1.305 3.495.998c.108-.776.417-1.305.76-1.605c-2.665-.3-5.466-1.332-5.466-5.93c0-1.31.465-2.38 1.235-3.22c-.135-.303-.54-1.523.105-3.176c0 0 1.005-.322 3.3 1.23c.96-.267 1.98-.399 3-.405c1.02.006 2.04.138 3 .405c2.28-1.552 3.285-1.23 3.285-1.23c.645 1.653.24 2.873.12 3.176c.765.84 1.23 1.91 1.23 3.22c0 4.61-2.805 5.625-5.475 5.92c.42.36.81 1.096.81 2.22c0 1.606-.015 2.896-.015 3.286c0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12\"\u002F>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M5 12h14m-7-7l7 7l-7 7\"\u002F>",{"id":11,"title":12,"body":13,"description":473,"extension":474,"group":475,"groupOrder":50,"meta":476,"navTitle":12,"navigation":477,"order":233,"path":478,"seo":479,"stem":480,"__hash__":481},"docs\u002Fdocs\u002Fwebmcp.md","WebMCP exposure",{"type":14,"value":15,"toc":463},"minimark",[16,20,29,37,104,112,116,119,183,194,198,268,288,303,323,327,350,354,391,395,431,435,459],[17,18,12],"h1",{"id":19},"webmcp-exposure",[21,22,23,24,28],"p",{},"WebMCP is an imperative browser API — ",[25,26,27],"code",{},"document.modelContext.registerTool(...)"," — that lets a page offer tools to an AI agent running in or alongside the browser. webmcpui controls can register themselves as tools.",[30,31,33,34],"h2",{"id":32},"opt-in-with-expose","Opt in with ",[25,35,36],{},"expose",[38,39,44],"pre",{"className":40,"code":41,"language":42,"meta":43,"style":43},"language-html shiki shiki-themes github-light-default ayu-dark","\u003Cwmcp-input label=\"Email\" name=\"email\" type=\"email\" expose>\u003C\u002Fwmcp-input>\n\u003C!-- registers a \"fill_email\" tool an agent can call -->\n","html","",[25,45,46,97],{"__ignoreMap":43},[47,48,51,55,59,63,67,71,74,76,79,82,84,86,89,92,94],"span",{"class":49,"line":50},"line",1,[47,52,54],{"class":53},"sqV5G","\u003C",[47,56,58],{"class":57},"sfBZl","wmcp-input",[47,60,62],{"class":61},"sI192"," label",[47,64,66],{"class":65},"siQKT","=",[47,68,70],{"class":69},"sxLuP","\"Email\"",[47,72,73],{"class":61}," name",[47,75,66],{"class":65},[47,77,78],{"class":69},"\"email\"",[47,80,81],{"class":61}," type",[47,83,66],{"class":65},[47,85,78],{"class":69},[47,87,88],{"class":61}," expose",[47,90,91],{"class":53},">\u003C\u002F",[47,93,58],{"class":57},[47,95,96],{"class":53},">\n",[47,98,100],{"class":49,"line":99},2,[47,101,103],{"class":102},"s5O_a","\u003C!-- registers a \"fill_email\" tool an agent can call -->\n",[21,105,106,107,111],{},"On connect, the element registers an imperative WebMCP tool; on disconnect, it unregisters. It is ",[108,109,110],"strong",{},"feature-detected"," — a complete no-op when no agent\u002Fhost is present (the common case today), so the control is always a good form control first.",[30,113,115],{"id":114},"the-generated-tool","The generated tool",[21,117,118],{},"For the example above, the registered tool is:",[120,121,122,135],"table",{},[123,124,125],"thead",{},[126,127,128,132],"tr",{},[129,130,131],"th",{},"Field",[129,133,134],{},"Value",[136,137,138,159,171],"tbody",{},[126,139,140,146],{},[141,142,143],"td",{},[25,144,145],{},"name",[141,147,148,151,152,155,156,158],{},[25,149,150],{},"fill_email"," (",[25,153,154],{},"fill_"," + the ",[25,157,145],{}," attribute)",[126,160,161,166],{},[141,162,163],{},[25,164,165],{},"description",[141,167,168],{},[25,169,170],{},"Set the value of the \"Email\" field.",[126,172,173,178],{},[141,174,175],{},[25,176,177],{},"inputSchema",[141,179,180],{},[25,181,182],{},"{ type: 'object', properties: { value: { type: 'string' } }, required: ['value'] }",[21,184,185,186,189,190,193],{},"When the agent calls the tool, the element applies the value exactly as if a user typed it — updating state, running validation, announcing errors, and firing ",[25,187,188],{},"input","\u002F",[25,191,192],{},"change"," events.",[30,195,197],{"id":196},"customizing-the-tool","Customizing the tool",[38,199,201],{"className":40,"code":200,"language":42,"meta":43,"style":43},"\u003Cwmcp-input\n  name=\"email\"\n  label=\"Work email\"\n  expose\n  tool-name=\"set_work_email\"\n  tool-description=\"Set the customer's work email address.\"\n>\u003C\u002Fwmcp-input>\n",[25,202,203,210,220,231,237,248,259],{"__ignoreMap":43},[47,204,205,207],{"class":49,"line":50},[47,206,54],{"class":53},[47,208,209],{"class":57},"wmcp-input\n",[47,211,212,215,217],{"class":49,"line":99},[47,213,214],{"class":61},"  name",[47,216,66],{"class":65},[47,218,219],{"class":69},"\"email\"\n",[47,221,223,226,228],{"class":49,"line":222},3,[47,224,225],{"class":61},"  label",[47,227,66],{"class":65},[47,229,230],{"class":69},"\"Work email\"\n",[47,232,234],{"class":49,"line":233},4,[47,235,236],{"class":61},"  expose\n",[47,238,240,243,245],{"class":49,"line":239},5,[47,241,242],{"class":61},"  tool-name",[47,244,66],{"class":65},[47,246,247],{"class":69},"\"set_work_email\"\n",[47,249,251,254,256],{"class":49,"line":250},6,[47,252,253],{"class":61},"  tool-description",[47,255,66],{"class":65},[47,257,258],{"class":69},"\"Set the customer's work email address.\"\n",[47,260,262,264,266],{"class":49,"line":261},7,[47,263,91],{"class":53},[47,265,58],{"class":57},[47,267,96],{"class":53},[269,270,271,282],"ul",{},[272,273,274,277,278,281],"li",{},[25,275,276],{},"tool-name"," overrides the generated ",[25,279,280],{},"fill_\u003Cname>",".",[272,283,284,287],{},[25,285,286],{},"tool-description"," overrides the generated description.",[21,289,290,291,294,295,298,299,302],{},"Controls with enumerated values (",[25,292,293],{},"\u003Cwmcp-select>",", ",[25,296,297],{},"\u003Cwmcp-radio-group>",") generate an ",[25,300,301],{},"enum","-typed schema so the agent knows the exact allowed values.",[304,305,306],"blockquote",{},[21,307,308,311,312,314,315,317,318,320,321,281],{},[108,309,310],{},"Tool names are page-global."," Two ",[25,313,36],{},"d controls that resolve to the same tool name — say two fields that both become ",[25,316,150],{}," — collide, and the host rejects the duplicate, so the second control won't be agent-callable. webmcpui logs a console warning when it sees this; give one control a unique ",[25,319,145],{},", or override it with ",[25,322,276],{},[30,324,326],{"id":325},"only-on-a-secure-context","Only on a secure context",[21,328,329,330,333,334,337,338,341,342,345,346,349],{},"WebMCP is a secure-context feature, so ",[25,331,332],{},"document.modelContext"," exists only on ",[108,335,336],{},"HTTPS"," pages — it's ",[25,339,340],{},"undefined"," on plain HTTP (",[25,343,344],{},"localhost"," counts as secure). webmcpui's feature detection reads that as \"no host present\" and quietly does nothing, so your controls stay perfectly good form controls. If you're testing exposure on an ",[25,347,348],{},"http:\u002F\u002F"," staging box and see no tools, that's why.",[30,351,353],{"id":352},"designed-for-a-human-in-the-loop","Designed for a human in the loop",[21,355,356,357,360,361,364,365,368,369,376,377,381,382,385,386,390],{},"WebMCP is explicitly a ",[108,358,359],{},"human-in-the-loop"," API — its own goals call out cooperative workflows where a person delegates to an agent while keeping visibility and control, and rule out fully autonomous, headless operation. There is, as yet, ",[108,362,363],{},"no built-in confirmation or user-prompting primitive"," in ",[25,366,367],{},"registerTool"," (it's an ",[370,371,375],"a",{"href":372,"rel":373},"https:\u002F\u002Fgithub.com\u002Fwebmachinelearning\u002Fwebmcp\u002Fissues\u002F165",[374],"nofollow","open question","). So consent stays a UI decision you make: an agent can ",[378,379,380],"em",{},"set"," a value or ",[378,383,384],{},"open"," a ",[370,387,389],{"href":388},"\u002Fdocs\u002Felements\u002Fdialog","dialog",", but the consequential step — submitting, confirming — remains a deliberate human action. That's the line webmcpui draws by default.",[30,392,394],{"id":393},"imperative-and-declarative","Imperative and declarative",[21,396,397,398,401,402,404,405,408,409,294,412,294,415,294,418,421,422,425,426,430],{},"The API webmcpui builds on is the ",[108,399,400],{},"imperative"," one (",[25,403,367],{},"). A ",[108,406,407],{},"declarative"," companion is also being standardized: native attributes (",[25,410,411],{},"toolname",[25,413,414],{},"tooldescription",[25,416,417],{},"toolparamdescription",[25,419,420],{},"toolautosubmit",") that annotate a plain ",[25,423,424],{},"\u003Cform>"," directly. The two describe the same kind of tool; webmcpui uses the imperative path under the hood because it's the lower-level primitive and the only one that covers interaction beyond forms — a ",[370,427,429],{"href":428},"\u002Fdocs\u002Felements\u002Fbutton","button","'s click or a dialog's open aren't expressible as form annotations.",[30,432,434],{"id":433},"spec-status","Spec status",[21,436,437,438,441,442,444,445,448,449,451,452,454,455,281],{},"As of mid-2026 WebMCP is early but moving: a ",[108,439,440],{},"public origin trial in Chrome 149+",", with Gemini in Chrome as the first consumer. The surface still shifts month to month — it moved to ",[25,443,332],{}," (with ",[25,446,447],{},"navigator.modelContext"," deprecated in Chrome 150), and is ",[25,450,340],{}," for almost everyone else. Everything here is additive and feature-detected, so adopting webmcpui costs nothing today and pays off as hosts ship. webmcpui detects both surfaces and prefers ",[25,453,332],{},". To exercise exposure now, use the ",[370,456,458],{"href":457},"\u002Fdocs\u002Ftesting","fake agent",[460,461,462],"style",{},"html pre.shiki code .sqV5G, html code.shiki .sqV5G{--shiki-default:#1F2328;--shiki-dark:#39BAE680}html pre.shiki code .sfBZl, html code.shiki .sfBZl{--shiki-default:#116329;--shiki-dark:#39BAE6}html pre.shiki code .sI192, html code.shiki .sI192{--shiki-default:#0550AE;--shiki-dark:#FFB454}html pre.shiki code .siQKT, html code.shiki .siQKT{--shiki-default:#1F2328;--shiki-dark:#BFBDB6B3}html pre.shiki code .sxLuP, html code.shiki .sxLuP{--shiki-default:#0A3069;--shiki-dark:#AAD94C}html pre.shiki code .s5O_a, html code.shiki .s5O_a{--shiki-default:#6E7781;--shiki-default-font-style:inherit;--shiki-dark:#5A6673;--shiki-dark-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":43,"searchDepth":99,"depth":99,"links":464},[465,467,468,469,470,471,472],{"id":32,"depth":99,"text":466},"Opt in with expose",{"id":114,"depth":99,"text":115},{"id":196,"depth":99,"text":197},{"id":325,"depth":99,"text":326},{"id":352,"depth":99,"text":353},{"id":393,"depth":99,"text":394},{"id":433,"depth":99,"text":434},"How a form control becomes an imperative WebMCP tool an agent can discover and call.","md","Getting started",{},true,"\u002Fdocs\u002Fwebmcp",{"title":12,"description":473},"docs\u002Fwebmcp","pI-bLkzhBAMfZOK6sW-ZAFVpQfBTCvEWp9huELckAek",[483,487,492,495,499,503,507,510,513,517,521,525,528,531,534,536,539],{"path":428,"title":484,"navTitle":485,"group":486,"order":50,"groupOrder":222},"\u003Cwmcp-button>","Button","Interaction",{"path":488,"title":489,"navTitle":490,"group":491,"order":233,"groupOrder":99},"\u002Fdocs\u002Felements\u002Fcheckbox","\u003Cwmcp-checkbox>","Checkbox","Elements",{"path":388,"title":493,"navTitle":494,"group":486,"order":99,"groupOrder":222},"\u003Cwmcp-dialog>","Dialog",{"path":496,"title":497,"navTitle":498,"group":491,"order":50,"groupOrder":99},"\u002Fdocs\u002Felements\u002Finput","\u003Cwmcp-input>","Input",{"path":500,"title":501,"navTitle":502,"group":486,"order":222,"groupOrder":222},"\u002Fdocs\u002Felements\u002Fmenu","\u003Cwmcp-menu>","Menu",{"path":504,"title":505,"navTitle":506,"group":486,"order":239,"groupOrder":222},"\u002Fdocs\u002Felements\u002Fpopover","\u003Cwmcp-popover>","Popover",{"path":508,"title":297,"navTitle":509,"group":491,"order":239,"groupOrder":99},"\u002Fdocs\u002Felements\u002Fradio","Radio group",{"path":511,"title":293,"navTitle":512,"group":491,"order":222,"groupOrder":99},"\u002Fdocs\u002Felements\u002Fselect","Select",{"path":514,"title":515,"navTitle":516,"group":486,"order":233,"groupOrder":222},"\u002Fdocs\u002Felements\u002Ftabs","\u003Cwmcp-tabs>","Tabs",{"path":518,"title":519,"navTitle":520,"group":491,"order":99,"groupOrder":99},"\u002Fdocs\u002Felements\u002Ftextarea","\u003Cwmcp-textarea>","Textarea",{"path":522,"title":523,"navTitle":524,"group":486,"order":250,"groupOrder":222},"\u002Fdocs\u002Felements\u002Ftoast","\u003Cwmcp-toast>","Toast",{"path":526,"title":527,"navTitle":527,"group":475,"order":250,"groupOrder":50},"\u002Fdocs\u002Fframeworks","React & Vue",{"path":529,"title":530,"navTitle":530,"group":475,"order":50,"groupOrder":50},"\u002Fdocs","Introduction",{"path":532,"title":533,"navTitle":533,"group":475,"order":99,"groupOrder":50},"\u002Fdocs\u002Finstallation","Installation",{"path":457,"title":535,"navTitle":535,"group":475,"order":239,"groupOrder":50},"Testing",{"path":537,"title":538,"navTitle":538,"group":475,"order":222,"groupOrder":50},"\u002Fdocs\u002Fvalidation","Validation",{"path":478,"title":12,"navTitle":12,"group":475,"order":233,"groupOrder":50},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":541},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Cpath d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\"\u002F>\u003Cpath d=\"M14 2v5a1 1 0 0 0 1 1h5M10 9H8m8 4H8m8 4H8\"\u002F>\u003C\u002Fg>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":543},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"m12 19l-7-7l7-7m7 7H5\"\u002F>",1782971919734]