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