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