[{"data":1,"prerenderedAt":3235},["ShallowReactive",2],{"navigation_docs":3,"-examples-authentication":282,"-examples-authentication-surround":3230},[4,40,70,99,122,156,189,253],{"title":5,"path":6,"stem":7,"children":8,"page":39},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29,34],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Configuration","\u002Fgetting-started\u002Fconfiguration","1.getting-started\u002F3.configuration","i-lucide-settings",{"title":25,"path":26,"stem":27,"icon":28},"Inspector","\u002Fgetting-started\u002Finspector","1.getting-started\u002F4.inspector","i-lucide-circuit-board",{"title":30,"path":31,"stem":32,"icon":33},"Connection","\u002Fgetting-started\u002Fconnection","1.getting-started\u002F5.connection","i-lucide-plug",{"title":35,"path":36,"stem":37,"icon":38},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F6.agent-skills","i-lucide-sparkles",false,{"title":41,"path":42,"stem":43,"children":44,"page":39},"Tools","\u002Ftools","2.tools",[45,50,55,60,65],{"title":46,"path":47,"stem":48,"icon":49},"Overview","\u002Ftools\u002Foverview","2.tools\u002F0.overview","i-lucide-wrench",{"title":51,"path":52,"stem":53,"icon":54},"Schema, handler & returns","\u002Ftools\u002Fschema-handler","2.tools\u002F1.schema-handler","i-lucide-braces",{"title":56,"path":57,"stem":58,"icon":59},"Annotations & input examples","\u002Ftools\u002Fannotations","2.tools\u002F2.annotations","i-lucide-badge-info",{"title":61,"path":62,"stem":63,"icon":64},"Errors & caching","\u002Ftools\u002Ferrors-caching","2.tools\u002F3.errors-caching","i-lucide-shield",{"title":66,"path":67,"stem":68,"icon":69},"Groups, files & dynamic registration","\u002Ftools\u002Fgroups-organization","2.tools\u002F4.groups-organization","i-lucide-tags",{"title":71,"path":72,"stem":73,"children":74,"page":39},"Resources","\u002Fresources","3.resources",[75,79,84,89,94],{"title":46,"path":76,"stem":77,"icon":78},"\u002Fresources\u002Foverview","3.resources\u002F0.overview","i-lucide-package",{"title":80,"path":81,"stem":82,"icon":83},"Static resources & structure","\u002Fresources\u002Fstatic-and-structure","3.resources\u002F1.static-and-structure","i-lucide-file-stack",{"title":85,"path":86,"stem":87,"icon":88},"Templates & handlers","\u002Fresources\u002Ftemplates-and-handlers","3.resources\u002F2.templates-and-handlers","i-lucide-git-branch",{"title":90,"path":91,"stem":92,"icon":93},"Metadata, content & errors","\u002Fresources\u002Fcontent-metadata-errors","3.resources\u002F3.content-metadata-errors","i-lucide-layers",{"title":95,"path":96,"stem":97,"icon":98},"Groups & organization","\u002Fresources\u002Forganization","3.resources\u002F4.organization","i-lucide-folder-tree",{"title":100,"path":101,"stem":102,"children":103,"page":39},"Prompts","\u002Fprompts","4.prompts",[104,108,113,117],{"title":46,"path":105,"stem":106,"icon":107},"\u002Fprompts\u002Foverview","4.prompts\u002F0.overview","i-lucide-message-square",{"title":109,"path":110,"stem":111,"icon":112},"Authoring & structure","\u002Fprompts\u002Fauthoring","4.prompts\u002F1.authoring","i-lucide-pen-line",{"title":114,"path":115,"stem":116,"icon":93},"Input, handler & messages","\u002Fprompts\u002Finput-handler-messages","4.prompts\u002F2.input-handler-messages",{"title":118,"path":119,"stem":120,"icon":121},"Patterns & advanced","\u002Fprompts\u002Fpatterns-advanced","4.prompts\u002F3.patterns-advanced","i-lucide-line-chart",{"title":123,"path":124,"stem":125,"children":126,"page":39},"Handlers","\u002Fhandlers","5.handlers",[127,131,136,141,146,151],{"title":46,"path":128,"stem":129,"icon":130},"\u002Fhandlers\u002Foverview","5.handlers\u002F0.overview","i-lucide-server",{"title":132,"path":133,"stem":134,"icon":135},"Default & custom handlers","\u002Fhandlers\u002Fdefault-and-custom","5.handlers\u002F1.default-and-custom","i-lucide-toggle-left",{"title":137,"path":138,"stem":139,"icon":140},"Structure & options","\u002Fhandlers\u002Fstructure-and-options","5.handlers\u002F2.structure-and-options","i-lucide-sliders-horizontal",{"title":142,"path":143,"stem":144,"icon":145},"Examples & routing","\u002Fhandlers\u002Fexamples-routing","5.handlers\u002F3.examples-routing","i-lucide-route",{"title":147,"path":148,"stem":149,"icon":150},"Sharing & practices","\u002Fhandlers\u002Fsharing-practices","5.handlers\u002F4.sharing-practices","i-lucide-share-2",{"title":152,"path":153,"stem":154,"icon":155},"Multi-handler organization","\u002Fhandlers\u002Forganization","5.handlers\u002F5.organization","i-lucide-network",{"title":157,"path":158,"stem":159,"children":160,"page":39},"Apps","\u002Fapps","6.apps",[161,165,170,175,179,184],{"title":46,"path":162,"stem":163,"icon":164},"\u002Fapps\u002Foverview","6.apps\u002F0.overview","i-lucide-app-window",{"title":166,"path":167,"stem":168,"icon":169},"Authoring & defineMcpApp","\u002Fapps\u002Fauthoring","6.apps\u002F1.authoring","i-lucide-code-2",{"title":171,"path":172,"stem":173,"icon":174},"useMcpApp() bridge","\u002Fapps\u002Fuse-mcp-app","6.apps\u002F2.use-mcp-app","i-lucide-message-circle",{"title":176,"path":177,"stem":178,"icon":64},"CSP & build pipeline","\u002Fapps\u002Fcsp-and-wiring","6.apps\u002F3.csp-and-wiring",{"title":180,"path":181,"stem":182,"icon":183},"Testing & publishing","\u002Fapps\u002Ftesting-publishing","6.apps\u002F4.testing-publishing","i-lucide-rocket",{"title":185,"path":186,"stem":187,"icon":188},"Patterns & limits","\u002Fapps\u002Fpatterns-reference","6.apps\u002F5.patterns-reference","i-lucide-book-marked",{"title":190,"path":191,"stem":192,"children":193,"page":39},"Advanced Topics","\u002Fadvanced","7.advanced",[194,199,204,209,214,218,223,228,233,238,243,248],{"title":195,"path":196,"stem":197,"icon":198},"Custom Paths","\u002Fadvanced\u002Fcustom-paths","7.advanced\u002F1.custom-paths","i-lucide-folder",{"title":200,"path":201,"stem":202,"icon":203},"Logging","\u002Fadvanced\u002Flogging","7.advanced\u002F10.logging","i-lucide-scroll-text",{"title":205,"path":206,"stem":207,"icon":208},"MCP Apps Internals","\u002Fadvanced\u002Fmcp-apps-internals","7.advanced\u002F11.mcp-apps-internals","i-lucide-cog",{"title":210,"path":211,"stem":212,"icon":213},"Listing Definitions","\u002Fadvanced\u002Flisting-definitions","7.advanced\u002F12.listing-definitions","i-lucide-list",{"title":215,"path":216,"stem":217,"icon":64},"Middleware","\u002Fadvanced\u002Fmiddleware","7.advanced\u002F2.middleware",{"title":219,"path":220,"stem":221,"icon":222},"TypeScript","\u002Fadvanced\u002Ftypescript","7.advanced\u002F3.typescript","i-lucide-type",{"title":224,"path":225,"stem":226,"icon":227},"Hooks","\u002Fadvanced\u002Fhooks","7.advanced\u002F4.hooks","i-lucide-webhook",{"title":229,"path":230,"stem":231,"icon":232},"MCP Evals","\u002Fadvanced\u002Fevals","7.advanced\u002F5.evals","i-lucide-flask-conical",{"title":234,"path":235,"stem":236,"icon":237},"Sessions","\u002Fadvanced\u002Fsessions","7.advanced\u002F6.sessions","i-lucide-database",{"title":239,"path":240,"stem":241,"icon":242},"Dynamic Definitions","\u002Fadvanced\u002Fdynamic-definitions","7.advanced\u002F7.dynamic-definitions","i-lucide-toggle-right",{"title":244,"path":245,"stem":246,"icon":247},"Code Mode","\u002Fadvanced\u002Fcode-mode","7.advanced\u002F8.code-mode","i-lucide-code",{"title":249,"path":250,"stem":251,"icon":252},"Elicitation","\u002Fadvanced\u002Felicitation","7.advanced\u002F9.elicitation","i-lucide-message-square-quote",{"title":254,"path":255,"stem":256,"children":257,"page":39},"Examples","\u002Fexamples","8.examples",[258,263,268,273,278],{"title":259,"path":260,"stem":261,"icon":262},"Authentication","\u002Fexamples\u002Fauthentication","8.examples\u002F1.authentication","i-lucide-shield-check",{"title":264,"path":265,"stem":266,"icon":267},"API Integration","\u002Fexamples\u002Fapi-integration","8.examples\u002F2.api-integration","i-lucide-globe",{"title":269,"path":270,"stem":271,"icon":272},"Common Patterns","\u002Fexamples\u002Fcommon-patterns","8.examples\u002F3.common-patterns","i-lucide-lightbulb",{"title":274,"path":275,"stem":276,"icon":277},"File Operations","\u002Fexamples\u002Ffile-operations","8.examples\u002F4.file-operations","i-lucide-file",{"title":279,"path":280,"stem":281,"icon":107},"Prompt Examples","\u002Fexamples\u002Fprompt-examples","8.examples\u002F5.prompt-examples",{"id":283,"title":284,"body":285,"description":3221,"extension":3222,"links":3223,"meta":3224,"navigation":3225,"path":260,"seo":3226,"stem":261,"__hash__":3229},"docs\u002F8.examples\u002F1.authentication.md","Authenticate MCP clients",{"type":286,"value":287,"toc":3202},"minimark",[288,292,296,312,360,386,390,405,410,413,603,608,612,615,887,891,894,1291,1295,1298,1434,1437,1461,1465,1472,1496,1947,2234,2243,2319,2323,2326,2711,2811,2815,2819,2825,2937,2941,2944,3039,3043,3046,3048,3051,3141,3145,3177,3181,3198],[289,290,46],"h2",{"id":291},"overview",[293,294,295],"p",{},"MCP endpoints can be secured using Bearer token authentication. This guide shows how to:",[297,298,299,303,306,309],"ol",{},[300,301,302],"li",{},"Generate and manage API keys for users",[300,304,305],{},"Validate tokens in MCP middleware",[300,307,308],{},"Access user context in your tools",[300,310,311],{},"Configure MCP clients with authentication",[313,314,317,320,346],"prompt",{":actions":315,"description":316,"icon":262},"[\"copy\",\"cursor\",\"windsurf\"]","Secure MCP endpoints with tokens",[293,318,319],{},"Add authentication to my Nuxt MCP endpoints (@nuxtjs\u002Fmcp-toolkit).",[297,321,322,325,328,331,334,337,340,343],{},[300,323,324],{},"Choose an auth strategy: Better Auth API keys or custom token validation",[300,326,327],{},"Create server\u002Fmcp\u002Findex.ts with defineMcpHandler and a middleware function",[300,329,330],{},"In the middleware, read the token from getHeader(event, 'authorization') or getHeader(event, 'x-api-key')",[300,332,333],{},"Validate the token and set event.context.user with the authenticated user",[300,335,336],{},"For this manually configured API-key recipe, use soft authentication and guard every protected operation; OAuth resource servers should return 401 with their metadata challenge",[300,338,339],{},"Access user context in tools via useEvent().context.user",[300,341,342],{},"Use the enabled guard on tools to hide them from unauthenticated users",[300,344,345],{},"Configure MCP clients to send the token in headers",[293,347,348,349,355,356],{},"Docs: ",[350,351,352],"a",{"href":352,"rel":353},"https:\u002F\u002Fmcp-toolkit.nuxt.dev\u002Fexamples\u002Fauthentication",[354],"nofollow","\nMiddleware: ",[350,357,358],{"href":358,"rel":359},"https:\u002F\u002Fmcp-toolkit.nuxt.dev\u002Fadvanced\u002Fmiddleware",[354],[361,362,365,369,370,374,375,377,378,381,382,385],"callout",{"color":363,"icon":364},"warning","i-lucide-triangle-alert",[366,367,368],"strong",{},"This recipe uses manually configured API keys, without OAuth discovery."," Its soft authentication sets context on success and leaves each protected operation responsible for refusing unauthenticated access. A ",[371,372,373],"code",{},"401"," can trigger OAuth discovery. For an OAuth resource server, that is intentional: return ",[371,376,373],{}," with ",[371,379,380],{},"WWW-Authenticate"," and publish the protected-resource metadata. Nitro’s ",[371,383,384],{},"createMcpOAuth"," implements that separate flow.",[289,387,389],{"id":388},"using-better-auth-api-keys","Using Better Auth API Keys",[293,391,392,393,398,399,404],{},"If you're using ",[350,394,397],{"href":395,"rel":396},"https:\u002F\u002Fwww.better-auth.com",[354],"Better Auth",", you can leverage the built-in ",[350,400,403],{"href":401,"rel":402},"https:\u002F\u002Fwww.better-auth.com\u002Fdocs\u002Fplugins\u002Fapi-key",[354],"API Key plugin"," for a complete solution.",[406,407,409],"h3",{"id":408},"server-configuration","Server Configuration",[293,411,412],{},"Add the API Key plugin to your Better Auth configuration:",[414,415,421],"pre",{"className":416,"code":417,"filename":418,"language":419,"meta":420,"style":420},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { betterAuth } from 'better-auth'\nimport { apiKey } from '@better-auth\u002Fapi-key'\n\nexport const auth = betterAuth({\n  \u002F\u002F ... your existing config\n  plugins: [\n    apiKey({\n      rateLimit: {\n        enabled: false, \u002F\u002F Disable rate limiting (if not needed)\n      },\n    }),\n  ],\n})\n","server\u002Futils\u002Fauth.ts","typescript","",[371,422,423,456,477,484,509,516,529,539,550,568,574,586,594],{"__ignoreMap":420},[424,425,428,432,436,440,443,446,449,453],"span",{"class":426,"line":427},"line",1,[424,429,431],{"class":430},"s7zQu","import",[424,433,435],{"class":434},"sMK4o"," {",[424,437,439],{"class":438},"sTEyZ"," betterAuth",[424,441,442],{"class":434}," }",[424,444,445],{"class":430}," from",[424,447,448],{"class":434}," '",[424,450,452],{"class":451},"sfazB","better-auth",[424,454,455],{"class":434},"'\n",[424,457,459,461,463,466,468,470,472,475],{"class":426,"line":458},2,[424,460,431],{"class":430},[424,462,435],{"class":434},[424,464,465],{"class":438}," apiKey",[424,467,442],{"class":434},[424,469,445],{"class":430},[424,471,448],{"class":434},[424,473,474],{"class":451},"@better-auth\u002Fapi-key",[424,476,455],{"class":434},[424,478,480],{"class":426,"line":479},3,[424,481,483],{"emptyLinePlaceholder":482},true,"\n",[424,485,487,490,494,497,500,503,506],{"class":426,"line":486},4,[424,488,489],{"class":430},"export",[424,491,493],{"class":492},"spNyl"," const",[424,495,496],{"class":438}," auth ",[424,498,499],{"class":434},"=",[424,501,439],{"class":502},"s2Zo4",[424,504,505],{"class":438},"(",[424,507,508],{"class":434},"{\n",[424,510,512],{"class":426,"line":511},5,[424,513,515],{"class":514},"sHwdD","  \u002F\u002F ... your existing config\n",[424,517,519,523,526],{"class":426,"line":518},6,[424,520,522],{"class":521},"swJcz","  plugins",[424,524,525],{"class":434},":",[424,527,528],{"class":438}," [\n",[424,530,532,535,537],{"class":426,"line":531},7,[424,533,534],{"class":502},"    apiKey",[424,536,505],{"class":438},[424,538,508],{"class":434},[424,540,542,545,547],{"class":426,"line":541},8,[424,543,544],{"class":521},"      rateLimit",[424,546,525],{"class":434},[424,548,549],{"class":434}," {\n",[424,551,553,556,558,562,565],{"class":426,"line":552},9,[424,554,555],{"class":521},"        enabled",[424,557,525],{"class":434},[424,559,561],{"class":560},"sfNiH"," false",[424,563,564],{"class":434},",",[424,566,567],{"class":514}," \u002F\u002F Disable rate limiting (if not needed)\n",[424,569,571],{"class":426,"line":570},10,[424,572,573],{"class":434},"      },\n",[424,575,577,580,583],{"class":426,"line":576},11,[424,578,579],{"class":434},"    }",[424,581,582],{"class":438},")",[424,584,585],{"class":434},",\n",[424,587,589,592],{"class":426,"line":588},12,[424,590,591],{"class":438},"  ]",[424,593,585],{"class":434},[424,595,597,600],{"class":426,"line":596},13,[424,598,599],{"class":434},"}",[424,601,602],{"class":438},")\n",[361,604,607],{"color":605,"icon":606},"info","i-lucide-info","The API Key plugin has rate limiting enabled by default. Disable it for development or configure appropriate limits for production.",[406,609,611],{"id":610},"client-configuration","Client Configuration",[293,613,614],{},"Add the client plugin to use API key methods:",[414,616,619],{"className":416,"code":617,"filename":618,"language":419,"meta":420,"style":420},"import { createAuthClient } from 'better-auth\u002Fclient'\nimport { apiKeyClient } from '@better-auth\u002Fapi-key\u002Fclient'\n\nconst client = createAuthClient({\n  plugins: [\n    apiKeyClient(),\n  ],\n})\n\n\u002F\u002F Create an API key\nconst { data } = await client.apiKey.create({ name: 'My MCP Key' })\nconsole.log(data.key) \u002F\u002F Save this - only shown once!\n\n\u002F\u002F List API keys\nconst { data: keys } = await client.apiKey.list()\n\n\u002F\u002F Delete an API key\nawait client.apiKey.delete({ keyId: 'key-id' })\n","composables\u002Fauth.ts",[371,620,621,641,661,665,681,689,699,705,711,715,720,773,794,798,804,839,844,850],{"__ignoreMap":420},[424,622,623,625,627,630,632,634,636,639],{"class":426,"line":427},[424,624,431],{"class":430},[424,626,435],{"class":434},[424,628,629],{"class":438}," createAuthClient",[424,631,442],{"class":434},[424,633,445],{"class":430},[424,635,448],{"class":434},[424,637,638],{"class":451},"better-auth\u002Fclient",[424,640,455],{"class":434},[424,642,643,645,647,650,652,654,656,659],{"class":426,"line":458},[424,644,431],{"class":430},[424,646,435],{"class":434},[424,648,649],{"class":438}," apiKeyClient",[424,651,442],{"class":434},[424,653,445],{"class":430},[424,655,448],{"class":434},[424,657,658],{"class":451},"@better-auth\u002Fapi-key\u002Fclient",[424,660,455],{"class":434},[424,662,663],{"class":426,"line":479},[424,664,483],{"emptyLinePlaceholder":482},[424,666,667,670,673,675,677,679],{"class":426,"line":486},[424,668,669],{"class":492},"const",[424,671,672],{"class":438}," client ",[424,674,499],{"class":434},[424,676,629],{"class":502},[424,678,505],{"class":438},[424,680,508],{"class":434},[424,682,683,685,687],{"class":426,"line":511},[424,684,522],{"class":521},[424,686,525],{"class":434},[424,688,528],{"class":438},[424,690,691,694,697],{"class":426,"line":518},[424,692,693],{"class":502},"    apiKeyClient",[424,695,696],{"class":438},"()",[424,698,585],{"class":434},[424,700,701,703],{"class":426,"line":531},[424,702,591],{"class":438},[424,704,585],{"class":434},[424,706,707,709],{"class":426,"line":541},[424,708,599],{"class":434},[424,710,602],{"class":438},[424,712,713],{"class":426,"line":552},[424,714,483],{"emptyLinePlaceholder":482},[424,716,717],{"class":426,"line":570},[424,718,719],{"class":514},"\u002F\u002F Create an API key\n",[424,721,722,724,726,729,731,734,737,740,743,746,748,751,753,756,759,761,763,766,769,771],{"class":426,"line":576},[424,723,669],{"class":492},[424,725,435],{"class":434},[424,727,728],{"class":438}," data ",[424,730,599],{"class":434},[424,732,733],{"class":434}," =",[424,735,736],{"class":430}," await",[424,738,739],{"class":438}," client",[424,741,742],{"class":434},".",[424,744,745],{"class":438},"apiKey",[424,747,742],{"class":434},[424,749,750],{"class":502},"create",[424,752,505],{"class":438},[424,754,755],{"class":434},"{",[424,757,758],{"class":521}," name",[424,760,525],{"class":434},[424,762,448],{"class":434},[424,764,765],{"class":451},"My MCP Key",[424,767,768],{"class":434},"'",[424,770,442],{"class":434},[424,772,602],{"class":438},[424,774,775,778,780,783,786,788,791],{"class":426,"line":588},[424,776,777],{"class":438},"console",[424,779,742],{"class":434},[424,781,782],{"class":502},"log",[424,784,785],{"class":438},"(data",[424,787,742],{"class":434},[424,789,790],{"class":438},"key) ",[424,792,793],{"class":514},"\u002F\u002F Save this - only shown once!\n",[424,795,796],{"class":426,"line":596},[424,797,483],{"emptyLinePlaceholder":482},[424,799,801],{"class":426,"line":800},14,[424,802,803],{"class":514},"\u002F\u002F List API keys\n",[424,805,807,809,811,814,816,819,821,823,825,827,829,831,833,836],{"class":426,"line":806},15,[424,808,669],{"class":492},[424,810,435],{"class":434},[424,812,813],{"class":521}," data",[424,815,525],{"class":434},[424,817,818],{"class":438}," keys ",[424,820,599],{"class":434},[424,822,733],{"class":434},[424,824,736],{"class":430},[424,826,739],{"class":438},[424,828,742],{"class":434},[424,830,745],{"class":438},[424,832,742],{"class":434},[424,834,835],{"class":502},"list",[424,837,838],{"class":438},"()\n",[424,840,842],{"class":426,"line":841},16,[424,843,483],{"emptyLinePlaceholder":482},[424,845,847],{"class":426,"line":846},17,[424,848,849],{"class":514},"\u002F\u002F Delete an API key\n",[424,851,853,856,858,860,862,864,867,869,871,874,876,878,881,883,885],{"class":426,"line":852},18,[424,854,855],{"class":430},"await",[424,857,739],{"class":438},[424,859,742],{"class":434},[424,861,745],{"class":438},[424,863,742],{"class":434},[424,865,866],{"class":502},"delete",[424,868,505],{"class":438},[424,870,755],{"class":434},[424,872,873],{"class":521}," keyId",[424,875,525],{"class":434},[424,877,448],{"class":434},[424,879,880],{"class":451},"key-id",[424,882,768],{"class":434},[424,884,442],{"class":434},[424,886,602],{"class":438},[406,888,890],{"id":889},"helper-function","Helper Function",[293,892,893],{},"Create a helper function that validates API keys without throwing errors:",[414,895,897],{"className":416,"code":896,"filename":418,"language":419,"meta":420,"style":420},"export async function getApiKeyUser(event: H3Event) {\n  const authHeader = getHeader(event, 'authorization')\n\n  if (!authHeader?.startsWith('Bearer ')) {\n    return null\n  }\n\n  const key = authHeader.slice(7)\n  const result = await auth.api.verifyApiKey({ body: { key } })\n\n  if (!result.valid || !result.key) {\n    return null\n  }\n\n  const user = await db.query.user.findFirst({\n    where: (users, { eq }) => eq(users.id, result.key!.referenceId),\n  })\n\n  if (!user) {\n    return null\n  }\n\n  return { user, apiKey: result.key }\n}\n",[371,898,899,928,956,960,994,1002,1007,1011,1035,1078,1082,1116,1122,1126,1130,1163,1217,1224,1228,1243,1250,1255,1260,1285],{"__ignoreMap":420},[424,900,901,903,906,909,912,914,918,920,924,926],{"class":426,"line":427},[424,902,489],{"class":430},[424,904,905],{"class":492}," async",[424,907,908],{"class":492}," function",[424,910,911],{"class":502}," getApiKeyUser",[424,913,505],{"class":434},[424,915,917],{"class":916},"sHdIc","event",[424,919,525],{"class":434},[424,921,923],{"class":922},"sBMFI"," H3Event",[424,925,582],{"class":434},[424,927,549],{"class":434},[424,929,930,933,936,938,941,943,945,947,949,952,954],{"class":426,"line":458},[424,931,932],{"class":492},"  const",[424,934,935],{"class":438}," authHeader",[424,937,733],{"class":434},[424,939,940],{"class":502}," getHeader",[424,942,505],{"class":521},[424,944,917],{"class":438},[424,946,564],{"class":434},[424,948,448],{"class":434},[424,950,951],{"class":451},"authorization",[424,953,768],{"class":434},[424,955,602],{"class":521},[424,957,958],{"class":426,"line":479},[424,959,483],{"emptyLinePlaceholder":482},[424,961,962,965,968,971,974,977,980,982,984,987,989,992],{"class":426,"line":486},[424,963,964],{"class":430},"  if",[424,966,967],{"class":521}," (",[424,969,970],{"class":434},"!",[424,972,973],{"class":438},"authHeader",[424,975,976],{"class":434},"?.",[424,978,979],{"class":502},"startsWith",[424,981,505],{"class":521},[424,983,768],{"class":434},[424,985,986],{"class":451},"Bearer ",[424,988,768],{"class":434},[424,990,991],{"class":521},")) ",[424,993,508],{"class":434},[424,995,996,999],{"class":426,"line":511},[424,997,998],{"class":430},"    return",[424,1000,1001],{"class":434}," null\n",[424,1003,1004],{"class":426,"line":518},[424,1005,1006],{"class":434},"  }\n",[424,1008,1009],{"class":426,"line":531},[424,1010,483],{"emptyLinePlaceholder":482},[424,1012,1013,1015,1018,1020,1022,1024,1027,1029,1033],{"class":426,"line":541},[424,1014,932],{"class":492},[424,1016,1017],{"class":438}," key",[424,1019,733],{"class":434},[424,1021,935],{"class":438},[424,1023,742],{"class":434},[424,1025,1026],{"class":502},"slice",[424,1028,505],{"class":521},[424,1030,1032],{"class":1031},"sbssI","7",[424,1034,602],{"class":521},[424,1036,1037,1039,1042,1044,1046,1049,1051,1054,1056,1059,1061,1063,1066,1068,1070,1072,1074,1076],{"class":426,"line":552},[424,1038,932],{"class":492},[424,1040,1041],{"class":438}," result",[424,1043,733],{"class":434},[424,1045,736],{"class":430},[424,1047,1048],{"class":438}," auth",[424,1050,742],{"class":434},[424,1052,1053],{"class":438},"api",[424,1055,742],{"class":434},[424,1057,1058],{"class":502},"verifyApiKey",[424,1060,505],{"class":521},[424,1062,755],{"class":434},[424,1064,1065],{"class":521}," body",[424,1067,525],{"class":434},[424,1069,435],{"class":434},[424,1071,1017],{"class":438},[424,1073,442],{"class":434},[424,1075,442],{"class":434},[424,1077,602],{"class":521},[424,1079,1080],{"class":426,"line":570},[424,1081,483],{"emptyLinePlaceholder":482},[424,1083,1084,1086,1088,1090,1093,1095,1098,1101,1104,1106,1108,1111,1114],{"class":426,"line":576},[424,1085,964],{"class":430},[424,1087,967],{"class":521},[424,1089,970],{"class":434},[424,1091,1092],{"class":438},"result",[424,1094,742],{"class":434},[424,1096,1097],{"class":438},"valid",[424,1099,1100],{"class":434}," ||",[424,1102,1103],{"class":434}," !",[424,1105,1092],{"class":438},[424,1107,742],{"class":434},[424,1109,1110],{"class":438},"key",[424,1112,1113],{"class":521},") ",[424,1115,508],{"class":434},[424,1117,1118,1120],{"class":426,"line":588},[424,1119,998],{"class":430},[424,1121,1001],{"class":434},[424,1123,1124],{"class":426,"line":596},[424,1125,1006],{"class":434},[424,1127,1128],{"class":426,"line":800},[424,1129,483],{"emptyLinePlaceholder":482},[424,1131,1132,1134,1137,1139,1141,1144,1146,1149,1151,1154,1156,1159,1161],{"class":426,"line":806},[424,1133,932],{"class":492},[424,1135,1136],{"class":438}," user",[424,1138,733],{"class":434},[424,1140,736],{"class":430},[424,1142,1143],{"class":438}," db",[424,1145,742],{"class":434},[424,1147,1148],{"class":438},"query",[424,1150,742],{"class":434},[424,1152,1153],{"class":438},"user",[424,1155,742],{"class":434},[424,1157,1158],{"class":502},"findFirst",[424,1160,505],{"class":521},[424,1162,508],{"class":434},[424,1164,1165,1168,1170,1172,1175,1177,1179,1182,1185,1188,1190,1192,1194,1196,1199,1201,1203,1205,1207,1210,1213,1215],{"class":426,"line":841},[424,1166,1167],{"class":502},"    where",[424,1169,525],{"class":434},[424,1171,967],{"class":434},[424,1173,1174],{"class":916},"users",[424,1176,564],{"class":434},[424,1178,435],{"class":434},[424,1180,1181],{"class":916}," eq",[424,1183,1184],{"class":434}," })",[424,1186,1187],{"class":492}," =>",[424,1189,1181],{"class":502},[424,1191,505],{"class":521},[424,1193,1174],{"class":438},[424,1195,742],{"class":434},[424,1197,1198],{"class":438},"id",[424,1200,564],{"class":434},[424,1202,1041],{"class":438},[424,1204,742],{"class":434},[424,1206,1110],{"class":438},[424,1208,1209],{"class":434},"!.",[424,1211,1212],{"class":438},"referenceId",[424,1214,582],{"class":521},[424,1216,585],{"class":434},[424,1218,1219,1222],{"class":426,"line":846},[424,1220,1221],{"class":434},"  }",[424,1223,602],{"class":521},[424,1225,1226],{"class":426,"line":852},[424,1227,483],{"emptyLinePlaceholder":482},[424,1229,1231,1233,1235,1237,1239,1241],{"class":426,"line":1230},19,[424,1232,964],{"class":430},[424,1234,967],{"class":521},[424,1236,970],{"class":434},[424,1238,1153],{"class":438},[424,1240,1113],{"class":521},[424,1242,508],{"class":434},[424,1244,1246,1248],{"class":426,"line":1245},20,[424,1247,998],{"class":430},[424,1249,1001],{"class":434},[424,1251,1253],{"class":426,"line":1252},21,[424,1254,1006],{"class":434},[424,1256,1258],{"class":426,"line":1257},22,[424,1259,483],{"emptyLinePlaceholder":482},[424,1261,1263,1266,1268,1270,1272,1274,1276,1278,1280,1282],{"class":426,"line":1262},23,[424,1264,1265],{"class":430},"  return",[424,1267,435],{"class":434},[424,1269,1136],{"class":438},[424,1271,564],{"class":434},[424,1273,465],{"class":521},[424,1275,525],{"class":434},[424,1277,1041],{"class":438},[424,1279,742],{"class":434},[424,1281,1110],{"class":438},[424,1283,1284],{"class":434}," }\n",[424,1286,1288],{"class":426,"line":1287},24,[424,1289,1290],{"class":434},"}\n",[406,1292,1294],{"id":1293},"mcp-handler-with-authentication","MCP Handler with Authentication",[293,1296,1297],{},"Create a handler that sets user context when a valid API key is provided:",[414,1299,1302],{"className":416,"code":1300,"filename":1301,"language":419,"meta":420,"style":420},"export default defineMcpHandler({\n  middleware: async (event) => {\n    const result = await getApiKeyUser(event)\n    if (result) {\n      event.context.user = result.user\n      event.context.userId = result.user.id\n    }\n  },\n})\n","server\u002Fmcp\u002Findex.ts",[371,1303,1304,1318,1337,1356,1369,1392,1418,1423,1428],{"__ignoreMap":420},[424,1305,1306,1308,1311,1314,1316],{"class":426,"line":427},[424,1307,489],{"class":430},[424,1309,1310],{"class":430}," default",[424,1312,1313],{"class":502}," defineMcpHandler",[424,1315,505],{"class":438},[424,1317,508],{"class":434},[424,1319,1320,1323,1325,1327,1329,1331,1333,1335],{"class":426,"line":458},[424,1321,1322],{"class":502},"  middleware",[424,1324,525],{"class":434},[424,1326,905],{"class":492},[424,1328,967],{"class":434},[424,1330,917],{"class":916},[424,1332,582],{"class":434},[424,1334,1187],{"class":492},[424,1336,549],{"class":434},[424,1338,1339,1342,1344,1346,1348,1350,1352,1354],{"class":426,"line":479},[424,1340,1341],{"class":492},"    const",[424,1343,1041],{"class":438},[424,1345,733],{"class":434},[424,1347,736],{"class":430},[424,1349,911],{"class":502},[424,1351,505],{"class":521},[424,1353,917],{"class":438},[424,1355,602],{"class":521},[424,1357,1358,1361,1363,1365,1367],{"class":426,"line":486},[424,1359,1360],{"class":430},"    if",[424,1362,967],{"class":521},[424,1364,1092],{"class":438},[424,1366,1113],{"class":521},[424,1368,508],{"class":434},[424,1370,1371,1374,1376,1379,1381,1383,1385,1387,1389],{"class":426,"line":511},[424,1372,1373],{"class":438},"      event",[424,1375,742],{"class":434},[424,1377,1378],{"class":438},"context",[424,1380,742],{"class":434},[424,1382,1153],{"class":438},[424,1384,733],{"class":434},[424,1386,1041],{"class":438},[424,1388,742],{"class":434},[424,1390,1391],{"class":438},"user\n",[424,1393,1394,1396,1398,1400,1402,1405,1407,1409,1411,1413,1415],{"class":426,"line":518},[424,1395,1373],{"class":438},[424,1397,742],{"class":434},[424,1399,1378],{"class":438},[424,1401,742],{"class":434},[424,1403,1404],{"class":438},"userId",[424,1406,733],{"class":434},[424,1408,1041],{"class":438},[424,1410,742],{"class":434},[424,1412,1153],{"class":438},[424,1414,742],{"class":434},[424,1416,1417],{"class":438},"id\n",[424,1419,1420],{"class":426,"line":531},[424,1421,1422],{"class":434},"    }\n",[424,1424,1425],{"class":426,"line":541},[424,1426,1427],{"class":434},"  },\n",[424,1429,1430,1432],{"class":426,"line":552},[424,1431,599],{"class":434},[424,1433,602],{"class":438},[293,1435,1436],{},"This approach:",[1438,1439,1440,1451,1458],"ul",{},[300,1441,1442,1443,1446,1447,1450],{},"Sets ",[371,1444,1445],{},"event.context.user"," and ",[371,1448,1449],{},"event.context.userId"," when authentication succeeds",[300,1452,1453,1454,1457],{},"Leaves context as ",[371,1455,1456],{},"undefined"," when no valid token is provided",[300,1459,1460],{},"Tools must check for user context and return an error if not authenticated",[406,1462,1464],{"id":1463},"using-context-in-tools","Using Context in Tools",[293,1466,1467,1468,1471],{},"Your tools can access the authenticated user from ",[371,1469,1470],{},"event.context",". Two patterns work well:",[297,1473,1474,1487],{},[300,1475,1476,1482,1483,1486],{},[366,1477,1478,1479],{},"Hide the tool with ",[371,1480,1481],{},"enabled"," — auth-required tools never appear in ",[371,1484,1485],{},"tools\u002Flist"," for anonymous callers (recommended).",[300,1488,1489,1492,1493,1495],{},[366,1490,1491],{},"Return a user-friendly message"," — the tool stays visible, but explains how to authenticate when called without a user. Avoid throwing ",[371,1494,373],{}," from a tool handler so MCP clients don't enter OAuth discovery.",[414,1497,1500],{"className":416,"code":1498,"filename":1499,"language":419,"meta":420,"style":420},"import { z } from 'zod'\nimport { useEvent } from 'h3'\nimport { defineMcpTool } from '@nuxtjs\u002Fmcp-toolkit\u002Fserver'\n\nexport default defineMcpTool({\n  name: 'create_todo',\n  description: 'Create a new todo for the authenticated user',\n  enabled: event => !!event.context.userId,\n  inputSchema: {\n    title: z.string().describe('The title of the todo'),\n    content: z.string().optional().describe('Optional description or content'),\n  },\n  handler: async ({ title, content }) => {\n    const event = useEvent()\n    const userId = event.context.userId as string\n\n    const [todo] = await db.insert(schema.todos).values({\n      title,\n      content: content || null,\n      userId,\n      createdAt: new Date(),\n      updatedAt: new Date(),\n    }).returning()\n\n    return `Todo created: ${todo.title}`\n  },\n})\n","server\u002Fmcp\u002Ftools\u002Fcreate-todo.ts",[371,1501,1502,1522,1541,1561,1565,1577,1593,1609,1636,1645,1679,1718,1722,1748,1760,1785,1789,1834,1841,1855,1862,1879,1894,1907,1911,1935,1940],{"__ignoreMap":420},[424,1503,1504,1506,1508,1511,1513,1515,1517,1520],{"class":426,"line":427},[424,1505,431],{"class":430},[424,1507,435],{"class":434},[424,1509,1510],{"class":438}," z",[424,1512,442],{"class":434},[424,1514,445],{"class":430},[424,1516,448],{"class":434},[424,1518,1519],{"class":451},"zod",[424,1521,455],{"class":434},[424,1523,1524,1526,1528,1531,1533,1535,1537,1539],{"class":426,"line":458},[424,1525,431],{"class":430},[424,1527,435],{"class":434},[424,1529,1530],{"class":438}," useEvent",[424,1532,442],{"class":434},[424,1534,445],{"class":430},[424,1536,448],{"class":434},[424,1538,406],{"class":451},[424,1540,455],{"class":434},[424,1542,1543,1545,1547,1550,1552,1554,1556,1559],{"class":426,"line":479},[424,1544,431],{"class":430},[424,1546,435],{"class":434},[424,1548,1549],{"class":438}," defineMcpTool",[424,1551,442],{"class":434},[424,1553,445],{"class":430},[424,1555,448],{"class":434},[424,1557,1558],{"class":451},"@nuxtjs\u002Fmcp-toolkit\u002Fserver",[424,1560,455],{"class":434},[424,1562,1563],{"class":426,"line":486},[424,1564,483],{"emptyLinePlaceholder":482},[424,1566,1567,1569,1571,1573,1575],{"class":426,"line":511},[424,1568,489],{"class":430},[424,1570,1310],{"class":430},[424,1572,1549],{"class":502},[424,1574,505],{"class":438},[424,1576,508],{"class":434},[424,1578,1579,1582,1584,1586,1589,1591],{"class":426,"line":518},[424,1580,1581],{"class":521},"  name",[424,1583,525],{"class":434},[424,1585,448],{"class":434},[424,1587,1588],{"class":451},"create_todo",[424,1590,768],{"class":434},[424,1592,585],{"class":434},[424,1594,1595,1598,1600,1602,1605,1607],{"class":426,"line":531},[424,1596,1597],{"class":521},"  description",[424,1599,525],{"class":434},[424,1601,448],{"class":434},[424,1603,1604],{"class":451},"Create a new todo for the authenticated user",[424,1606,768],{"class":434},[424,1608,585],{"class":434},[424,1610,1611,1614,1616,1619,1621,1624,1626,1628,1630,1632,1634],{"class":426,"line":541},[424,1612,1613],{"class":502},"  enabled",[424,1615,525],{"class":434},[424,1617,1618],{"class":916}," event",[424,1620,1187],{"class":492},[424,1622,1623],{"class":434}," !!",[424,1625,917],{"class":438},[424,1627,742],{"class":434},[424,1629,1378],{"class":438},[424,1631,742],{"class":434},[424,1633,1404],{"class":438},[424,1635,585],{"class":434},[424,1637,1638,1641,1643],{"class":426,"line":552},[424,1639,1640],{"class":521},"  inputSchema",[424,1642,525],{"class":434},[424,1644,549],{"class":434},[424,1646,1647,1650,1652,1654,1656,1659,1661,1663,1666,1668,1670,1673,1675,1677],{"class":426,"line":570},[424,1648,1649],{"class":521},"    title",[424,1651,525],{"class":434},[424,1653,1510],{"class":438},[424,1655,742],{"class":434},[424,1657,1658],{"class":502},"string",[424,1660,696],{"class":438},[424,1662,742],{"class":434},[424,1664,1665],{"class":502},"describe",[424,1667,505],{"class":438},[424,1669,768],{"class":434},[424,1671,1672],{"class":451},"The title of the todo",[424,1674,768],{"class":434},[424,1676,582],{"class":438},[424,1678,585],{"class":434},[424,1680,1681,1684,1686,1688,1690,1692,1694,1696,1699,1701,1703,1705,1707,1709,1712,1714,1716],{"class":426,"line":576},[424,1682,1683],{"class":521},"    content",[424,1685,525],{"class":434},[424,1687,1510],{"class":438},[424,1689,742],{"class":434},[424,1691,1658],{"class":502},[424,1693,696],{"class":438},[424,1695,742],{"class":434},[424,1697,1698],{"class":502},"optional",[424,1700,696],{"class":438},[424,1702,742],{"class":434},[424,1704,1665],{"class":502},[424,1706,505],{"class":438},[424,1708,768],{"class":434},[424,1710,1711],{"class":451},"Optional description or content",[424,1713,768],{"class":434},[424,1715,582],{"class":438},[424,1717,585],{"class":434},[424,1719,1720],{"class":426,"line":588},[424,1721,1427],{"class":434},[424,1723,1724,1727,1729,1731,1734,1737,1739,1742,1744,1746],{"class":426,"line":596},[424,1725,1726],{"class":502},"  handler",[424,1728,525],{"class":434},[424,1730,905],{"class":492},[424,1732,1733],{"class":434}," ({",[424,1735,1736],{"class":916}," title",[424,1738,564],{"class":434},[424,1740,1741],{"class":916}," content",[424,1743,1184],{"class":434},[424,1745,1187],{"class":492},[424,1747,549],{"class":434},[424,1749,1750,1752,1754,1756,1758],{"class":426,"line":800},[424,1751,1341],{"class":492},[424,1753,1618],{"class":438},[424,1755,733],{"class":434},[424,1757,1530],{"class":502},[424,1759,838],{"class":521},[424,1761,1762,1764,1767,1769,1771,1773,1775,1777,1779,1782],{"class":426,"line":806},[424,1763,1341],{"class":492},[424,1765,1766],{"class":438}," userId",[424,1768,733],{"class":434},[424,1770,1618],{"class":438},[424,1772,742],{"class":434},[424,1774,1378],{"class":438},[424,1776,742],{"class":434},[424,1778,1404],{"class":438},[424,1780,1781],{"class":430}," as",[424,1783,1784],{"class":922}," string\n",[424,1786,1787],{"class":426,"line":841},[424,1788,483],{"emptyLinePlaceholder":482},[424,1790,1791,1793,1796,1799,1802,1804,1806,1808,1810,1813,1815,1818,1820,1823,1825,1827,1830,1832],{"class":426,"line":846},[424,1792,1341],{"class":492},[424,1794,1795],{"class":434}," [",[424,1797,1798],{"class":438},"todo",[424,1800,1801],{"class":434},"]",[424,1803,733],{"class":434},[424,1805,736],{"class":430},[424,1807,1143],{"class":438},[424,1809,742],{"class":434},[424,1811,1812],{"class":502},"insert",[424,1814,505],{"class":521},[424,1816,1817],{"class":438},"schema",[424,1819,742],{"class":434},[424,1821,1822],{"class":438},"todos",[424,1824,582],{"class":521},[424,1826,742],{"class":434},[424,1828,1829],{"class":502},"values",[424,1831,505],{"class":521},[424,1833,508],{"class":434},[424,1835,1836,1839],{"class":426,"line":852},[424,1837,1838],{"class":438},"      title",[424,1840,585],{"class":434},[424,1842,1843,1846,1848,1850,1852],{"class":426,"line":1230},[424,1844,1845],{"class":521},"      content",[424,1847,525],{"class":434},[424,1849,1741],{"class":438},[424,1851,1100],{"class":434},[424,1853,1854],{"class":434}," null,\n",[424,1856,1857,1860],{"class":426,"line":1245},[424,1858,1859],{"class":438},"      userId",[424,1861,585],{"class":434},[424,1863,1864,1867,1869,1872,1875,1877],{"class":426,"line":1252},[424,1865,1866],{"class":521},"      createdAt",[424,1868,525],{"class":434},[424,1870,1871],{"class":434}," new",[424,1873,1874],{"class":502}," Date",[424,1876,696],{"class":521},[424,1878,585],{"class":434},[424,1880,1881,1884,1886,1888,1890,1892],{"class":426,"line":1257},[424,1882,1883],{"class":521},"      updatedAt",[424,1885,525],{"class":434},[424,1887,1871],{"class":434},[424,1889,1874],{"class":502},[424,1891,696],{"class":521},[424,1893,585],{"class":434},[424,1895,1896,1898,1900,1902,1905],{"class":426,"line":1262},[424,1897,579],{"class":434},[424,1899,582],{"class":521},[424,1901,742],{"class":434},[424,1903,1904],{"class":502},"returning",[424,1906,838],{"class":521},[424,1908,1909],{"class":426,"line":1287},[424,1910,483],{"emptyLinePlaceholder":482},[424,1912,1914,1916,1919,1922,1925,1927,1929,1932],{"class":426,"line":1913},25,[424,1915,998],{"class":430},[424,1917,1918],{"class":434}," `",[424,1920,1921],{"class":451},"Todo created: ",[424,1923,1924],{"class":434},"${",[424,1926,1798],{"class":438},[424,1928,742],{"class":434},[424,1930,1931],{"class":438},"title",[424,1933,1934],{"class":434},"}`\n",[424,1936,1938],{"class":426,"line":1937},26,[424,1939,1427],{"class":434},[424,1941,1943,1945],{"class":426,"line":1942},27,[424,1944,599],{"class":434},[424,1946,602],{"class":438},[414,1948,1951],{"className":416,"code":1949,"filename":1950,"language":419,"meta":420,"style":420},"import { useEvent } from 'h3'\nimport { defineMcpTool } from '@nuxtjs\u002Fmcp-toolkit\u002Fserver'\n\nexport default defineMcpTool({\n  name: 'list_todos',\n  description: 'List all todos for the authenticated user',\n  inputSchema: {},\n  handler: async () => {\n    const event = useEvent()\n    const userId = event.context.userId as string | undefined\n\n    if (!userId) {\n      return 'Authentication required. Configure your MCP client with an API key (Authorization: Bearer …) and try again.'\n    }\n\n    const todos = await db.query.todos.findMany({\n      where: (todos, { eq }) => eq(todos.userId, userId),\n    })\n\n    return todos\n  },\n})\n","server\u002Fmcp\u002Ftools\u002Flist-todos.ts",[371,1952,1953,1971,1989,1993,2005,2020,2035,2044,2059,2071,2100,2104,2118,2130,2134,2138,2168,2207,2213,2217,2224,2228],{"__ignoreMap":420},[424,1954,1955,1957,1959,1961,1963,1965,1967,1969],{"class":426,"line":427},[424,1956,431],{"class":430},[424,1958,435],{"class":434},[424,1960,1530],{"class":438},[424,1962,442],{"class":434},[424,1964,445],{"class":430},[424,1966,448],{"class":434},[424,1968,406],{"class":451},[424,1970,455],{"class":434},[424,1972,1973,1975,1977,1979,1981,1983,1985,1987],{"class":426,"line":458},[424,1974,431],{"class":430},[424,1976,435],{"class":434},[424,1978,1549],{"class":438},[424,1980,442],{"class":434},[424,1982,445],{"class":430},[424,1984,448],{"class":434},[424,1986,1558],{"class":451},[424,1988,455],{"class":434},[424,1990,1991],{"class":426,"line":479},[424,1992,483],{"emptyLinePlaceholder":482},[424,1994,1995,1997,1999,2001,2003],{"class":426,"line":486},[424,1996,489],{"class":430},[424,1998,1310],{"class":430},[424,2000,1549],{"class":502},[424,2002,505],{"class":438},[424,2004,508],{"class":434},[424,2006,2007,2009,2011,2013,2016,2018],{"class":426,"line":511},[424,2008,1581],{"class":521},[424,2010,525],{"class":434},[424,2012,448],{"class":434},[424,2014,2015],{"class":451},"list_todos",[424,2017,768],{"class":434},[424,2019,585],{"class":434},[424,2021,2022,2024,2026,2028,2031,2033],{"class":426,"line":518},[424,2023,1597],{"class":521},[424,2025,525],{"class":434},[424,2027,448],{"class":434},[424,2029,2030],{"class":451},"List all todos for the authenticated user",[424,2032,768],{"class":434},[424,2034,585],{"class":434},[424,2036,2037,2039,2041],{"class":426,"line":531},[424,2038,1640],{"class":521},[424,2040,525],{"class":434},[424,2042,2043],{"class":434}," {},\n",[424,2045,2046,2048,2050,2052,2055,2057],{"class":426,"line":541},[424,2047,1726],{"class":502},[424,2049,525],{"class":434},[424,2051,905],{"class":492},[424,2053,2054],{"class":434}," ()",[424,2056,1187],{"class":492},[424,2058,549],{"class":434},[424,2060,2061,2063,2065,2067,2069],{"class":426,"line":552},[424,2062,1341],{"class":492},[424,2064,1618],{"class":438},[424,2066,733],{"class":434},[424,2068,1530],{"class":502},[424,2070,838],{"class":521},[424,2072,2073,2075,2077,2079,2081,2083,2085,2087,2089,2091,2094,2097],{"class":426,"line":570},[424,2074,1341],{"class":492},[424,2076,1766],{"class":438},[424,2078,733],{"class":434},[424,2080,1618],{"class":438},[424,2082,742],{"class":434},[424,2084,1378],{"class":438},[424,2086,742],{"class":434},[424,2088,1404],{"class":438},[424,2090,1781],{"class":430},[424,2092,2093],{"class":922}," string",[424,2095,2096],{"class":434}," |",[424,2098,2099],{"class":922}," undefined\n",[424,2101,2102],{"class":426,"line":576},[424,2103,483],{"emptyLinePlaceholder":482},[424,2105,2106,2108,2110,2112,2114,2116],{"class":426,"line":588},[424,2107,1360],{"class":430},[424,2109,967],{"class":521},[424,2111,970],{"class":434},[424,2113,1404],{"class":438},[424,2115,1113],{"class":521},[424,2117,508],{"class":434},[424,2119,2120,2123,2125,2128],{"class":426,"line":596},[424,2121,2122],{"class":430},"      return",[424,2124,448],{"class":434},[424,2126,2127],{"class":451},"Authentication required. Configure your MCP client with an API key (Authorization: Bearer …) and try again.",[424,2129,455],{"class":434},[424,2131,2132],{"class":426,"line":800},[424,2133,1422],{"class":434},[424,2135,2136],{"class":426,"line":806},[424,2137,483],{"emptyLinePlaceholder":482},[424,2139,2140,2142,2145,2147,2149,2151,2153,2155,2157,2159,2161,2164,2166],{"class":426,"line":841},[424,2141,1341],{"class":492},[424,2143,2144],{"class":438}," todos",[424,2146,733],{"class":434},[424,2148,736],{"class":430},[424,2150,1143],{"class":438},[424,2152,742],{"class":434},[424,2154,1148],{"class":438},[424,2156,742],{"class":434},[424,2158,1822],{"class":438},[424,2160,742],{"class":434},[424,2162,2163],{"class":502},"findMany",[424,2165,505],{"class":521},[424,2167,508],{"class":434},[424,2169,2170,2173,2175,2177,2179,2181,2183,2185,2187,2189,2191,2193,2195,2197,2199,2201,2203,2205],{"class":426,"line":846},[424,2171,2172],{"class":502},"      where",[424,2174,525],{"class":434},[424,2176,967],{"class":434},[424,2178,1822],{"class":916},[424,2180,564],{"class":434},[424,2182,435],{"class":434},[424,2184,1181],{"class":916},[424,2186,1184],{"class":434},[424,2188,1187],{"class":492},[424,2190,1181],{"class":502},[424,2192,505],{"class":521},[424,2194,1822],{"class":438},[424,2196,742],{"class":434},[424,2198,1404],{"class":438},[424,2200,564],{"class":434},[424,2202,1766],{"class":438},[424,2204,582],{"class":521},[424,2206,585],{"class":434},[424,2208,2209,2211],{"class":426,"line":852},[424,2210,579],{"class":434},[424,2212,602],{"class":521},[424,2214,2215],{"class":426,"line":1230},[424,2216,483],{"emptyLinePlaceholder":482},[424,2218,2219,2221],{"class":426,"line":1245},[424,2220,998],{"class":430},[424,2222,2223],{"class":438}," todos\n",[424,2225,2226],{"class":426,"line":1252},[424,2227,1427],{"class":434},[424,2229,2230,2232],{"class":426,"line":1257},[424,2231,599],{"class":434},[424,2233,602],{"class":438},[361,2235,2236,2237,2239,2240,2242],{"color":605,"icon":606},"The ",[371,2238,1481],{}," guard runs after middleware, so it sees the user context set above. See ",[350,2241,239],{"href":240}," for more patterns.",[361,2244,2245,2255],{"color":605,"icon":606},[293,2246,2247,2248,2251,2252,525],{},"Remember to enable ",[371,2249,2250],{},"asyncContext"," in your Nuxt config to use ",[371,2253,2254],{},"useEvent()",[414,2256,2259],{"className":416,"code":2257,"filename":2258,"language":419,"meta":420,"style":420},"export default defineNuxtConfig({\n  nitro: {\n    experimental: {\n      asyncContext: true,\n    },\n  },\n})\n","nuxt.config.ts",[371,2260,2261,2274,2283,2292,2304,2309,2313],{"__ignoreMap":420},[424,2262,2263,2265,2267,2270,2272],{"class":426,"line":427},[424,2264,489],{"class":430},[424,2266,1310],{"class":430},[424,2268,2269],{"class":502}," defineNuxtConfig",[424,2271,505],{"class":438},[424,2273,508],{"class":434},[424,2275,2276,2279,2281],{"class":426,"line":458},[424,2277,2278],{"class":521},"  nitro",[424,2280,525],{"class":434},[424,2282,549],{"class":434},[424,2284,2285,2288,2290],{"class":426,"line":479},[424,2286,2287],{"class":521},"    experimental",[424,2289,525],{"class":434},[424,2291,549],{"class":434},[424,2293,2294,2297,2299,2302],{"class":426,"line":486},[424,2295,2296],{"class":521},"      asyncContext",[424,2298,525],{"class":434},[424,2300,2301],{"class":560}," true",[424,2303,585],{"class":434},[424,2305,2306],{"class":426,"line":511},[424,2307,2308],{"class":434},"    },\n",[424,2310,2311],{"class":426,"line":518},[424,2312,1427],{"class":434},[424,2314,2315,2317],{"class":426,"line":531},[424,2316,599],{"class":434},[424,2318,602],{"class":438},[289,2320,2322],{"id":2321},"custom-token-validation","Custom Token Validation",[293,2324,2325],{},"If you're not using Better Auth, you can implement your own token validation. For this API-key recipe, set user context on success and keep authorization guards on every protected operation:",[414,2327,2329],{"className":416,"code":2328,"filename":418,"language":419,"meta":420,"style":420},"import { createHash } from 'node:crypto'\n\nexport async function getTokenUser(event: H3Event) {\n  const authHeader = getHeader(event, 'authorization')\n\n  if (!authHeader?.startsWith('Bearer ')) {\n    return null\n  }\n\n  const token = authHeader.slice(7)\n  const tokenHash = createHash('sha256').update(token).digest('hex')\n\n  \u002F\u002F Look up the token in your database\n  const apiToken = await db.query.apiTokens.findFirst({\n    where: (tokens, { eq }) => eq(tokens.hash, tokenHash),\n  })\n\n  if (!apiToken) {\n    return null\n  }\n\n  \u002F\u002F Check expiration\n  if (apiToken.expiresAt && apiToken.expiresAt \u003C new Date()) {\n    return null\n  }\n\n  return { userId: apiToken.userId }\n}\n",[371,2330,2331,2351,2355,2378,2402,2406,2432,2438,2442,2446,2467,2517,2521,2526,2556,2596,2602,2606,2621,2627,2631,2635,2640,2674,2680,2684,2688,2706],{"__ignoreMap":420},[424,2332,2333,2335,2337,2340,2342,2344,2346,2349],{"class":426,"line":427},[424,2334,431],{"class":430},[424,2336,435],{"class":434},[424,2338,2339],{"class":438}," createHash",[424,2341,442],{"class":434},[424,2343,445],{"class":430},[424,2345,448],{"class":434},[424,2347,2348],{"class":451},"node:crypto",[424,2350,455],{"class":434},[424,2352,2353],{"class":426,"line":458},[424,2354,483],{"emptyLinePlaceholder":482},[424,2356,2357,2359,2361,2363,2366,2368,2370,2372,2374,2376],{"class":426,"line":479},[424,2358,489],{"class":430},[424,2360,905],{"class":492},[424,2362,908],{"class":492},[424,2364,2365],{"class":502}," getTokenUser",[424,2367,505],{"class":434},[424,2369,917],{"class":916},[424,2371,525],{"class":434},[424,2373,923],{"class":922},[424,2375,582],{"class":434},[424,2377,549],{"class":434},[424,2379,2380,2382,2384,2386,2388,2390,2392,2394,2396,2398,2400],{"class":426,"line":486},[424,2381,932],{"class":492},[424,2383,935],{"class":438},[424,2385,733],{"class":434},[424,2387,940],{"class":502},[424,2389,505],{"class":521},[424,2391,917],{"class":438},[424,2393,564],{"class":434},[424,2395,448],{"class":434},[424,2397,951],{"class":451},[424,2399,768],{"class":434},[424,2401,602],{"class":521},[424,2403,2404],{"class":426,"line":511},[424,2405,483],{"emptyLinePlaceholder":482},[424,2407,2408,2410,2412,2414,2416,2418,2420,2422,2424,2426,2428,2430],{"class":426,"line":518},[424,2409,964],{"class":430},[424,2411,967],{"class":521},[424,2413,970],{"class":434},[424,2415,973],{"class":438},[424,2417,976],{"class":434},[424,2419,979],{"class":502},[424,2421,505],{"class":521},[424,2423,768],{"class":434},[424,2425,986],{"class":451},[424,2427,768],{"class":434},[424,2429,991],{"class":521},[424,2431,508],{"class":434},[424,2433,2434,2436],{"class":426,"line":531},[424,2435,998],{"class":430},[424,2437,1001],{"class":434},[424,2439,2440],{"class":426,"line":541},[424,2441,1006],{"class":434},[424,2443,2444],{"class":426,"line":552},[424,2445,483],{"emptyLinePlaceholder":482},[424,2447,2448,2450,2453,2455,2457,2459,2461,2463,2465],{"class":426,"line":570},[424,2449,932],{"class":492},[424,2451,2452],{"class":438}," token",[424,2454,733],{"class":434},[424,2456,935],{"class":438},[424,2458,742],{"class":434},[424,2460,1026],{"class":502},[424,2462,505],{"class":521},[424,2464,1032],{"class":1031},[424,2466,602],{"class":521},[424,2468,2469,2471,2474,2476,2478,2480,2482,2485,2487,2489,2491,2494,2496,2499,2501,2503,2506,2508,2510,2513,2515],{"class":426,"line":576},[424,2470,932],{"class":492},[424,2472,2473],{"class":438}," tokenHash",[424,2475,733],{"class":434},[424,2477,2339],{"class":502},[424,2479,505],{"class":521},[424,2481,768],{"class":434},[424,2483,2484],{"class":451},"sha256",[424,2486,768],{"class":434},[424,2488,582],{"class":521},[424,2490,742],{"class":434},[424,2492,2493],{"class":502},"update",[424,2495,505],{"class":521},[424,2497,2498],{"class":438},"token",[424,2500,582],{"class":521},[424,2502,742],{"class":434},[424,2504,2505],{"class":502},"digest",[424,2507,505],{"class":521},[424,2509,768],{"class":434},[424,2511,2512],{"class":451},"hex",[424,2514,768],{"class":434},[424,2516,602],{"class":521},[424,2518,2519],{"class":426,"line":588},[424,2520,483],{"emptyLinePlaceholder":482},[424,2522,2523],{"class":426,"line":596},[424,2524,2525],{"class":514},"  \u002F\u002F Look up the token in your database\n",[424,2527,2528,2530,2533,2535,2537,2539,2541,2543,2545,2548,2550,2552,2554],{"class":426,"line":800},[424,2529,932],{"class":492},[424,2531,2532],{"class":438}," apiToken",[424,2534,733],{"class":434},[424,2536,736],{"class":430},[424,2538,1143],{"class":438},[424,2540,742],{"class":434},[424,2542,1148],{"class":438},[424,2544,742],{"class":434},[424,2546,2547],{"class":438},"apiTokens",[424,2549,742],{"class":434},[424,2551,1158],{"class":502},[424,2553,505],{"class":521},[424,2555,508],{"class":434},[424,2557,2558,2560,2562,2564,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2588,2590,2592,2594],{"class":426,"line":806},[424,2559,1167],{"class":502},[424,2561,525],{"class":434},[424,2563,967],{"class":434},[424,2565,2566],{"class":916},"tokens",[424,2568,564],{"class":434},[424,2570,435],{"class":434},[424,2572,1181],{"class":916},[424,2574,1184],{"class":434},[424,2576,1187],{"class":492},[424,2578,1181],{"class":502},[424,2580,505],{"class":521},[424,2582,2566],{"class":438},[424,2584,742],{"class":434},[424,2586,2587],{"class":438},"hash",[424,2589,564],{"class":434},[424,2591,2473],{"class":438},[424,2593,582],{"class":521},[424,2595,585],{"class":434},[424,2597,2598,2600],{"class":426,"line":841},[424,2599,1221],{"class":434},[424,2601,602],{"class":521},[424,2603,2604],{"class":426,"line":846},[424,2605,483],{"emptyLinePlaceholder":482},[424,2607,2608,2610,2612,2614,2617,2619],{"class":426,"line":852},[424,2609,964],{"class":430},[424,2611,967],{"class":521},[424,2613,970],{"class":434},[424,2615,2616],{"class":438},"apiToken",[424,2618,1113],{"class":521},[424,2620,508],{"class":434},[424,2622,2623,2625],{"class":426,"line":1230},[424,2624,998],{"class":430},[424,2626,1001],{"class":434},[424,2628,2629],{"class":426,"line":1245},[424,2630,1006],{"class":434},[424,2632,2633],{"class":426,"line":1252},[424,2634,483],{"emptyLinePlaceholder":482},[424,2636,2637],{"class":426,"line":1257},[424,2638,2639],{"class":514},"  \u002F\u002F Check expiration\n",[424,2641,2642,2644,2646,2648,2650,2653,2656,2658,2660,2662,2665,2667,2669,2672],{"class":426,"line":1262},[424,2643,964],{"class":430},[424,2645,967],{"class":521},[424,2647,2616],{"class":438},[424,2649,742],{"class":434},[424,2651,2652],{"class":438},"expiresAt",[424,2654,2655],{"class":434}," &&",[424,2657,2532],{"class":438},[424,2659,742],{"class":434},[424,2661,2652],{"class":438},[424,2663,2664],{"class":434}," \u003C",[424,2666,1871],{"class":434},[424,2668,1874],{"class":502},[424,2670,2671],{"class":521},"()) ",[424,2673,508],{"class":434},[424,2675,2676,2678],{"class":426,"line":1287},[424,2677,998],{"class":430},[424,2679,1001],{"class":434},[424,2681,2682],{"class":426,"line":1913},[424,2683,1006],{"class":434},[424,2685,2686],{"class":426,"line":1937},[424,2687,483],{"emptyLinePlaceholder":482},[424,2689,2690,2692,2694,2696,2698,2700,2702,2704],{"class":426,"line":1942},[424,2691,1265],{"class":430},[424,2693,435],{"class":434},[424,2695,1766],{"class":521},[424,2697,525],{"class":434},[424,2699,2532],{"class":438},[424,2701,742],{"class":434},[424,2703,1404],{"class":438},[424,2705,1284],{"class":434},[424,2707,2709],{"class":426,"line":2708},28,[424,2710,1290],{"class":434},[414,2712,2714],{"className":416,"code":2713,"filename":1301,"language":419,"meta":420,"style":420},"export default defineMcpHandler({\n  middleware: async (event) => {\n    const result = await getTokenUser(event)\n    if (result) {\n      event.context.userId = result.userId\n    }\n  },\n})\n",[371,2715,2716,2728,2746,2764,2776,2797,2801,2805],{"__ignoreMap":420},[424,2717,2718,2720,2722,2724,2726],{"class":426,"line":427},[424,2719,489],{"class":430},[424,2721,1310],{"class":430},[424,2723,1313],{"class":502},[424,2725,505],{"class":438},[424,2727,508],{"class":434},[424,2729,2730,2732,2734,2736,2738,2740,2742,2744],{"class":426,"line":458},[424,2731,1322],{"class":502},[424,2733,525],{"class":434},[424,2735,905],{"class":492},[424,2737,967],{"class":434},[424,2739,917],{"class":916},[424,2741,582],{"class":434},[424,2743,1187],{"class":492},[424,2745,549],{"class":434},[424,2747,2748,2750,2752,2754,2756,2758,2760,2762],{"class":426,"line":479},[424,2749,1341],{"class":492},[424,2751,1041],{"class":438},[424,2753,733],{"class":434},[424,2755,736],{"class":430},[424,2757,2365],{"class":502},[424,2759,505],{"class":521},[424,2761,917],{"class":438},[424,2763,602],{"class":521},[424,2765,2766,2768,2770,2772,2774],{"class":426,"line":486},[424,2767,1360],{"class":430},[424,2769,967],{"class":521},[424,2771,1092],{"class":438},[424,2773,1113],{"class":521},[424,2775,508],{"class":434},[424,2777,2778,2780,2782,2784,2786,2788,2790,2792,2794],{"class":426,"line":511},[424,2779,1373],{"class":438},[424,2781,742],{"class":434},[424,2783,1378],{"class":438},[424,2785,742],{"class":434},[424,2787,1404],{"class":438},[424,2789,733],{"class":434},[424,2791,1041],{"class":438},[424,2793,742],{"class":434},[424,2795,2796],{"class":438},"userId\n",[424,2798,2799],{"class":426,"line":518},[424,2800,1422],{"class":434},[424,2802,2803],{"class":426,"line":531},[424,2804,1427],{"class":434},[424,2806,2807,2809],{"class":426,"line":541},[424,2808,599],{"class":434},[424,2810,602],{"class":438},[289,2812,2814],{"id":2813},"configuring-mcp-clients","Configuring MCP Clients",[406,2816,2818],{"id":2817},"cursor","Cursor",[293,2820,2821,2822,525],{},"Add your MCP server to ",[371,2823,2824],{},".cursor\u002Fmcp.json",[414,2826,2830],{"className":2827,"code":2828,"filename":2824,"language":2829,"meta":420,"style":420},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"mcpServers\": {\n    \"my-app\": {\n      \"url\": \"http:\u002F\u002Flocalhost:3000\u002Fmcp\",\n      \"headers\": {\n        \"Authorization\": \"Bearer your-api-key-here\"\n      }\n    }\n  }\n}\n","json",[371,2831,2832,2836,2851,2865,2887,2900,2920,2925,2929,2933],{"__ignoreMap":420},[424,2833,2834],{"class":426,"line":427},[424,2835,508],{"class":434},[424,2837,2838,2841,2844,2847,2849],{"class":426,"line":458},[424,2839,2840],{"class":434},"  \"",[424,2842,2843],{"class":492},"mcpServers",[424,2845,2846],{"class":434},"\"",[424,2848,525],{"class":434},[424,2850,549],{"class":434},[424,2852,2853,2856,2859,2861,2863],{"class":426,"line":479},[424,2854,2855],{"class":434},"    \"",[424,2857,2858],{"class":922},"my-app",[424,2860,2846],{"class":434},[424,2862,525],{"class":434},[424,2864,549],{"class":434},[424,2866,2867,2870,2873,2875,2877,2880,2883,2885],{"class":426,"line":486},[424,2868,2869],{"class":434},"      \"",[424,2871,2872],{"class":1031},"url",[424,2874,2846],{"class":434},[424,2876,525],{"class":434},[424,2878,2879],{"class":434}," \"",[424,2881,2882],{"class":451},"http:\u002F\u002Flocalhost:3000\u002Fmcp",[424,2884,2846],{"class":434},[424,2886,585],{"class":434},[424,2888,2889,2891,2894,2896,2898],{"class":426,"line":511},[424,2890,2869],{"class":434},[424,2892,2893],{"class":1031},"headers",[424,2895,2846],{"class":434},[424,2897,525],{"class":434},[424,2899,549],{"class":434},[424,2901,2902,2905,2908,2910,2912,2914,2917],{"class":426,"line":518},[424,2903,2904],{"class":434},"        \"",[424,2906,2907],{"class":521},"Authorization",[424,2909,2846],{"class":434},[424,2911,525],{"class":434},[424,2913,2879],{"class":434},[424,2915,2916],{"class":451},"Bearer your-api-key-here",[424,2918,2919],{"class":434},"\"\n",[424,2921,2922],{"class":426,"line":531},[424,2923,2924],{"class":434},"      }\n",[424,2926,2927],{"class":426,"line":541},[424,2928,1422],{"class":434},[424,2930,2931],{"class":426,"line":552},[424,2932,1006],{"class":434},[424,2934,2935],{"class":426,"line":570},[424,2936,1290],{"class":434},[406,2938,2940],{"id":2939},"claude-desktop","Claude Desktop",[293,2942,2943],{},"Add to your Claude Desktop configuration:",[414,2945,2947],{"className":2827,"code":2828,"filename":2946,"language":2829,"meta":420,"style":420},"claude_desktop_config.json",[371,2948,2949,2953,2965,2977,2995,3007,3023,3027,3031,3035],{"__ignoreMap":420},[424,2950,2951],{"class":426,"line":427},[424,2952,508],{"class":434},[424,2954,2955,2957,2959,2961,2963],{"class":426,"line":458},[424,2956,2840],{"class":434},[424,2958,2843],{"class":492},[424,2960,2846],{"class":434},[424,2962,525],{"class":434},[424,2964,549],{"class":434},[424,2966,2967,2969,2971,2973,2975],{"class":426,"line":479},[424,2968,2855],{"class":434},[424,2970,2858],{"class":922},[424,2972,2846],{"class":434},[424,2974,525],{"class":434},[424,2976,549],{"class":434},[424,2978,2979,2981,2983,2985,2987,2989,2991,2993],{"class":426,"line":486},[424,2980,2869],{"class":434},[424,2982,2872],{"class":1031},[424,2984,2846],{"class":434},[424,2986,525],{"class":434},[424,2988,2879],{"class":434},[424,2990,2882],{"class":451},[424,2992,2846],{"class":434},[424,2994,585],{"class":434},[424,2996,2997,2999,3001,3003,3005],{"class":426,"line":511},[424,2998,2869],{"class":434},[424,3000,2893],{"class":1031},[424,3002,2846],{"class":434},[424,3004,525],{"class":434},[424,3006,549],{"class":434},[424,3008,3009,3011,3013,3015,3017,3019,3021],{"class":426,"line":518},[424,3010,2904],{"class":434},[424,3012,2907],{"class":521},[424,3014,2846],{"class":434},[424,3016,525],{"class":434},[424,3018,2879],{"class":434},[424,3020,2916],{"class":451},[424,3022,2919],{"class":434},[424,3024,3025],{"class":426,"line":531},[424,3026,2924],{"class":434},[424,3028,3029],{"class":426,"line":541},[424,3030,1422],{"class":434},[424,3032,3033],{"class":426,"line":552},[424,3034,1006],{"class":434},[424,3036,3037],{"class":426,"line":570},[424,3038,1290],{"class":434},[406,3040,3042],{"id":3041},"other-clients","Other Clients",[293,3044,3045],{},"Most MCP clients support custom headers. Check your client's documentation for the exact configuration format.",[289,3047,219],{"id":419},[293,3049,3050],{},"For type-safe context, extend the H3 event context:",[414,3052,3055],{"className":416,"code":3053,"filename":3054,"language":419,"meta":420,"style":420},"declare module 'h3' {\n  interface H3EventContext {\n    user?: {\n      id: string\n      name: string\n      email: string\n    }\n    userId?: string\n  }\n}\n","server\u002Ftypes.ts",[371,3056,3057,3073,3083,3093,3102,3111,3120,3124,3133,3137],{"__ignoreMap":420},[424,3058,3059,3062,3065,3067,3069,3071],{"class":426,"line":427},[424,3060,3061],{"class":492},"declare",[424,3063,3064],{"class":492}," module",[424,3066,448],{"class":434},[424,3068,406],{"class":451},[424,3070,768],{"class":434},[424,3072,549],{"class":434},[424,3074,3075,3078,3081],{"class":426,"line":458},[424,3076,3077],{"class":492},"  interface",[424,3079,3080],{"class":922}," H3EventContext",[424,3082,549],{"class":434},[424,3084,3085,3088,3091],{"class":426,"line":479},[424,3086,3087],{"class":521},"    user",[424,3089,3090],{"class":434},"?:",[424,3092,549],{"class":434},[424,3094,3095,3098,3100],{"class":426,"line":486},[424,3096,3097],{"class":521},"      id",[424,3099,525],{"class":434},[424,3101,1784],{"class":922},[424,3103,3104,3107,3109],{"class":426,"line":511},[424,3105,3106],{"class":521},"      name",[424,3108,525],{"class":434},[424,3110,1784],{"class":922},[424,3112,3113,3116,3118],{"class":426,"line":518},[424,3114,3115],{"class":521},"      email",[424,3117,525],{"class":434},[424,3119,1784],{"class":922},[424,3121,3122],{"class":426,"line":531},[424,3123,1422],{"class":434},[424,3125,3126,3129,3131],{"class":426,"line":541},[424,3127,3128],{"class":521},"    userId",[424,3130,3090],{"class":434},[424,3132,1784],{"class":922},[424,3134,3135],{"class":426,"line":552},[424,3136,1006],{"class":434},[424,3138,3139],{"class":426,"line":570},[424,3140,1290],{"class":434},[289,3142,3144],{"id":3143},"security-best-practices","Security Best Practices",[297,3146,3147,3153,3159,3165,3171],{},[300,3148,3149,3152],{},[366,3150,3151],{},"Always hash tokens"," - Store hashed tokens in your database, not plaintext",[300,3154,3155,3158],{},[366,3156,3157],{},"Set expiration dates"," - API keys should expire to limit exposure",[300,3160,3161,3164],{},[366,3162,3163],{},"Implement rate limiting"," - Prevent abuse with request limits per key",[300,3166,3167,3170],{},[366,3168,3169],{},"Allow key revocation"," - Users should be able to delete compromised keys",[300,3172,3173,3176],{},[366,3174,3175],{},"Log key usage"," - Track when keys are used for security auditing",[289,3178,3180],{"id":3179},"next-steps","Next Steps",[1438,3182,3183,3188,3193],{},[300,3184,3185,3187],{},[350,3186,215],{"href":216}," - Learn more about middleware options",[300,3189,3190,3192],{},[350,3191,123],{"href":128}," - Create custom authenticated handlers",[300,3194,3195,3197],{},[350,3196,219],{"href":220}," - Type-safe context definitions",[3199,3200,3201],"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 .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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 .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}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":420,"searchDepth":458,"depth":458,"links":3203},[3204,3205,3212,3213,3218,3219,3220],{"id":291,"depth":458,"text":46},{"id":388,"depth":458,"text":389,"children":3206},[3207,3208,3209,3210,3211],{"id":408,"depth":479,"text":409},{"id":610,"depth":479,"text":611},{"id":889,"depth":479,"text":890},{"id":1293,"depth":479,"text":1294},{"id":1463,"depth":479,"text":1464},{"id":2321,"depth":458,"text":2322},{"id":2813,"depth":458,"text":2814,"children":3214},[3215,3216,3217],{"id":2817,"depth":479,"text":2818},{"id":2939,"depth":479,"text":2940},{"id":3041,"depth":479,"text":3042},{"id":419,"depth":458,"text":219},{"id":3143,"depth":458,"text":3144},{"id":3179,"depth":458,"text":3180},"Secure your MCP endpoints with Bearer token authentication.","md",null,{},{"title":259,"icon":262},{"title":3227,"description":3228},"MCP Authentication","Learn how to add authentication to your MCP handlers using API keys and middleware.","nXjJssKxKQVsyIL6j7euGhsv7Z9vZS6-tckO9houCF8",[3231,3233],{"title":249,"path":250,"stem":251,"description":3232,"icon":252,"children":-1},"Ask the user for structured input or send them to a URL with useMcpElicitation().",{"title":264,"path":265,"stem":266,"description":3234,"icon":267,"children":-1},"Integrate external APIs and use Nuxt server utilities in MCP tools.",1788527933904]