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