[{"data":1,"prerenderedAt":1897},["ShallowReactive",2],{"navigation_docs":3,"-modules-mcp":153,"-modules-mcp-surround":1892},[4,35,50,59,144],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Local Development","\u002Fgetting-started\u002Flocal-development","1.getting-started\u002F3.local-development","i-lucide-terminal",{"title":21,"path":22,"stem":23,"icon":24},"Publishing Packages","\u002Fgetting-started\u002Fpublishing","1.getting-started\u002F4.publishing","i-lucide-package-check",{"title":26,"path":27,"stem":28,"icon":29},"Writing a Module","\u002Fgetting-started\u002Fwriting-a-module","1.getting-started\u002F5.writing-a-module","i-lucide-puzzle",{"title":31,"path":32,"stem":33,"icon":34},"UX Patterns","\u002Fgetting-started\u002Fux-patterns","1.getting-started\u002F6.ux-patterns","i-lucide-layout-template",{"title":36,"path":37,"stem":38,"children":39},"Applications","\u002Fapplications","2.applications",[40,45],{"title":41,"path":42,"stem":43,"icon":44},"Website","\u002Fapplications\u002Fwebsite","2.applications\u002F1.website","i-lucide-layout-dashboard",{"title":46,"path":47,"stem":48,"icon":49},"Docs","\u002Fapplications\u002Fdocs","2.applications\u002F2.docs","i-lucide-book-open",{"title":51,"path":52,"stem":53,"children":54},"Layers","\u002Flayers","3.layers",[55],{"title":56,"path":57,"stem":58},"Base Layer","\u002Flayers\u002Fbase","3.layers\u002F1.base",{"title":60,"path":61,"stem":62,"children":63},"Modules","\u002Fmodules","4.modules",[64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140],{"title":65,"path":66,"stem":67},"Account","\u002Fmodules\u002Faccount","4.modules\u002F01.account",{"title":69,"path":70,"stem":71},"Admin","\u002Fmodules\u002Fadmin","4.modules\u002F02.admin",{"title":73,"path":74,"stem":75},"Auth","\u002Fmodules\u002Fauth","4.modules\u002F03.auth",{"title":77,"path":78,"stem":79},"Authorization","\u002Fmodules\u002Fauthorization","4.modules\u002F04.authorization",{"title":81,"path":82,"stem":83},"Cookie Consent","\u002Fmodules\u002Fcookie-consent","4.modules\u002F05.cookie-consent",{"title":85,"path":86,"stem":87},"Events","\u002Fmodules\u002Fevents","4.modules\u002F06.events",{"title":89,"path":90,"stem":91},"Forms","\u002Fmodules\u002Fforms","4.modules\u002F07.forms",{"title":93,"path":94,"stem":95},"MCP","\u002Fmodules\u002Fmcp","4.modules\u002F08.mcp",{"title":97,"path":98,"stem":99},"Menu","\u002Fmodules\u002Fmenu","4.modules\u002F09.menu",{"title":101,"path":102,"stem":103},"Module Kit","\u002Fmodules\u002Fmodule-kit","4.modules\u002F10.module-kit",{"title":105,"path":106,"stem":107},"Notify","\u002Fmodules\u002Fnotify","4.modules\u002F11.notify",{"title":109,"path":110,"stem":111},"OAuth Server","\u002Fmodules\u002Foauth-server","4.modules\u002F12.oauth-server",{"title":113,"path":114,"stem":115},"Payments","\u002Fmodules\u002Fpayments","4.modules\u002F13.payments",{"title":117,"path":118,"stem":119},"Preferences","\u002Fmodules\u002Fpreferences","4.modules\u002F14.preferences",{"title":121,"path":122,"stem":123},"Stripe","\u002Fmodules\u002Fstripe","4.modules\u002F15.stripe",{"title":125,"path":126,"stem":127},"Subscriptions","\u002Fmodules\u002Fsubscriptions","4.modules\u002F16.subscriptions",{"title":129,"path":130,"stem":131},"UI","\u002Fmodules\u002Fui","4.modules\u002F17.ui",{"title":133,"path":134,"stem":135},"Users","\u002Fmodules\u002Fusers","4.modules\u002F18.users",{"title":137,"path":138,"stem":139},"Widget","\u002Fmodules\u002Fwidget","4.modules\u002F19.widget",{"title":141,"path":142,"stem":143},"Email Templates","\u002Fmodules\u002Femail-templates","4.modules\u002F20.email-templates",{"title":145,"path":146,"stem":147,"children":148},"Packages","\u002Fpackages","5.packages",[149],{"title":150,"path":151,"stem":152},"CLI","\u002Fpackages\u002Fcli","5.packages\u002F4.cli",{"id":154,"title":93,"body":155,"description":1886,"extension":1887,"links":1888,"meta":1889,"navigation":900,"path":94,"seo":1890,"stem":95,"__hash__":1891},"docs\u002F4.modules\u002F08.mcp.md",{"type":156,"value":157,"toc":1878},"minimark",[158,194,219,224,239,420,424,435,484,499,503,623,627,852,857,861,867,1010,1041,1048,1251,1301,1307,1409,1684,1687,1769,1776,1800,1804,1874],[159,160,161,162,169,170,178,179,182,183,186,187,190,191,193],"p",{},"A ",[163,164,168],"a",{"href":165,"rel":166},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fguide\u002Fmodules",[167],"nofollow","Nuxt module"," on top of ",[163,171,174],{"href":172,"rel":173},"https:\u002F\u002Fmcp-toolkit.nuxt.dev",[167],[175,176,177],"code",{},"@nuxtjs\u002Fmcp-toolkit","\nthat serves one MCP endpoint (",[175,180,181],{},"\u002Fmcp",") for everybody. What a client sees in ",[175,184,185],{},"tools\u002Flist"," depends on who is calling: an\nordinary user sees their own tools, and staff tools appear only when the host's policy lets that user in. Clients\nauthenticate with a user API token (",[175,188,189],{},"Authorization: Bearer fnu_…","), an OAuth access token or a cookie session; see\n",[163,192,73],{"href":74},".",[195,196,197,201,202,207,208,210,211,214,215,218],"note",{},[198,199,200],"strong",{},"Requires"," ",[163,203,204],{"href":74},[175,205,206],{},"@frigear-nu\u002Fauth"," and ",[175,209,177],{}," (",[175,212,213],{},">=0.24.0","); both are installed\nautomatically. Events, Forms, OAuth Server and Subscriptions always depend on this module; Users installs it only\nwhen ",[175,216,217],{},"users.settings.mcp"," is on.",[220,221,223],"h2",{"id":222},"quick-setup","Quick setup",[159,225,226,227,230,231,234,235,238],{},"Exposing tools is opt-in per module: a module contributes its MCP tools only when its ",[175,228,229],{},"settings.mcp"," is ",[175,232,233],{},"true","\n(default ",[175,236,237],{},"false",").",[240,241,246],"pre",{"className":242,"code":243,"language":244,"meta":245,"style":245},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  users: { settings: { mcp: true } },\n  events: { settings: { mcp: true } },\n  forms: { settings: { mcp: true } },\n  subscriptions: { settings: { mcp: true } },\n  oauthServer: { settings: { mcp: true } },\n})\n","ts","",[175,247,248,272,307,333,359,385,411],{"__ignoreMap":245},[249,250,253,257,260,264,268],"span",{"class":251,"line":252},"line",1,[249,254,256],{"class":255},"s7zQu","export",[249,258,259],{"class":255}," default",[249,261,263],{"class":262},"s2Zo4"," defineNuxtConfig",[249,265,267],{"class":266},"sTEyZ","(",[249,269,271],{"class":270},"sMK4o","{\n",[249,273,275,279,282,285,288,290,292,295,297,301,304],{"class":251,"line":274},2,[249,276,278],{"class":277},"swJcz","  users",[249,280,281],{"class":270},":",[249,283,284],{"class":270}," {",[249,286,287],{"class":277}," settings",[249,289,281],{"class":270},[249,291,284],{"class":270},[249,293,294],{"class":277}," mcp",[249,296,281],{"class":270},[249,298,300],{"class":299},"sfNiH"," true",[249,302,303],{"class":270}," }",[249,305,306],{"class":270}," },\n",[249,308,310,313,315,317,319,321,323,325,327,329,331],{"class":251,"line":309},3,[249,311,312],{"class":277},"  events",[249,314,281],{"class":270},[249,316,284],{"class":270},[249,318,287],{"class":277},[249,320,281],{"class":270},[249,322,284],{"class":270},[249,324,294],{"class":277},[249,326,281],{"class":270},[249,328,300],{"class":299},[249,330,303],{"class":270},[249,332,306],{"class":270},[249,334,336,339,341,343,345,347,349,351,353,355,357],{"class":251,"line":335},4,[249,337,338],{"class":277},"  forms",[249,340,281],{"class":270},[249,342,284],{"class":270},[249,344,287],{"class":277},[249,346,281],{"class":270},[249,348,284],{"class":270},[249,350,294],{"class":277},[249,352,281],{"class":270},[249,354,300],{"class":299},[249,356,303],{"class":270},[249,358,306],{"class":270},[249,360,362,365,367,369,371,373,375,377,379,381,383],{"class":251,"line":361},5,[249,363,364],{"class":277},"  subscriptions",[249,366,281],{"class":270},[249,368,284],{"class":270},[249,370,287],{"class":277},[249,372,281],{"class":270},[249,374,284],{"class":270},[249,376,294],{"class":277},[249,378,281],{"class":270},[249,380,300],{"class":299},[249,382,303],{"class":270},[249,384,306],{"class":270},[249,386,388,391,393,395,397,399,401,403,405,407,409],{"class":251,"line":387},6,[249,389,390],{"class":277},"  oauthServer",[249,392,281],{"class":270},[249,394,284],{"class":270},[249,396,287],{"class":277},[249,398,281],{"class":270},[249,400,284],{"class":270},[249,402,294],{"class":277},[249,404,281],{"class":270},[249,406,300],{"class":299},[249,408,303],{"class":270},[249,410,306],{"class":270},[249,412,414,417],{"class":251,"line":413},7,[249,415,416],{"class":270},"}",[249,418,419],{"class":266},")\n",[220,421,423],{"id":422},"options","Options",[159,425,426,427,430,431,434],{},"The config key is ",[175,428,429],{},"mcpModules",", not ",[175,432,433],{},"mcp"," (that belongs to the toolkit).",[436,437,438,457],"table",{},[439,440,441],"thead",{},[442,443,444,448,451,454],"tr",{},[445,446,447],"th",{},"Option",[445,449,450],{},"Type",[445,452,453],{},"Default",[445,455,456],{},"Purpose",[458,459,460],"tbody",{},[442,461,462,468,473,478],{},[463,464,465],"td",{},[175,466,467],{},"route",[463,469,470],{},[175,471,472],{},"string",[463,474,475,476],{},"the toolkit default, ",[175,477,181],{},[463,479,480,481,238],{},"Route of the MCP endpoint (forwarded to the toolkit's ",[175,482,483],{},"mcp.route",[159,485,486,487,490,491,494,495,498],{},"The module also sets the toolkit's standing ",[175,488,489],{},"mcp.instructions"," (unless the host provides its own), which explain to the\nagent that it acts as the signed-in user, that other people's personal data needs a ",[175,492,493],{},"*:pii"," scope, and that some\nsettings (such as where form submissions are delivered) can only be changed in the admin UI, and that money is in whole currency units. It turns on Nitro's\n",[175,496,497],{},"asyncContext",", which the scoped definers use to reach the request.",[220,500,502],{"id":501},"rules-every-tool-follows","Rules every tool follows",[504,505,506,517,538,547,568,601,611,617],"ul",{},[507,508,509,512,513,516],"li",{},[198,510,511],{},"Scopes."," Every definition declares the scopes it needs (registered with ",[175,514,515],{},"addAuthScope","). A token without them\nnever sees the tool, and a direct call is refused.",[507,518,519,201,522,525,526,529,530,533,534,537],{},[198,520,521],{},"Admin tools use the module's own gate.",[175,523,524],{},"events:manage"," plus the ",[175,527,528],{},"events:authorize"," host hook, ",[175,531,532],{},"forms:manage","\nplus ",[175,535,536],{},"forms:authorize",". Both must pass on every listing and every call.",[507,539,540,543,544,238],{},[198,541,542],{},"\"My\" tools take no user id."," They act on the authenticated user (",[175,545,546],{},"ctx.user",[507,548,549,552,553,555,556,559,560,563,564,567],{},[198,550,551],{},"Personal data of others is opt-in."," Staff tools return ids, statuses and counts. Names, emails, form answers and\nfile names need a ",[175,554,493],{}," scope (",[175,557,558],{},"events:pii",", ",[175,561,562],{},"forms:pii",") on top of the manage scope. Responses carry a ",[175,565,566],{},"notice","\nexplaining what was withheld.",[507,569,570,573,574,577,578,581,582,585,586,589,590,593,594,597,598,193],{},[198,571,572],{},"Money is in whole currency units."," Amounts in tool inputs and outputs are major units next to a currency code (",[175,575,576],{},"52.2"," with ",[175,579,580],{},"\"USD\""," is 52.20 US dollars, never ",[175,583,584],{},"5220","), so an agent cannot mistake cents for dollars. Tools convert at the edge with ",[175,587,588],{},"fromCents"," \u002F ",[175,591,592],{},"toCents"," from ",[175,595,596],{},"@frigear-nu\u002Fmcp\u002Futils"," (exponent-aware: JPY has no decimals, KWD has three); the database and REST API keep minor units. Describe money fields with ",[175,599,600],{},"MONEY_NOTICE",[507,602,603,606,607,610],{},[198,604,605],{},"No exfiltration levers."," Where form submissions are delivered (",[175,608,609],{},"delivery",": recipients, webhooks) cannot be read or\nchanged through MCP.",[507,612,613,616],{},[198,614,615],{},"Session-only areas stay out."," User administration and OAuth application administration are not exposed.",[507,618,619,622],{},[198,620,621],{},"Fail closed."," A definition not created with the scoped definers is dropped at runtime, a tool whose input cannot be\ndescribed as JSON Schema is dropped (and logged) instead of breaking the listing, and a failing policy hook hides the\ntool.",[220,624,626],{"id":625},"exposed-tools","Exposed tools",[436,628,629,644],{},[439,630,631],{},[442,632,633,638,641],{},[445,634,635,637],{},[175,636,229],{}," of",[445,639,640],{},"Tool",[445,642,643],{},"Scopes",[458,645,646,669,697,716,739,763,784,801,818,835],{},[442,647,648,653,664],{},[463,649,650],{},[175,651,652],{},"events",[463,654,655,559,658,559,661],{},[175,656,657],{},"list-events",[175,659,660],{},"get-event",[175,662,663],{},"my-tickets",[463,665,666],{},[175,667,668],{},"tickets:read",[442,670,671,676,693],{},[463,672,673,675],{},[175,674,652],{}," (staff)",[463,677,678,559,681,559,684,559,687,559,690],{},[175,679,680],{},"list-all-events",[175,682,683],{},"get-event-definition",[175,685,686],{},"create-event",[175,688,689],{},"update-event",[175,691,692],{},"update-ticket-type",[463,694,695],{},[175,696,524],{},[442,698,699,703,708],{},[463,700,701,675],{},[175,702,652],{},[463,704,705],{},[175,706,707],{},"list-attendees",[463,709,710,712,713,715],{},[175,711,524],{}," (+ ",[175,714,558],{}," for names and emails)",[442,717,718,723,734],{},[463,719,720],{},[175,721,722],{},"forms",[463,724,725,559,728,559,731],{},[175,726,727],{},"list-forms",[175,729,730],{},"get-form",[175,732,733],{},"submit-form",[463,735,736],{},[175,737,738],{},"forms:submit",[442,740,741,745,759],{},[463,742,743,675],{},[175,744,722],{},[463,746,747,559,750,559,753,559,756],{},[175,748,749],{},"list-all-forms",[175,751,752],{},"get-form-definition",[175,754,755],{},"create-form",[175,757,758],{},"update-form",[463,760,761],{},[175,762,532],{},[442,764,765,769,777],{},[463,766,767,675],{},[175,768,722],{},[463,770,771,559,774],{},[175,772,773],{},"list-submissions",[175,775,776],{},"get-submission",[463,778,779,712,781,783],{},[175,780,532],{},[175,782,562],{}," for answers)",[442,785,786,791,796],{},[463,787,788],{},[175,789,790],{},"oauthServer",[463,792,793],{},[175,794,795],{},"my-oauth-applications",[463,797,798],{},[175,799,800],{},"oauth:read",[442,802,803,808,813],{},[463,804,805],{},[175,806,807],{},"users",[463,809,810],{},[175,811,812],{},"get-my-profile",[463,814,815],{},[175,816,817],{},"profile:read",[442,819,820,825,830],{},[463,821,822],{},[175,823,824],{},"payments",[463,826,827],{},[175,828,829],{},"my-payments",[463,831,832],{},[175,833,834],{},"payments:read",[442,836,837,842,847],{},[463,838,839],{},[175,840,841],{},"subscriptions",[463,843,844],{},[175,845,846],{},"my-subscriptions",[463,848,849],{},[175,850,851],{},"subscriptions:read",[159,853,854,856],{},[175,855,733],{}," always submits as the caller and works for forms open to everyone or to signed-in users; forms that need\ntheir own token or password are refused.",[220,858,860],{"id":859},"server","Server",[159,862,863,864,281],{},"Add tools to a module from its ",[175,865,866],{},"setup()",[240,868,870],{"className":242,"code":869,"language":244,"meta":245,"style":245},"import { addMcpDefinitions } from '@frigear-nu\u002Fmcp\u002Futils'\n\n\u002F\u002F moduleDependencies: { '@frigear-nu\u002Fmcp': { version: '>=0.0.1' } }\naddAuthScope(nuxt, { name: 'notes:read', description: 'Read your notes' })\n\u002F\u002F Opt-in: only register when the host enabled it, as the built-in modules do.\nif (options.settings?.mcp === true) addMcpDefinitions(nuxt, resolver.resolve('.\u002Fruntime\u002Fserver\u002Fmcp'))\n",[175,871,872,896,902,908,951,956],{"__ignoreMap":245},[249,873,874,877,879,882,884,887,890,893],{"class":251,"line":252},[249,875,876],{"class":255},"import",[249,878,284],{"class":270},[249,880,881],{"class":266}," addMcpDefinitions",[249,883,303],{"class":270},[249,885,886],{"class":255}," from",[249,888,889],{"class":270}," '",[249,891,596],{"class":892},"sfazB",[249,894,895],{"class":270},"'\n",[249,897,898],{"class":251,"line":274},[249,899,901],{"emptyLinePlaceholder":900},true,"\n",[249,903,904],{"class":251,"line":309},[249,905,907],{"class":906},"sHwdD","\u002F\u002F moduleDependencies: { '@frigear-nu\u002Fmcp': { version: '>=0.0.1' } }\n",[249,909,910,912,915,918,920,923,925,927,930,933,935,938,940,942,945,947,949],{"class":251,"line":335},[249,911,515],{"class":262},[249,913,914],{"class":266},"(nuxt",[249,916,917],{"class":270},",",[249,919,284],{"class":270},[249,921,922],{"class":277}," name",[249,924,281],{"class":270},[249,926,889],{"class":270},[249,928,929],{"class":892},"notes:read",[249,931,932],{"class":270},"'",[249,934,917],{"class":270},[249,936,937],{"class":277}," description",[249,939,281],{"class":270},[249,941,889],{"class":270},[249,943,944],{"class":892},"Read your notes",[249,946,932],{"class":270},[249,948,303],{"class":270},[249,950,419],{"class":266},[249,952,953],{"class":251,"line":361},[249,954,955],{"class":906},"\u002F\u002F Opt-in: only register when the host enabled it, as the built-in modules do.\n",[249,957,958,961,964,966,969,972,975,978,980,983,986,988,990,993,995,998,1000,1002,1005,1007],{"class":251,"line":387},[249,959,960],{"class":255},"if",[249,962,963],{"class":266}," (options",[249,965,193],{"class":270},[249,967,968],{"class":266},"settings",[249,970,971],{"class":270},"?.",[249,973,974],{"class":266},"mcp ",[249,976,977],{"class":270},"===",[249,979,300],{"class":299},[249,981,982],{"class":266},") ",[249,984,985],{"class":262},"addMcpDefinitions",[249,987,914],{"class":266},[249,989,917],{"class":270},[249,991,992],{"class":266}," resolver",[249,994,193],{"class":270},[249,996,997],{"class":262},"resolve",[249,999,267],{"class":266},[249,1001,932],{"class":270},[249,1003,1004],{"class":892},".\u002Fruntime\u002Fserver\u002Fmcp",[249,1006,932],{"class":270},[249,1008,1009],{"class":266},"))\n",[159,1011,1012,1015,1016,1019,1020,1023,1024,207,1027,1030,1031,1033,1034,1037,1038,238],{},[175,1013,1014],{},"addMcpDefinitions(nuxt, dir)"," takes a directory laid out like a project's ",[175,1017,1018],{},"server\u002Fmcp",": optional ",[175,1021,1022],{},"tools\u002F",",\n",[175,1025,1026],{},"resources\u002F",[175,1028,1029],{},"prompts\u002F"," folders. Subfolders of ",[175,1032,1022],{}," become groups (",[175,1035,1036],{},"tools\u002Fadmin\u002F…"," is group ",[175,1039,1040],{},"admin",[159,1042,1043,1044,1047],{},"The auto-imported definers share the access options and pass a ",[175,1045,1046],{},"ScopedMcpContext"," to the handler:",[240,1049,1051],{"className":242,"code":1050,"language":244,"meta":245,"style":245},"interface ScopedAccess {\n  \u002F** Required: a definition without scopes is never exposed. *\u002F\n  scopes: string[]\n  \u002F** Never exposed to API tokens or OAuth tokens. *\u002F\n  sessionOnly?: boolean\n  \u002F** Extra check on every listing and call, typically the module's `*:authorize` hook. Identify the caller from `principal.user.id`. *\u002F\n  gate?: (event: H3Event, principal: AuthPrincipal) => boolean | Promise\u003Cboolean>\n}\n\ninterface ScopedMcpContext {\n  event: H3Event\n  principal: AuthPrincipal\n  \u002F** The authenticated user. Use this; never take a user id as an argument. *\u002F\n  user: AuthUser\n  \u002F** Whether the credential carries `scope` (e.g. an opt-in `*:pii` scope). *\u002F\n  hasScope: (scope: string) => boolean\n}\n",[175,1052,1053,1066,1071,1084,1089,1100,1105,1157,1163,1168,1178,1189,1200,1206,1217,1223,1246],{"__ignoreMap":245},[249,1054,1055,1059,1063],{"class":251,"line":252},[249,1056,1058],{"class":1057},"spNyl","interface",[249,1060,1062],{"class":1061},"sBMFI"," ScopedAccess",[249,1064,1065],{"class":270}," {\n",[249,1067,1068],{"class":251,"line":274},[249,1069,1070],{"class":906},"  \u002F** Required: a definition without scopes is never exposed. *\u002F\n",[249,1072,1073,1076,1078,1081],{"class":251,"line":309},[249,1074,1075],{"class":277},"  scopes",[249,1077,281],{"class":270},[249,1079,1080],{"class":1061}," string",[249,1082,1083],{"class":266},"[]\n",[249,1085,1086],{"class":251,"line":335},[249,1087,1088],{"class":906},"  \u002F** Never exposed to API tokens or OAuth tokens. *\u002F\n",[249,1090,1091,1094,1097],{"class":251,"line":361},[249,1092,1093],{"class":277},"  sessionOnly",[249,1095,1096],{"class":270},"?:",[249,1098,1099],{"class":1061}," boolean\n",[249,1101,1102],{"class":251,"line":387},[249,1103,1104],{"class":906},"  \u002F** Extra check on every listing and call, typically the module's `*:authorize` hook. Identify the caller from `principal.user.id`. *\u002F\n",[249,1106,1107,1110,1112,1114,1118,1120,1123,1125,1128,1130,1133,1136,1139,1142,1145,1148,1151,1154],{"class":251,"line":413},[249,1108,1109],{"class":277},"  gate",[249,1111,1096],{"class":270},[249,1113,210],{"class":270},[249,1115,1117],{"class":1116},"sHdIc","event",[249,1119,281],{"class":270},[249,1121,1122],{"class":1061}," H3Event",[249,1124,917],{"class":270},[249,1126,1127],{"class":1116}," principal",[249,1129,281],{"class":270},[249,1131,1132],{"class":1061}," AuthPrincipal",[249,1134,1135],{"class":270},")",[249,1137,1138],{"class":1057}," =>",[249,1140,1141],{"class":1061}," boolean",[249,1143,1144],{"class":270}," |",[249,1146,1147],{"class":1061}," Promise",[249,1149,1150],{"class":270},"\u003C",[249,1152,1153],{"class":1061},"boolean",[249,1155,1156],{"class":270},">\n",[249,1158,1160],{"class":251,"line":1159},8,[249,1161,1162],{"class":270},"}\n",[249,1164,1166],{"class":251,"line":1165},9,[249,1167,901],{"emptyLinePlaceholder":900},[249,1169,1171,1173,1176],{"class":251,"line":1170},10,[249,1172,1058],{"class":1057},[249,1174,1175],{"class":1061}," ScopedMcpContext",[249,1177,1065],{"class":270},[249,1179,1181,1184,1186],{"class":251,"line":1180},11,[249,1182,1183],{"class":277},"  event",[249,1185,281],{"class":270},[249,1187,1188],{"class":1061}," H3Event\n",[249,1190,1192,1195,1197],{"class":251,"line":1191},12,[249,1193,1194],{"class":277},"  principal",[249,1196,281],{"class":270},[249,1198,1199],{"class":1061}," AuthPrincipal\n",[249,1201,1203],{"class":251,"line":1202},13,[249,1204,1205],{"class":906},"  \u002F** The authenticated user. Use this; never take a user id as an argument. *\u002F\n",[249,1207,1209,1212,1214],{"class":251,"line":1208},14,[249,1210,1211],{"class":277},"  user",[249,1213,281],{"class":270},[249,1215,1216],{"class":1061}," AuthUser\n",[249,1218,1220],{"class":251,"line":1219},15,[249,1221,1222],{"class":906},"  \u002F** Whether the credential carries `scope` (e.g. an opt-in `*:pii` scope). *\u002F\n",[249,1224,1226,1229,1231,1233,1236,1238,1240,1242,1244],{"class":251,"line":1225},16,[249,1227,1228],{"class":277},"  hasScope",[249,1230,281],{"class":270},[249,1232,210],{"class":270},[249,1234,1235],{"class":1116},"scope",[249,1237,281],{"class":270},[249,1239,1080],{"class":1061},[249,1241,1135],{"class":270},[249,1243,1138],{"class":1057},[249,1245,1099],{"class":1061},[249,1247,1249],{"class":251,"line":1248},17,[249,1250,1162],{"class":270},[436,1252,1253,1263],{},[439,1254,1255],{},[442,1256,1257,1260],{},[445,1258,1259],{},"Definer",[445,1261,1262],{},"Handler signature",[458,1264,1265,1277,1289],{},[442,1266,1267,1272],{},[463,1268,1269],{},[175,1270,1271],{},"defineScopedMcpTool",[463,1273,1274],{},[175,1275,1276],{},"(args, ctx: ScopedMcpContext, extra) => result",[442,1278,1279,1284],{},[463,1280,1281],{},[175,1282,1283],{},"defineScopedMcpResource",[463,1285,1286],{},[175,1287,1288],{},"(ctx: ScopedMcpContext, ...toolkitResourceArgs) => result",[442,1290,1291,1296],{},[463,1292,1293],{},[175,1294,1295],{},"defineScopedMcpPrompt",[463,1297,1298],{},[175,1299,1300],{},"(args, ctx: ScopedMcpContext) => result",[159,1302,1303,1304,193],{},"Each takes the toolkit's own definition options plus ",[175,1305,1306],{},"ScopedAccess",[240,1308,1310],{"className":242,"code":1309,"language":244,"meta":245,"style":245},"\u002F\u002F runtime\u002Fserver\u002Fmcp\u002Ftools\u002Fmy-notes.ts\nexport default defineScopedMcpTool({\n  description: 'List my notes',\n  scopes: ['notes:read'],\n  handler: (_args, { user }) => listNotes(user.id),\n})\n",[175,1311,1312,1317,1330,1346,1366,1403],{"__ignoreMap":245},[249,1313,1314],{"class":251,"line":252},[249,1315,1316],{"class":906},"\u002F\u002F runtime\u002Fserver\u002Fmcp\u002Ftools\u002Fmy-notes.ts\n",[249,1318,1319,1321,1323,1326,1328],{"class":251,"line":274},[249,1320,256],{"class":255},[249,1322,259],{"class":255},[249,1324,1325],{"class":262}," defineScopedMcpTool",[249,1327,267],{"class":266},[249,1329,271],{"class":270},[249,1331,1332,1335,1337,1339,1342,1344],{"class":251,"line":309},[249,1333,1334],{"class":277},"  description",[249,1336,281],{"class":270},[249,1338,889],{"class":270},[249,1340,1341],{"class":892},"List my notes",[249,1343,932],{"class":270},[249,1345,1023],{"class":270},[249,1347,1348,1350,1352,1355,1357,1359,1361,1364],{"class":251,"line":335},[249,1349,1075],{"class":277},[249,1351,281],{"class":270},[249,1353,1354],{"class":266}," [",[249,1356,932],{"class":270},[249,1358,929],{"class":892},[249,1360,932],{"class":270},[249,1362,1363],{"class":266},"]",[249,1365,1023],{"class":270},[249,1367,1368,1371,1373,1375,1378,1380,1382,1385,1388,1390,1393,1396,1398,1401],{"class":251,"line":361},[249,1369,1370],{"class":262},"  handler",[249,1372,281],{"class":270},[249,1374,210],{"class":270},[249,1376,1377],{"class":1116},"_args",[249,1379,917],{"class":270},[249,1381,284],{"class":270},[249,1383,1384],{"class":1116}," user",[249,1386,1387],{"class":270}," })",[249,1389,1138],{"class":1057},[249,1391,1392],{"class":262}," listNotes",[249,1394,1395],{"class":266},"(user",[249,1397,193],{"class":270},[249,1399,1400],{"class":266},"id)",[249,1402,1023],{"class":270},[249,1404,1405,1407],{"class":251,"line":387},[249,1406,416],{"class":270},[249,1408,419],{"class":266},[240,1410,1412],{"className":242,"code":1411,"language":244,"meta":245,"style":245},"\u002F\u002F runtime\u002Fserver\u002Fmcp\u002Ftools\u002Fadmin\u002Flist-all-notes.ts\nexport default defineScopedMcpTool({\n  description: 'List every note (staff)',\n  scopes: ['notes:manage'],\n  gate: canManageNotes, \u002F\u002F e.g. your `notes:authorize` hook\n  handler: (_args, ctx) => {\n    const allow = ctx.hasScope('notes:pii')\n    const notes = listAllNotes().map(note => redactPii(pick(note, ['id', 'text', 'ownerEmail']), { allow, fields: ['ownerEmail'] }))\n    return { notice: piiNotice(allow, 'notes:pii', 'Owner emails'), notes }\n  },\n})\n",[175,1413,1414,1419,1431,1446,1465,1479,1500,1529,1627,1673,1678],{"__ignoreMap":245},[249,1415,1416],{"class":251,"line":252},[249,1417,1418],{"class":906},"\u002F\u002F runtime\u002Fserver\u002Fmcp\u002Ftools\u002Fadmin\u002Flist-all-notes.ts\n",[249,1420,1421,1423,1425,1427,1429],{"class":251,"line":274},[249,1422,256],{"class":255},[249,1424,259],{"class":255},[249,1426,1325],{"class":262},[249,1428,267],{"class":266},[249,1430,271],{"class":270},[249,1432,1433,1435,1437,1439,1442,1444],{"class":251,"line":309},[249,1434,1334],{"class":277},[249,1436,281],{"class":270},[249,1438,889],{"class":270},[249,1440,1441],{"class":892},"List every note (staff)",[249,1443,932],{"class":270},[249,1445,1023],{"class":270},[249,1447,1448,1450,1452,1454,1456,1459,1461,1463],{"class":251,"line":335},[249,1449,1075],{"class":277},[249,1451,281],{"class":270},[249,1453,1354],{"class":266},[249,1455,932],{"class":270},[249,1457,1458],{"class":892},"notes:manage",[249,1460,932],{"class":270},[249,1462,1363],{"class":266},[249,1464,1023],{"class":270},[249,1466,1467,1469,1471,1474,1476],{"class":251,"line":361},[249,1468,1109],{"class":277},[249,1470,281],{"class":270},[249,1472,1473],{"class":266}," canManageNotes",[249,1475,917],{"class":270},[249,1477,1478],{"class":906}," \u002F\u002F e.g. your `notes:authorize` hook\n",[249,1480,1481,1483,1485,1487,1489,1491,1494,1496,1498],{"class":251,"line":387},[249,1482,1370],{"class":262},[249,1484,281],{"class":270},[249,1486,210],{"class":270},[249,1488,1377],{"class":1116},[249,1490,917],{"class":270},[249,1492,1493],{"class":1116}," ctx",[249,1495,1135],{"class":270},[249,1497,1138],{"class":1057},[249,1499,1065],{"class":270},[249,1501,1502,1505,1508,1511,1513,1515,1518,1520,1522,1525,1527],{"class":251,"line":413},[249,1503,1504],{"class":1057},"    const",[249,1506,1507],{"class":266}," allow",[249,1509,1510],{"class":270}," =",[249,1512,1493],{"class":266},[249,1514,193],{"class":270},[249,1516,1517],{"class":262},"hasScope",[249,1519,267],{"class":277},[249,1521,932],{"class":270},[249,1523,1524],{"class":892},"notes:pii",[249,1526,932],{"class":270},[249,1528,419],{"class":277},[249,1530,1531,1533,1536,1538,1541,1544,1546,1549,1551,1553,1555,1558,1560,1563,1565,1567,1569,1571,1573,1576,1578,1580,1582,1585,1587,1589,1591,1594,1596,1599,1601,1603,1605,1607,1610,1612,1614,1616,1618,1620,1623,1625],{"class":251,"line":1159},[249,1532,1504],{"class":1057},[249,1534,1535],{"class":266}," notes",[249,1537,1510],{"class":270},[249,1539,1540],{"class":262}," listAllNotes",[249,1542,1543],{"class":277},"()",[249,1545,193],{"class":270},[249,1547,1548],{"class":262},"map",[249,1550,267],{"class":277},[249,1552,195],{"class":1116},[249,1554,1138],{"class":1057},[249,1556,1557],{"class":262}," redactPii",[249,1559,267],{"class":277},[249,1561,1562],{"class":262},"pick",[249,1564,267],{"class":277},[249,1566,195],{"class":266},[249,1568,917],{"class":270},[249,1570,1354],{"class":277},[249,1572,932],{"class":270},[249,1574,1575],{"class":892},"id",[249,1577,932],{"class":270},[249,1579,917],{"class":270},[249,1581,889],{"class":270},[249,1583,1584],{"class":892},"text",[249,1586,932],{"class":270},[249,1588,917],{"class":270},[249,1590,889],{"class":270},[249,1592,1593],{"class":892},"ownerEmail",[249,1595,932],{"class":270},[249,1597,1598],{"class":277},"])",[249,1600,917],{"class":270},[249,1602,284],{"class":270},[249,1604,1507],{"class":266},[249,1606,917],{"class":270},[249,1608,1609],{"class":277}," fields",[249,1611,281],{"class":270},[249,1613,1354],{"class":277},[249,1615,932],{"class":270},[249,1617,1593],{"class":892},[249,1619,932],{"class":270},[249,1621,1622],{"class":277},"] ",[249,1624,416],{"class":270},[249,1626,1009],{"class":277},[249,1628,1629,1632,1634,1637,1639,1642,1644,1647,1649,1651,1653,1655,1657,1659,1662,1664,1666,1668,1670],{"class":251,"line":1165},[249,1630,1631],{"class":255},"    return",[249,1633,284],{"class":270},[249,1635,1636],{"class":277}," notice",[249,1638,281],{"class":270},[249,1640,1641],{"class":262}," piiNotice",[249,1643,267],{"class":277},[249,1645,1646],{"class":266},"allow",[249,1648,917],{"class":270},[249,1650,889],{"class":270},[249,1652,1524],{"class":892},[249,1654,932],{"class":270},[249,1656,917],{"class":270},[249,1658,889],{"class":270},[249,1660,1661],{"class":892},"Owner emails",[249,1663,932],{"class":270},[249,1665,1135],{"class":277},[249,1667,917],{"class":270},[249,1669,1535],{"class":266},[249,1671,1672],{"class":270}," }\n",[249,1674,1675],{"class":251,"line":1170},[249,1676,1677],{"class":270},"  },\n",[249,1679,1680,1682],{"class":251,"line":1180},[249,1681,416],{"class":270},[249,1683,419],{"class":266},[159,1685,1686],{},"Helpers (also auto-imported):",[240,1688,1690],{"className":242,"code":1689,"language":244,"meta":245,"style":245},"pick(row, ['id', 'text']) \u002F\u002F an explicit allow-list, so a new column is never exposed by accident\nredactPii(row, { allow, fields }) \u002F\u002F drops `fields` unless `allow`\npiiNotice(allowed, scope, fieldsLabel) \u002F\u002F message for the agent when data was withheld; undefined when allowed\n",[175,1691,1692,1723,1748],{"__ignoreMap":245},[249,1693,1694,1696,1699,1701,1703,1705,1707,1709,1711,1713,1715,1717,1720],{"class":251,"line":252},[249,1695,1562],{"class":262},[249,1697,1698],{"class":266},"(row",[249,1700,917],{"class":270},[249,1702,1354],{"class":266},[249,1704,932],{"class":270},[249,1706,1575],{"class":892},[249,1708,932],{"class":270},[249,1710,917],{"class":270},[249,1712,889],{"class":270},[249,1714,1584],{"class":892},[249,1716,932],{"class":270},[249,1718,1719],{"class":266},"]) ",[249,1721,1722],{"class":906},"\u002F\u002F an explicit allow-list, so a new column is never exposed by accident\n",[249,1724,1725,1728,1730,1732,1734,1736,1738,1741,1743,1745],{"class":251,"line":274},[249,1726,1727],{"class":262},"redactPii",[249,1729,1698],{"class":266},[249,1731,917],{"class":270},[249,1733,284],{"class":270},[249,1735,1507],{"class":266},[249,1737,917],{"class":270},[249,1739,1740],{"class":266}," fields ",[249,1742,416],{"class":270},[249,1744,982],{"class":266},[249,1746,1747],{"class":906},"\u002F\u002F drops `fields` unless `allow`\n",[249,1749,1750,1753,1756,1758,1761,1763,1766],{"class":251,"line":309},[249,1751,1752],{"class":262},"piiNotice",[249,1754,1755],{"class":266},"(allowed",[249,1757,917],{"class":270},[249,1759,1760],{"class":266}," scope",[249,1762,917],{"class":270},[249,1764,1765],{"class":266}," fieldsLabel) ",[249,1767,1768],{"class":906},"\u002F\u002F message for the agent when data was withheld; undefined when allowed\n",[159,1770,1771,1772,1775],{},"Return explicit allow-listed fields and never a raw database row. Define input schemas with plain types: zod\ntransforms and ",[175,1773,1774],{},"z.coerce.date()"," cannot be sent to clients as JSON Schema, so parse with your REST schema inside the\nhandler instead.",[159,1777,1778,1780,1781,559,1784,559,1787,1790,1791,1023,1793,207,1796,1799],{},[175,1779,596],{}," also exports ",[175,1782,1783],{},"isPrincipalAllowed",[175,1785,1786],{},"scopeTags",[175,1788,1789],{},"SCOPED_META_KEY"," and the ",[175,1792,1306],{},[175,1794,1795],{},"RedactOptions",[175,1797,1798],{},"McpDefinitionKind"," types.",[220,1801,1803],{"id":1802},"hooks","Hooks",[436,1805,1806,1819],{},[439,1807,1808],{},[442,1809,1810,1813,1816],{},[445,1811,1812],{},"Hook",[445,1814,1815],{},"When",[445,1817,1818],{},"Payload",[458,1820,1821,1841,1858],{},[442,1822,1823,1829,1832],{},[463,1824,1825,1828],{},[175,1826,1827],{},"mcp:definitions:paths"," (Nuxt)",[463,1830,1831],{},"Build time, collecting definition folders",[463,1833,1834,1837,1838,1840],{},[175,1835,1836],{},"{ tools, resources, prompts, handlers: string[] }","; ",[175,1839,985],{}," pushes to it",[442,1842,1843,1849,1852],{},[463,1844,1845,1848],{},[175,1846,1847],{},"mcp:config:resolved"," (Nitro, from the toolkit)",[463,1850,1851],{},"The resolved config is built per request",[463,1853,1854,1857],{},[175,1855,1856],{},"{ config, event }","; the module filters out unscoped or non-serializable definitions here",[442,1859,1860,1865,1868],{},[463,1861,1862,1848],{},[175,1863,1864],{},"mcp:tool:called",[463,1866,1867],{},"After every tool call",[463,1869,1870,1873],{},[175,1871,1872],{},"{ name, result, durationMs, event }","; the module logs who called which tool (never arguments or results)",[1875,1876,1877],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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);}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}",{"title":245,"searchDepth":274,"depth":274,"links":1879},[1880,1881,1882,1883,1884,1885],{"id":222,"depth":274,"text":223},{"id":422,"depth":274,"text":423},{"id":501,"depth":274,"text":502},{"id":625,"depth":274,"text":626},{"id":859,"depth":274,"text":860},{"id":1802,"depth":274,"text":1803},"Modules contribute MCP tools that are only listed and callable within the scopes the caller holds, without leaking other people's personal data.","md",null,{},{"title":93,"description":1886},"5313eCFXatcHCUJQhOVDhl671qOcijrOi4q8P1f0sSA",[1893,1895],{"title":89,"path":90,"stem":91,"description":1894,"children":-1},"Dynamic forms stored in the database - single page or stepped, conditional fields, file uploads, stored or email-only submissions.",{"title":97,"path":98,"stem":99,"description":1896,"children":-1},"Named, shareable navigation menus - modules contribute items, Nuxt Content can too, consumers read and render them.",1792824485286]