[{"data":1,"prerenderedAt":3347},["ShallowReactive",2],{"docs-navigation:en":3,"content-page:docs:YIBJnYRBTW7Yljh0ggwGa2RYhBjOmoYleISovhC_21g":595,"content-page-surround:docs:YIBJnYRBTW7Yljh0ggwGa2RYhBjOmoYleISovhC_21g":3328,"i-logos:nuxt-icon":3333,"i-lucide:braces":3338,"i-logos:typescript-icon":3341,"i-lucide:terminal":3343,"i-lucide:clipboard":3345},[4,55,123,191,450,509,554,590],{"title":5,"page":6,"canonicalKey":7,"locale":8,"id":9,"draft":6,"icon":10,"sidebar":11,"children":12},"Learn",false,"1","en","content:docs:1.overview:.navigation.yml","i-lucide-book-open","section",[13,20,27,34,41,48],{"title":14,"id":15,"canonicalKey":16,"locale":8,"draft":6,"navigation":17,"icon":18,"path":19},"Better Convex Nuxt","content:docs:1.overview:1.introduction.md","1\u002F1",{"icon":18},"i-lucide-orbit","\u002Fdocs\u002Foverview\u002Fintroduction",{"title":21,"id":22,"canonicalKey":23,"locale":8,"draft":6,"navigation":24,"icon":25,"path":26},"Why Better Convex Nuxt","content:docs:1.overview:2.why-better-convex-nuxt.md","1\u002F2",{"icon":25},"i-lucide-badge-check","\u002Fdocs\u002Foverview\u002Fwhy-better-convex-nuxt",{"title":28,"id":29,"canonicalKey":30,"locale":8,"draft":6,"navigation":31,"icon":32,"path":33},"Who It Is For","content:docs:1.overview:3.who-it-is-for.md","1\u002F3",{"icon":32},"i-lucide-users","\u002Fdocs\u002Foverview\u002Fwho-it-is-for",{"title":35,"id":36,"canonicalKey":37,"locale":8,"draft":6,"navigation":38,"icon":39,"path":40},"Use Cases","content:docs:1.overview:4.use-cases.md","1\u002F4",{"icon":39},"i-lucide-layout-dashboard","\u002Fdocs\u002Foverview\u002Fuse-cases",{"title":42,"id":43,"canonicalKey":44,"locale":8,"draft":6,"navigation":45,"icon":46,"path":47},"Compare Nuxt Integrations","content:docs:1.overview:5.comparison.md","1\u002F5",{"icon":46},"i-lucide-scale","\u002Fdocs\u002Foverview\u002Fcomparison",{"title":49,"id":50,"canonicalKey":51,"locale":8,"draft":6,"navigation":52,"icon":53,"path":54},"Limitations and Trade-offs","content:docs:1.overview:6.limitations.md","1\u002F6",{"icon":53},"i-lucide-triangle-alert","\u002Fdocs\u002Foverview\u002Flimitations",{"title":56,"page":6,"canonicalKey":57,"locale":8,"id":58,"draft":6,"icon":59,"children":60},"Understand","2","content:docs:2.understand:.navigation.yml","i-lucide-brain",[61,67,74,81,88,95,102,109,116],{"title":62,"id":63,"canonicalKey":64,"locale":8,"draft":6,"navigation":65,"icon":59,"path":66},"Mental Model","content:docs:2.understand:1.mental-model.md","2\u002F1",{"icon":59},"\u002Fdocs\u002Funderstand\u002Fmental-model",{"title":68,"id":69,"canonicalKey":70,"locale":8,"draft":6,"navigation":71,"icon":72,"path":73},"Request Lifecycle","content:docs:2.understand:2.request-lifecycle.md","2\u002F2",{"icon":72},"i-lucide-route","\u002Fdocs\u002Funderstand\u002Frequest-lifecycle",{"title":75,"id":76,"canonicalKey":77,"locale":8,"draft":6,"navigation":78,"icon":79,"path":80},"SSR, Hydration, and Real-Time","content:docs:2.understand:3.ssr-hydration-realtime.md","2\u002F3",{"icon":79},"i-lucide-refresh-cw","\u002Fdocs\u002Funderstand\u002Fssr-hydration-realtime",{"title":82,"id":83,"canonicalKey":84,"locale":8,"draft":6,"navigation":85,"icon":86,"path":87},"Query Ownership and Caching","content:docs:2.understand:4.query-ownership-and-caching.md","2\u002F4",{"icon":86},"i-lucide-database","\u002Fdocs\u002Funderstand\u002Fquery-ownership-and-caching",{"title":89,"id":90,"canonicalKey":91,"locale":8,"draft":6,"navigation":92,"icon":93,"path":94},"Authentication and Identity","content:docs:2.understand:5.authentication-and-identity.md","2\u002F5",{"icon":93},"i-lucide-fingerprint","\u002Fdocs\u002Funderstand\u002Fauthentication-and-identity",{"title":96,"id":97,"canonicalKey":98,"locale":8,"draft":6,"navigation":99,"icon":100,"path":101},"Server and Client Boundaries","content:docs:2.understand:6.server-and-client-boundaries.md","2\u002F6",{"icon":100},"i-lucide-panels-top-left","\u002Fdocs\u002Funderstand\u002Fserver-and-client-boundaries",{"title":103,"id":104,"canonicalKey":105,"locale":8,"draft":6,"navigation":106,"icon":107,"path":108},"Errors and Failures","content:docs:2.understand:7.errors-and-failures.md","2\u002F7",{"icon":107},"i-lucide-circle-x","\u002Fdocs\u002Funderstand\u002Ferrors-and-failures",{"title":110,"id":111,"canonicalKey":112,"locale":8,"draft":6,"navigation":113,"icon":114,"path":115},"Design Decisions","content:docs:2.understand:8.design-decisions.md","2\u002F8",{"icon":114},"i-lucide-git-branch","\u002Fdocs\u002Funderstand\u002Fdesign-decisions",{"title":117,"id":118,"canonicalKey":119,"locale":8,"draft":6,"navigation":120,"icon":121,"path":122},"Glossary","content:docs:2.understand:9.glossary.md","2\u002F9",{"icon":121},"i-lucide-book-a","\u002Fdocs\u002Funderstand\u002Fglossary",{"title":124,"page":6,"canonicalKey":125,"locale":8,"id":126,"draft":6,"icon":127,"children":128},"Get Started","3","content:docs:3.get-started:.navigation.yml","i-lucide-rocket",[129,136,143,150,157,164,171,178,185],{"title":130,"id":131,"canonicalKey":132,"locale":8,"draft":6,"navigation":133,"icon":134,"path":135},"Choose Your Path","content:docs:3.get-started:1.choose-your-path.md","3\u002F1",{"icon":134},"i-lucide-signpost","\u002Fdocs\u002Fget-started\u002Fchoose-your-path",{"title":137,"id":138,"canonicalKey":139,"locale":8,"draft":6,"navigation":140,"icon":141,"path":142},"Installation","content:docs:3.get-started:2.installation.md","3\u002F2",{"icon":141},"i-lucide-download","\u002Fdocs\u002Fget-started\u002Finstallation",{"title":144,"id":145,"canonicalKey":146,"locale":8,"draft":6,"navigation":147,"icon":148,"path":149},"First Real-Time Page","content:docs:3.get-started:3.first-realtime-page.md","3\u002F3",{"icon":148},"i-lucide-radio","\u002Fdocs\u002Fget-started\u002Ffirst-realtime-page",{"title":151,"id":152,"canonicalKey":153,"locale":8,"draft":6,"navigation":154,"icon":155,"path":156},"Add a Mutation","content:docs:3.get-started:4.add-a-mutation.md","3\u002F4",{"icon":155},"i-lucide-square-pen","\u002Fdocs\u002Fget-started\u002Fadd-a-mutation",{"title":158,"id":159,"canonicalKey":160,"locale":8,"draft":6,"navigation":161,"icon":162,"path":163},"Add Authentication","content:docs:3.get-started:5.add-authentication.md","3\u002F5",{"icon":162},"i-lucide-log-in","\u002Fdocs\u002Fget-started\u002Fadd-authentication",{"title":165,"id":166,"canonicalKey":167,"locale":8,"draft":6,"navigation":168,"icon":169,"path":170},"Protect Data","content:docs:3.get-started:6.protect-data.md","3\u002F6",{"icon":169},"i-lucide-shield-check","\u002Fdocs\u002Fget-started\u002Fprotect-data",{"title":172,"id":173,"canonicalKey":174,"locale":8,"draft":6,"navigation":175,"icon":176,"path":177},"Project Structure","content:docs:3.get-started:7.project-structure.md","3\u002F7",{"icon":176},"i-lucide-folder-tree","\u002Fdocs\u002Fget-started\u002Fproject-structure",{"title":179,"id":180,"canonicalKey":181,"locale":8,"draft":6,"navigation":182,"icon":183,"path":184},"Next Steps","content:docs:3.get-started:8.next-steps.md","3\u002F8",{"icon":183},"i-lucide-arrow-right","\u002Fdocs\u002Fget-started\u002Fnext-steps",{"title":186,"id":187,"canonicalKey":188,"locale":8,"draft":6,"navigation":189,"icon":100,"path":190},"Plain Vue and Vite","content:docs:3.get-started:9.plain-vue.md","3\u002F9",{"icon":100},"\u002Fdocs\u002Fget-started\u002Fplain-vue",{"title":192,"page":6,"canonicalKey":193,"locale":8,"id":194,"draft":6,"icon":195,"sidebar":11,"children":196},"Build","4","content:docs:4.build:.navigation.yml","i-lucide-blocks",[197,234,265,336,368,393,432],{"title":198,"page":6,"canonicalKey":199,"locale":8,"children":200},"Queries","4\u002F1",[201,206,213,220,227],{"title":198,"id":202,"canonicalKey":203,"locale":8,"draft":6,"navigation":204,"icon":86,"path":205},"content:docs:4.build:1.queries:1.queries.md","4\u002F1\u002F1",{"icon":86},"\u002Fdocs\u002Fbuild\u002Fqueries\u002Fqueries",{"title":207,"id":208,"canonicalKey":209,"locale":8,"draft":6,"navigation":210,"icon":211,"path":212},"Reactive Arguments","content:docs:4.build:1.queries:2.reactive-arguments.md","4\u002F1\u002F2",{"icon":211},"i-lucide-sliders-horizontal","\u002Fdocs\u002Fbuild\u002Fqueries\u002Freactive-arguments",{"title":214,"id":215,"canonicalKey":216,"locale":8,"draft":6,"navigation":217,"icon":218,"path":219},"Loading and Stale Data","content:docs:4.build:1.queries:3.loading-and-stale-data.md","4\u002F1\u002F3",{"icon":218},"i-lucide-loader-circle","\u002Fdocs\u002Fbuild\u002Fqueries\u002Floading-and-stale-data",{"title":221,"id":222,"canonicalKey":223,"locale":8,"draft":6,"navigation":224,"icon":225,"path":226},"Query Execution Options","content:docs:4.build:1.queries:4.ssr-options.md","4\u002F1\u002F4",{"icon":225},"i-lucide-server-cog","\u002Fdocs\u002Fbuild\u002Fqueries\u002Fssr-options",{"title":228,"id":229,"canonicalKey":230,"locale":8,"draft":6,"navigation":231,"icon":232,"path":233},"Pagination","content:docs:4.build:1.queries:6.pagination.md","4\u002F1\u002F6",{"icon":232},"i-lucide-list-plus","\u002Fdocs\u002Fbuild\u002Fqueries\u002Fpagination",{"title":235,"page":6,"canonicalKey":236,"locale":8,"children":237},"Write Data","4\u002F2",[238,244,251,258],{"title":239,"id":240,"canonicalKey":241,"locale":8,"draft":6,"navigation":242,"icon":155,"path":243},"Mutations","content:docs:4.build:2.write-data:1.mutations.md","4\u002F2\u002F1",{"icon":155},"\u002Fdocs\u002Fbuild\u002Fwrite-data\u002Fmutations",{"title":245,"id":246,"canonicalKey":247,"locale":8,"draft":6,"navigation":248,"icon":249,"path":250},"Actions","content:docs:4.build:2.write-data:2.actions.md","4\u002F2\u002F2",{"icon":249},"i-lucide-zap","\u002Fdocs\u002Fbuild\u002Fwrite-data\u002Factions",{"title":252,"id":253,"canonicalKey":254,"locale":8,"draft":6,"navigation":255,"icon":256,"path":257},"Optimistic Updates","content:docs:4.build:2.write-data:3.optimistic-updates.md","4\u002F2\u002F3",{"icon":256},"i-lucide-gauge","\u002Fdocs\u002Fbuild\u002Fwrite-data\u002Foptimistic-updates",{"title":259,"id":260,"canonicalKey":261,"locale":8,"draft":6,"navigation":262,"icon":263,"path":264},"Concurrent Operations","content:docs:4.build:2.write-data:4.concurrent-operations.md","4\u002F2\u002F4",{"icon":263},"i-lucide-git-fork","\u002Fdocs\u002Fbuild\u002Fwrite-data\u002Fconcurrent-operations",{"title":266,"page":6,"canonicalKey":267,"locale":8,"children":268},"Authentication","4\u002F3",[269,275,282,289,295,301,308,315,322,329],{"title":266,"id":270,"canonicalKey":271,"locale":8,"draft":6,"navigation":272,"icon":273,"path":274},"content:docs:4.build:3.authentication:1.overview.md","4\u002F3\u002F1",{"icon":273},"i-lucide-shield","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Foverview",{"title":276,"id":277,"canonicalKey":278,"locale":8,"draft":6,"navigation":279,"icon":280,"path":281},"Better Auth Setup","content:docs:4.build:3.authentication:2.better-auth-setup.md","4\u002F3\u002F2",{"icon":280},"i-lucide-settings-2","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fbetter-auth-setup",{"title":283,"id":284,"canonicalKey":285,"locale":8,"draft":6,"navigation":286,"icon":287,"path":288},"Auth State and User Data","content:docs:4.build:3.authentication:3.auth-state-and-user.md","4\u002F3\u002F3",{"icon":287},"i-lucide-user-round","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fauth-state-and-user",{"title":290,"id":291,"canonicalKey":292,"locale":8,"draft":6,"navigation":293,"icon":162,"path":294},"Sign In and Sign Out","content:docs:4.build:3.authentication:4.sign-in-and-sign-out.md","4\u002F3\u002F4",{"icon":162},"\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fsign-in-and-sign-out",{"title":296,"id":297,"canonicalKey":298,"locale":8,"draft":6,"navigation":299,"icon":72,"path":300},"Route Protection","content:docs:4.build:3.authentication:5.route-protection.md","4\u002F3\u002F5",{"icon":72},"\u002Fdocs\u002Fbuild\u002Fauthentication\u002Froute-protection",{"title":302,"id":303,"canonicalKey":304,"locale":8,"draft":6,"navigation":305,"icon":306,"path":307},"Backend Authorization","content:docs:4.build:3.authentication:6.backend-authorization.md","4\u002F3\u002F6",{"icon":306},"i-lucide-lock-keyhole","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fbackend-authorization",{"title":309,"id":310,"canonicalKey":311,"locale":8,"draft":6,"navigation":312,"icon":313,"path":314},"Better Auth Plugins","content:docs:4.build:3.authentication:7.better-auth-plugins.md","4\u002F3\u002F7",{"icon":313},"i-lucide-plug","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fbetter-auth-plugins",{"title":316,"id":317,"canonicalKey":318,"locale":8,"draft":6,"navigation":319,"icon":320,"path":321},"Custom User Fields","content:docs:4.build:3.authentication:8.custom-user-fields.md","4\u002F3\u002F8",{"icon":320},"i-lucide-user-cog","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fcustom-user-fields",{"title":323,"id":324,"canonicalKey":325,"locale":8,"draft":6,"navigation":326,"icon":327,"path":328},"User Synchronization","content:docs:4.build:3.authentication:9.user-synchronization.md","4\u002F3\u002F9",{"icon":327},"i-lucide-refresh-ccw","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fuser-synchronization",{"title":330,"id":331,"canonicalKey":332,"locale":8,"draft":6,"navigation":333,"icon":334,"path":335},"Delegated OAuth and MCP","content:docs:4.build:3.authentication:10.delegated-oauth-and-mcp.md","4\u002F3\u002F10",{"icon":334},"i-lucide-bot","\u002Fdocs\u002Fbuild\u002Fauthentication\u002Fdelegated-oauth-and-mcp",{"title":337,"page":6,"canonicalKey":338,"locale":8,"children":339},"Server","4\u002F4",[340,347,354,361],{"title":341,"id":342,"canonicalKey":343,"locale":8,"draft":6,"navigation":344,"icon":345,"path":346},"serverConvex","content:docs:4.build:4.server:1.server-convex.md","4\u002F4\u002F1",{"icon":345},"i-lucide-server","\u002Fdocs\u002Fbuild\u002Fserver\u002Fserver-convex",{"title":348,"id":349,"canonicalKey":350,"locale":8,"draft":6,"navigation":351,"icon":352,"path":353},"Server Routes","content:docs:4.build:4.server:2.server-routes.md","4\u002F4\u002F2",{"icon":352},"i-lucide-waypoints","\u002Fdocs\u002Fbuild\u002Fserver\u002Fserver-routes",{"title":355,"id":356,"canonicalKey":357,"locale":8,"draft":6,"navigation":358,"icon":359,"path":360},"Webhooks and Jobs","content:docs:4.build:4.server:3.webhooks-and-jobs.md","4\u002F4\u002F3",{"icon":359},"i-lucide-webhook","\u002Fdocs\u002Fbuild\u002Fserver\u002Fwebhooks-and-jobs",{"title":362,"id":363,"canonicalKey":364,"locale":8,"draft":6,"navigation":365,"icon":366,"path":367},"Credentials and Server Security","content:docs:4.build:4.server:4.credentials-and-security.md","4\u002F4\u002F4",{"icon":366},"i-lucide-key-round","\u002Fdocs\u002Fbuild\u002Fserver\u002Fcredentials-and-security",{"title":369,"page":6,"canonicalKey":370,"locale":8,"children":371},"Files","4\u002F5",[372,379,386],{"title":373,"id":374,"canonicalKey":375,"locale":8,"draft":6,"navigation":376,"icon":377,"path":378},"Upload Files","content:docs:4.build:5.files:1.upload-files.md","4\u002F5\u002F1",{"icon":377},"i-lucide-upload","\u002Fdocs\u002Fbuild\u002Ffiles\u002Fupload-files",{"title":380,"id":381,"canonicalKey":382,"locale":8,"draft":6,"navigation":383,"icon":384,"path":385},"Storage URLs","content:docs:4.build:5.files:3.storage-urls.md","4\u002F5\u002F3",{"icon":384},"i-lucide-link","\u002Fdocs\u002Fbuild\u002Ffiles\u002Fstorage-urls",{"title":387,"id":388,"canonicalKey":389,"locale":8,"draft":6,"navigation":390,"icon":391,"path":392},"File Validation and Deletion","content:docs:4.build:5.files:4.validation-and-deletion.md","4\u002F5\u002F4",{"icon":391},"i-lucide-file-x","\u002Fdocs\u002Fbuild\u002Ffiles\u002Fvalidation-and-deletion",{"title":394,"page":6,"canonicalKey":395,"locale":8,"children":396},"Application Behavior","4\u002F6",[397,404,411,418,425],{"title":398,"id":399,"canonicalKey":400,"locale":8,"draft":6,"navigation":401,"icon":402,"path":403},"Connection State","content:docs:4.build:6.application-behavior:1.connection-state.md","4\u002F6\u002F1",{"icon":402},"i-lucide-wifi","\u002Fdocs\u002Fbuild\u002Fapplication-behavior\u002Fconnection-state",{"title":405,"id":406,"canonicalKey":407,"locale":8,"draft":6,"navigation":408,"icon":409,"path":410},"Error Handling","content:docs:4.build:6.application-behavior:2.error-handling.md","4\u002F6\u002F2",{"icon":409},"i-lucide-circle-alert","\u002Fdocs\u002Fbuild\u002Fapplication-behavior\u002Ferror-handling",{"title":412,"id":413,"canonicalKey":414,"locale":8,"draft":6,"navigation":415,"icon":416,"path":417},"Logging","content:docs:4.build:6.application-behavior:3.logging.md","4\u002F6\u002F3",{"icon":416},"i-lucide-scroll-text","\u002Fdocs\u002Fbuild\u002Fapplication-behavior\u002Flogging",{"title":419,"id":420,"canonicalKey":421,"locale":8,"draft":6,"navigation":422,"icon":423,"path":424},"DevTools","content:docs:4.build:6.application-behavior:4.devtools.md","4\u002F6\u002F4",{"icon":423},"i-lucide-wrench","\u002Fdocs\u002Fbuild\u002Fapplication-behavior\u002Fdevtools",{"title":426,"id":427,"canonicalKey":428,"locale":8,"draft":6,"navigation":429,"icon":430,"path":431},"Performance","content:docs:4.build:6.application-behavior:5.performance.md","4\u002F6\u002F5",{"icon":430},"i-lucide-chart-no-axes-combined","\u002Fdocs\u002Fbuild\u002Fapplication-behavior\u002Fperformance",{"title":433,"page":6,"canonicalKey":434,"locale":8,"id":435,"draft":6,"icon":334,"children":436},"Agents and MCP","4\u002F7","content:docs:4.build:7.agents:.navigation.yml",[437,444],{"title":438,"id":439,"canonicalKey":440,"locale":8,"draft":6,"navigation":441,"icon":442,"path":443},"MCP on Convex","content:docs:4.build:7.agents:1.mcp.md","4\u002F7\u002F1",{"icon":442},"i-lucide-plug-zap","\u002Fdocs\u002Fbuild\u002Fagents\u002Fmcp",{"title":445,"id":446,"canonicalKey":447,"locale":8,"draft":6,"navigation":448,"icon":100,"path":449},"Vue MCP Apps","content:docs:4.build:7.agents:2.mcp-apps.md","4\u002F7\u002F2",{"icon":100},"\u002Fdocs\u002Fbuild\u002Fagents\u002Fmcp-apps",{"title":451,"page":6,"canonicalKey":452,"locale":8,"id":453,"draft":6,"icon":454,"children":455},"Recipes","5","content:docs:5.recipes:.navigation.yml","i-lucide-cooking-pot",[456,462,469,476,483,490,497,503],{"title":457,"id":458,"canonicalKey":459,"locale":8,"draft":6,"navigation":460,"icon":39,"path":461},"Protected Dashboard","content:docs:5.recipes:1.protected-dashboard.md","5\u002F1",{"icon":39},"\u002Fdocs\u002Frecipes\u002Fprotected-dashboard",{"title":463,"id":464,"canonicalKey":465,"locale":8,"draft":6,"navigation":466,"icon":467,"path":468},"Real-Time Feed","content:docs:5.recipes:2.realtime-feed.md","5\u002F2",{"icon":467},"i-lucide-messages-square","\u002Fdocs\u002Frecipes\u002Frealtime-feed",{"title":470,"id":471,"canonicalKey":472,"locale":8,"draft":6,"navigation":473,"icon":474,"path":475},"Optimistic Todo List","content:docs:5.recipes:3.optimistic-todo-list.md","5\u002F3",{"icon":474},"i-lucide-list-todo","\u002Fdocs\u002Frecipes\u002Foptimistic-todo-list",{"title":477,"id":478,"canonicalKey":479,"locale":8,"draft":6,"navigation":480,"icon":481,"path":482},"Infinite Scroll","content:docs:5.recipes:4.infinite-scroll.md","5\u002F4",{"icon":481},"i-lucide-mouse","\u002Fdocs\u002Frecipes\u002Finfinite-scroll",{"title":484,"id":485,"canonicalKey":486,"locale":8,"draft":6,"navigation":487,"icon":488,"path":489},"File Upload Form","content:docs:5.recipes:5.file-upload-form.md","5\u002F5",{"icon":488},"i-lucide-file-up","\u002Fdocs\u002Frecipes\u002Ffile-upload-form",{"title":491,"id":492,"canonicalKey":493,"locale":8,"draft":6,"navigation":494,"icon":495,"path":496},"Organization Permissions","content:docs:5.recipes:6.organization-permissions.md","5\u002F6",{"icon":495},"i-lucide-building-2","\u002Fdocs\u002Frecipes\u002Forganization-permissions",{"title":498,"id":499,"canonicalKey":500,"locale":8,"draft":6,"navigation":501,"icon":345,"path":502},"Authenticated Server Route","content:docs:5.recipes:7.authenticated-server-route.md","5\u002F7",{"icon":345},"\u002Fdocs\u002Frecipes\u002Fauthenticated-server-route",{"title":504,"id":505,"canonicalKey":506,"locale":8,"draft":6,"navigation":507,"icon":100,"path":508},"Public and Private Data","content:docs:5.recipes:8.public-and-private-data.md","5\u002F8",{"icon":100},"\u002Fdocs\u002Frecipes\u002Fpublic-and-private-data",{"title":510,"page":6,"canonicalKey":511,"locale":8,"id":512,"draft":6,"icon":513,"children":514},"Reference","6","content:docs:6.reference:.navigation.yml","i-lucide-braces",[515,521,527,533,540,547],{"title":516,"id":517,"canonicalKey":518,"locale":8,"draft":6,"navigation":519,"icon":513,"path":520},"Composables","content:docs:6.reference:1.composables.md","6\u002F1",{"icon":513},"\u002Fdocs\u002Freference\u002Fcomposables",{"title":522,"id":523,"canonicalKey":524,"locale":8,"draft":6,"navigation":525,"icon":345,"path":526},"Server API","content:docs:6.reference:3.server-api.md","6\u002F3",{"icon":345},"\u002Fdocs\u002Freference\u002Fserver-api",{"title":528,"id":529,"canonicalKey":530,"locale":8,"draft":6,"navigation":531,"icon":107,"path":532},"Error Types","content:docs:6.reference:4.error-types.md","6\u002F4",{"icon":107},"\u002Fdocs\u002Freference\u002Ferror-types",{"title":534,"id":535,"canonicalKey":536,"locale":8,"draft":6,"navigation":537,"icon":538,"path":539},"Module Configuration","content:docs:6.reference:5.module-configuration.md","6\u002F5",{"icon":538},"i-lucide-settings","\u002Fdocs\u002Freference\u002Fmodule-configuration",{"title":541,"id":542,"canonicalKey":543,"locale":8,"draft":6,"navigation":544,"icon":545,"path":546},"Package Exports","content:docs:6.reference:6.package-exports.md","6\u002F6",{"icon":545},"i-lucide-package-open","\u002Fdocs\u002Freference\u002Fpackage-exports",{"title":548,"id":549,"canonicalKey":550,"locale":8,"draft":6,"navigation":551,"icon":552,"path":553},"API Surface","content:docs:6.reference:7.api-surface.md","6\u002F7",{"icon":552},"i-lucide-list","\u002Fdocs\u002Freference\u002Fapi-surface",{"title":555,"page":6,"canonicalKey":556,"locale":8,"id":557,"draft":6,"icon":280,"children":558},"Operations","7","content:docs:7.operations:.navigation.yml",[559,566,572,578,584],{"title":560,"id":561,"canonicalKey":562,"locale":8,"draft":6,"navigation":563,"icon":564,"path":565},"Environment Variables","content:docs:7.operations:1.environment-variables.md","7\u002F1",{"icon":564},"i-lucide-variable","\u002Fdocs\u002Foperations\u002Fenvironment-variables",{"title":567,"id":568,"canonicalKey":569,"locale":8,"draft":6,"navigation":570,"icon":127,"path":571},"Deployment","content:docs:7.operations:2.deployment.md","7\u002F2",{"icon":127},"\u002Fdocs\u002Foperations\u002Fdeployment",{"title":573,"id":574,"canonicalKey":575,"locale":8,"draft":6,"navigation":576,"icon":169,"path":577},"Security Model","content:docs:7.operations:3.security-model.md","7\u002F3",{"icon":169},"\u002Fdocs\u002Foperations\u002Fsecurity-model",{"title":579,"id":580,"canonicalKey":581,"locale":8,"draft":6,"navigation":582,"icon":423,"path":583},"Troubleshooting","content:docs:7.operations:4.troubleshooting.md","7\u002F4",{"icon":423},"\u002Fdocs\u002Foperations\u002Ftroubleshooting",{"title":585,"id":586,"canonicalKey":587,"locale":8,"draft":6,"navigation":588,"icon":25,"path":589},"Release Compatibility","content:docs:7.operations:5.release-compatibility.md","7\u002F5",{"icon":25},"\u002Fdocs\u002Foperations\u002Frelease-compatibility",{"title":591,"id":592,"canonicalKey":593,"locale":8,"draft":6,"path":594},"Better Convex documentation","content:docs:index.md","\u002F","\u002Fdocs",{"title":330,"description":596,"navigation":597,"body":598,"type":3315,"id":331,"canonicalKey":332,"draft":6,"partial":6,"locale":8,"collection":3316,"navigationFile":6,"file":3317,"route":3323,"resolution":3325},"Expose the fixed delegated-human MCP profile through the official Better Auth OAuth Provider and live Convex authorization.",{"icon":334},{"type":599,"children":600,"toc":3297},"root",[601,616,636,652,659,664,770,775,781,786,839,940,952,957,963,975,980,998,1004,1009,1228,1239,1341,1346,1473,1478,1518,1600,1606,1646,1651,1770,1788,1799,1804,1809,1815,1831,1901,1937,1962,1974,1979,1985,1990,2041,2072,2078,2096,2115,2586,2611,2616,2622,2634,2652,2657,2662,2667,2672,2687,2706,2712,2722,2780,2785,2823,2861,2866,2871,2876,2918,2924,2929,2991,2996,3001,3018,3024,3029,3083,3094,3100,3105,3110,3260],{"type":602,"tag":603,"props":604,"children":605},"element","p",{},[606,609,614],{"type":607,"value":608},"text","Better Convex Nuxt supports one deliberately narrow OAuth authorization-server profile for MCP clients acting on behalf of a signed-in human. Use it when an external agent needs delegated access to application operations. Start with the provider-neutral ",{"type":602,"tag":610,"props":611,"children":612},"a",{"href":443},[613],{"type":607,"value":438},{"type":607,"value":615}," guide; this page adds the optional Better Auth authorization-server profile.",{"type":602,"tag":603,"props":617,"children":618},{},[619,621,627,629,634],{"type":607,"value":620},"This is different from a private service actor. The delegated profile requires an interactive user session, verified consent, a preregistered OAuth client, and a short-lived access token. For controlled internal automation that does not act for a user, supply a provider-neutral verifier to ",{"type":602,"tag":622,"props":623,"children":624},"code",{},[625],{"type":607,"value":626},"@lupinum\u002Fbetter-convex-mcp",{"type":607,"value":628}," and keep credential state and authorization in the application. Do not combine those credentials or add an ",{"type":602,"tag":622,"props":630,"children":631},{},[632],{"type":607,"value":633},"MCP_SERVER_SECRET",{"type":607,"value":635}," bridge to the delegated path.",{"type":602,"tag":603,"props":637,"children":638},{},[639,641,650],{"type":607,"value":640},"The complete application reference is ",{"type":602,"tag":610,"props":642,"children":644},{"href":643},"https:\u002F\u002Fgithub.com\u002Flupinum-dev\u002Fbetter-convex\u002Ftree\u002Fmain\u002Fstarters\u002Fmcp-oauth-agent",[645],{"type":602,"tag":622,"props":646,"children":647},{},[648],{"type":607,"value":649},"starters\u002Fmcp-oauth-agent",{"type":607,"value":651},".",{"type":602,"tag":653,"props":654,"children":656},"h2",{"id":655},"separate-the-three-oauth-roles",[657],{"type":607,"value":658},"Separate the three OAuth roles",{"type":602,"tag":603,"props":660,"children":661},{},[662],{"type":607,"value":663},"“OAuth” can describe three independent application roles:",{"type":602,"tag":665,"props":666,"children":667},"table",{},[668,692],{"type":602,"tag":669,"props":670,"children":671},"thead",{},[672],{"type":602,"tag":673,"props":674,"children":675},"tr",{},[676,682,687],{"type":602,"tag":677,"props":678,"children":679},"th",{},[680],{"type":607,"value":681},"Role",{"type":602,"tag":677,"props":683,"children":684},{},[685],{"type":607,"value":686},"Responsibility",{"type":602,"tag":677,"props":688,"children":689},{},[690],{"type":607,"value":691},"How Better Convex Nuxt enables it",{"type":602,"tag":693,"props":694,"children":695},"tbody",{},[696,721,752],{"type":602,"tag":673,"props":697,"children":698},{},[699,705,710],{"type":602,"tag":700,"props":701,"children":702},"td",{},[703],{"type":607,"value":704},"Social\u002FOIDC login client",{"type":602,"tag":700,"props":706,"children":707},{},[708],{"type":607,"value":709},"The application signs users in through a host-selected identity provider.",{"type":602,"tag":700,"props":711,"children":712},{},[713,715,720],{"type":607,"value":714},"Configure that Better Auth provider in the application's ",{"type":602,"tag":622,"props":716,"children":717},{},[718],{"type":607,"value":719},"createAuth",{"type":607,"value":651},{"type":602,"tag":673,"props":722,"children":723},{},[724,729,734],{"type":602,"tag":700,"props":725,"children":726},{},[727],{"type":607,"value":728},"Authorization server",{"type":602,"tag":700,"props":730,"children":731},{},[732],{"type":607,"value":733},"The application issues delegated access tokens to preregistered clients.",{"type":602,"tag":700,"props":735,"children":736},{},[737,739,744,746,751],{"type":607,"value":738},"Supply the reviewed OAuth Provider options to ",{"type":602,"tag":622,"props":740,"children":741},{},[742],{"type":607,"value":743},"convexAuth()",{"type":607,"value":745}," and ",{"type":602,"tag":622,"props":747,"children":748},{},[749],{"type":607,"value":750},"oauthProvider()",{"type":607,"value":651},{"type":602,"tag":673,"props":753,"children":754},{},[755,760,765],{"type":602,"tag":700,"props":756,"children":757},{},[758],{"type":607,"value":759},"Resource server",{"type":602,"tag":700,"props":761,"children":762},{},[763],{"type":607,"value":764},"A protected endpoint verifies bearer tokens and scopes before application authorization.",{"type":602,"tag":700,"props":766,"children":767},{},[768],{"type":607,"value":769},"Opt in to the fixed MCP route and verify the bearer again in the Convex HTTP action.",{"type":602,"tag":603,"props":771,"children":772},{},[773],{"type":607,"value":774},"Enabling social login does not enable the authorization server, publish MCP\nmetadata, or create a bearer-token resource endpoint. Each role has its own\nconfiguration and threat model.",{"type":602,"tag":653,"props":776,"children":778},{"id":777},"install-the-exact-profile",[779],{"type":607,"value":780},"Install the exact profile",{"type":602,"tag":603,"props":782,"children":783},{},[784],{"type":607,"value":785},"Install the exact consumer-owned auth peers only for an auth-enabled application. A Convex-only Better Convex Nuxt install includes neither package:",{"type":602,"tag":787,"props":788,"children":791},"pre",{"language":789,"class":790},"bash","shiki shiki-themes light-plus dark-plus dark:dark-plus",[792],{"type":602,"tag":622,"props":793,"children":795},{"class":794},"language-bash",[796],{"type":602,"tag":797,"props":798,"children":801},"span",{"class":799,"style":800},"line","display: inline",[802,808,814,819,824,829,834],{"type":602,"tag":797,"props":803,"children":805},{"style":804},"color:#795E26;--shiki-dark:#DCDCAA",[806],{"type":607,"value":807},"pnpm",{"type":602,"tag":797,"props":809,"children":811},{"style":810},"color:#A31515;--shiki-dark:#CE9178",[812],{"type":607,"value":813}," add",{"type":602,"tag":797,"props":815,"children":816},{"style":810},[817],{"type":607,"value":818}," @lupinum\u002Fbetter-convex-nuxt",{"type":602,"tag":797,"props":820,"children":821},{"style":810},[822],{"type":607,"value":823}," convex@1.42.2",{"type":602,"tag":797,"props":825,"children":826},{"style":810},[827],{"type":607,"value":828}," nuxt@4.5.1",{"type":602,"tag":797,"props":830,"children":831},{"style":810},[832],{"type":607,"value":833}," better-auth@1.7.0-rc.2",{"type":602,"tag":797,"props":835,"children":836},{"style":810},[837],{"type":607,"value":838}," @better-auth\u002Foauth-provider@1.7.0-rc.2",{"type":602,"tag":665,"props":840,"children":841},{},[842,858],{"type":602,"tag":669,"props":843,"children":844},{},[845],{"type":602,"tag":673,"props":846,"children":847},{},[848,853],{"type":602,"tag":677,"props":849,"children":850},{},[851],{"type":607,"value":852},"Package",{"type":602,"tag":677,"props":854,"children":855},{},[856],{"type":607,"value":857},"Supported source-candidate version",{"type":602,"tag":693,"props":859,"children":860},{},[861,877,893,909,924],{"type":602,"tag":673,"props":862,"children":863},{},[864,869],{"type":602,"tag":700,"props":865,"children":866},{},[867],{"type":607,"value":868},"Nuxt",{"type":602,"tag":700,"props":870,"children":871},{},[872],{"type":602,"tag":622,"props":873,"children":874},{},[875],{"type":607,"value":876},"4.5.1",{"type":602,"tag":673,"props":878,"children":879},{},[880,885],{"type":602,"tag":700,"props":881,"children":882},{},[883],{"type":607,"value":884},"Convex",{"type":602,"tag":700,"props":886,"children":887},{},[888],{"type":602,"tag":622,"props":889,"children":890},{},[891],{"type":607,"value":892},"1.42.2",{"type":602,"tag":673,"props":894,"children":895},{},[896,901],{"type":602,"tag":700,"props":897,"children":898},{},[899],{"type":607,"value":900},"Better Auth",{"type":602,"tag":700,"props":902,"children":903},{},[904],{"type":602,"tag":622,"props":905,"children":906},{},[907],{"type":607,"value":908},"1.7.0-rc.2",{"type":602,"tag":673,"props":910,"children":911},{},[912,917],{"type":602,"tag":700,"props":913,"children":914},{},[915],{"type":607,"value":916},"OAuth Provider, optional peer",{"type":602,"tag":700,"props":918,"children":919},{},[920],{"type":602,"tag":622,"props":921,"children":922},{},[923],{"type":607,"value":908},{"type":602,"tag":673,"props":925,"children":926},{},[927,932],{"type":602,"tag":700,"props":928,"children":929},{},[930],{"type":607,"value":931},"Convex Helpers, package-owned",{"type":602,"tag":700,"props":933,"children":934},{},[935],{"type":602,"tag":622,"props":936,"children":937},{},[938],{"type":607,"value":939},"0.1.114",{"type":602,"tag":603,"props":941,"children":942},{},[943,945,950],{"type":607,"value":944},"The root package manifest is canonical. Do not substitute another OAuth Provider release, patch the provider in the consumer, or allow duplicate physical Provider, Better Auth, or Better Auth Core runtimes. Better Auth owns its own Kysely dependency; it is not a Better Convex peer. See ",{"type":602,"tag":610,"props":946,"children":947},{"href":589},[948],{"type":607,"value":949},"release compatibility",{"type":607,"value":951}," before changing the tuple.",{"type":602,"tag":603,"props":953,"children":954},{},[955],{"type":607,"value":956},"This source candidate is not stable auth support while its Better Auth family is still an RC.",{"type":602,"tag":653,"props":958,"children":960},{"id":959},"keep-one-auth-source-of-truth",[961],{"type":607,"value":962},"Keep one auth source of truth",{"type":602,"tag":603,"props":964,"children":965},{},[966,968,973],{"type":607,"value":967},"Mount exactly one component named ",{"type":602,"tag":622,"props":969,"children":970},{},[971],{"type":607,"value":972},"betterAuth",{"type":607,"value":974},". Better Auth owns users, accounts, sessions, verification state, OAuth clients, resources, consent, tokens, and signing keys in that component database. The OAuth Provider uses the same Better Auth factory and adapter as browser sessions; MCP does not get another auth database or adapter.",{"type":602,"tag":603,"props":976,"children":977},{},[978],{"type":607,"value":979},"Application-owned organization, membership, delegation, approval, and resource tables remain canonical Convex product data. A user display projection may be derived from Better Auth, but it is not another credential or session store.",{"type":602,"tag":603,"props":981,"children":982},{},[983,985,990,992,996],{"type":607,"value":984},"If a schema-changing Better Auth plugin requires the ",{"type":602,"tag":610,"props":986,"children":987},{"href":314},[988],{"type":607,"value":989},"local-component mode",{"type":607,"value":991},", generate one complete local schema before the first write and mount that component as ",{"type":602,"tag":622,"props":993,"children":994},{},[995],{"type":607,"value":972},{"type":607,"value":997},". Do not mount the packaged and local components together.",{"type":602,"tag":653,"props":999,"children":1001},{"id":1000},"enable-the-fixed-public-topology",[1002],{"type":607,"value":1003},"Enable the fixed public topology",{"type":602,"tag":603,"props":1005,"children":1006},{},[1007],{"type":607,"value":1008},"Configure Nuxt for the authorization-server origin. Register the official MCP\nhandler directly on the deployment-owned Convex HTTP router, as shown by the\nstarter; Nuxt does not relay MCP traffic:",{"type":602,"tag":787,"props":1010,"children":1013},{"language":1011,"filename":1012,"class":790},"ts","nuxt.config.ts",[1014],{"type":602,"tag":622,"props":1015,"children":1017},{"class":1016},"language-ts",[1018,1043,1045,1069,1070,1083,1084,1121,1122,1155,1156,1210,1211,1219,1220],{"type":602,"tag":797,"props":1019,"children":1020},{"class":799,"style":800},[1021,1027,1032,1037],{"type":602,"tag":797,"props":1022,"children":1024},{"style":1023},"color:#AF00DB;--shiki-dark:#C586C0",[1025],{"type":607,"value":1026},"export",{"type":602,"tag":797,"props":1028,"children":1029},{"style":1023},[1030],{"type":607,"value":1031}," default",{"type":602,"tag":797,"props":1033,"children":1034},{"style":804},[1035],{"type":607,"value":1036}," defineNuxtConfig",{"type":602,"tag":797,"props":1038,"children":1040},{"style":1039},"color:#000000;--shiki-dark:#D4D4D4",[1041],{"type":607,"value":1042},"({",{"type":607,"value":1044},"\n",{"type":602,"tag":797,"props":1046,"children":1047},{"class":799,"style":800},[1048,1054,1059,1064],{"type":602,"tag":797,"props":1049,"children":1051},{"style":1050},"color:#001080;--shiki-dark:#9CDCFE",[1052],{"type":607,"value":1053},"  modules:",{"type":602,"tag":797,"props":1055,"children":1056},{"style":1039},[1057],{"type":607,"value":1058}," [",{"type":602,"tag":797,"props":1060,"children":1061},{"style":810},[1062],{"type":607,"value":1063},"'@lupinum\u002Fbetter-convex-nuxt'",{"type":602,"tag":797,"props":1065,"children":1066},{"style":1039},[1067],{"type":607,"value":1068},"],",{"type":607,"value":1044},{"type":602,"tag":797,"props":1071,"children":1072},{"class":799,"style":800},[1073,1078],{"type":602,"tag":797,"props":1074,"children":1075},{"style":1050},[1076],{"type":607,"value":1077},"  convex:",{"type":602,"tag":797,"props":1079,"children":1080},{"style":1039},[1081],{"type":607,"value":1082}," {",{"type":607,"value":1044},{"type":602,"tag":797,"props":1085,"children":1086},{"class":799,"style":800},[1087,1092,1097,1101,1106,1110,1116],{"type":602,"tag":797,"props":1088,"children":1089},{"style":1050},[1090],{"type":607,"value":1091},"    url:",{"type":602,"tag":797,"props":1093,"children":1094},{"style":1050},[1095],{"type":607,"value":1096}," process",{"type":602,"tag":797,"props":1098,"children":1099},{"style":1039},[1100],{"type":607,"value":651},{"type":602,"tag":797,"props":1102,"children":1103},{"style":1050},[1104],{"type":607,"value":1105},"env",{"type":602,"tag":797,"props":1107,"children":1108},{"style":1039},[1109],{"type":607,"value":651},{"type":602,"tag":797,"props":1111,"children":1113},{"style":1112},"color:#0070C1;--shiki-dark:#4FC1FF",[1114],{"type":607,"value":1115},"NUXT_PUBLIC_CONVEX_URL",{"type":602,"tag":797,"props":1117,"children":1118},{"style":1039},[1119],{"type":607,"value":1120},",",{"type":607,"value":1044},{"type":602,"tag":797,"props":1123,"children":1124},{"class":799,"style":800},[1125,1130,1134,1138,1142,1146,1151],{"type":602,"tag":797,"props":1126,"children":1127},{"style":1050},[1128],{"type":607,"value":1129},"    siteUrl:",{"type":602,"tag":797,"props":1131,"children":1132},{"style":1050},[1133],{"type":607,"value":1096},{"type":602,"tag":797,"props":1135,"children":1136},{"style":1039},[1137],{"type":607,"value":651},{"type":602,"tag":797,"props":1139,"children":1140},{"style":1050},[1141],{"type":607,"value":1105},{"type":602,"tag":797,"props":1143,"children":1144},{"style":1039},[1145],{"type":607,"value":651},{"type":602,"tag":797,"props":1147,"children":1148},{"style":1112},[1149],{"type":607,"value":1150},"NUXT_PUBLIC_CONVEX_SITE_URL",{"type":602,"tag":797,"props":1152,"children":1153},{"style":1039},[1154],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":1157,"children":1158},{"class":799,"style":800},[1159,1164,1169,1174,1178,1182,1186,1190,1195,1200,1205],{"type":602,"tag":797,"props":1160,"children":1161},{"style":1050},[1162],{"type":607,"value":1163},"    auth:",{"type":602,"tag":797,"props":1165,"children":1166},{"style":1039},[1167],{"type":607,"value":1168}," { ",{"type":602,"tag":797,"props":1170,"children":1171},{"style":1050},[1172],{"type":607,"value":1173},"origin:",{"type":602,"tag":797,"props":1175,"children":1176},{"style":1050},[1177],{"type":607,"value":1096},{"type":602,"tag":797,"props":1179,"children":1180},{"style":1039},[1181],{"type":607,"value":651},{"type":602,"tag":797,"props":1183,"children":1184},{"style":1050},[1185],{"type":607,"value":1105},{"type":602,"tag":797,"props":1187,"children":1188},{"style":1039},[1189],{"type":607,"value":651},{"type":602,"tag":797,"props":1191,"children":1192},{"style":1112},[1193],{"type":607,"value":1194},"SITE_URL",{"type":602,"tag":797,"props":1196,"children":1197},{"style":1039},[1198],{"type":607,"value":1199}," ?? ",{"type":602,"tag":797,"props":1201,"children":1202},{"style":810},[1203],{"type":607,"value":1204},"'http:\u002F\u002Flocalhost:3000'",{"type":602,"tag":797,"props":1206,"children":1207},{"style":1039},[1208],{"type":607,"value":1209}," },",{"type":607,"value":1044},{"type":602,"tag":797,"props":1212,"children":1213},{"class":799,"style":800},[1214],{"type":602,"tag":797,"props":1215,"children":1216},{"style":1039},[1217],{"type":607,"value":1218},"  },",{"type":607,"value":1044},{"type":602,"tag":797,"props":1221,"children":1222},{"class":799,"style":800},[1223],{"type":602,"tag":797,"props":1224,"children":1225},{"style":1039},[1226],{"type":607,"value":1227},"})",{"type":602,"tag":603,"props":1229,"children":1230},{},[1231,1233,1237],{"type":607,"value":1232},"All public identifiers come from the one validated ",{"type":602,"tag":622,"props":1234,"children":1235},{},[1236],{"type":607,"value":1194},{"type":607,"value":1238},"; request headers never select them.",{"type":602,"tag":665,"props":1240,"children":1241},{},[1242,1258],{"type":602,"tag":669,"props":1243,"children":1244},{},[1245],{"type":602,"tag":673,"props":1246,"children":1247},{},[1248,1253],{"type":602,"tag":677,"props":1249,"children":1250},{},[1251],{"type":607,"value":1252},"Purpose",{"type":602,"tag":677,"props":1254,"children":1255},{},[1256],{"type":607,"value":1257},"Fixed public value",{"type":602,"tag":693,"props":1259,"children":1260},{},[1261,1277,1293,1309,1325],{"type":602,"tag":673,"props":1262,"children":1263},{},[1264,1269],{"type":602,"tag":700,"props":1265,"children":1266},{},[1267],{"type":607,"value":1268},"Authorization issuer",{"type":602,"tag":700,"props":1270,"children":1271},{},[1272],{"type":602,"tag":622,"props":1273,"children":1274},{},[1275],{"type":607,"value":1276},"https:\u002F\u002Fapp.example.com\u002Fapi\u002Fauth",{"type":602,"tag":673,"props":1278,"children":1279},{},[1280,1285],{"type":602,"tag":700,"props":1281,"children":1282},{},[1283],{"type":607,"value":1284},"Authorization-server metadata",{"type":602,"tag":700,"props":1286,"children":1287},{},[1288],{"type":602,"tag":622,"props":1289,"children":1290},{},[1291],{"type":607,"value":1292},"https:\u002F\u002Fapp.example.com\u002F.well-known\u002Foauth-authorization-server\u002Fapi\u002Fauth",{"type":602,"tag":673,"props":1294,"children":1295},{},[1296,1301],{"type":602,"tag":700,"props":1297,"children":1298},{},[1299],{"type":607,"value":1300},"JWKS",{"type":602,"tag":700,"props":1302,"children":1303},{},[1304],{"type":602,"tag":622,"props":1305,"children":1306},{},[1307],{"type":607,"value":1308},"https:\u002F\u002Fapp.example.com\u002Fapi\u002Fauth\u002Fjwks",{"type":602,"tag":673,"props":1310,"children":1311},{},[1312,1317],{"type":602,"tag":700,"props":1313,"children":1314},{},[1315],{"type":607,"value":1316},"MCP resource",{"type":602,"tag":700,"props":1318,"children":1319},{},[1320],{"type":602,"tag":622,"props":1321,"children":1322},{},[1323],{"type":607,"value":1324},"https:\u002F\u002Fdeployment.convex.site\u002Fmcp",{"type":602,"tag":673,"props":1326,"children":1327},{},[1328,1333],{"type":602,"tag":700,"props":1329,"children":1330},{},[1331],{"type":607,"value":1332},"Protected-resource metadata",{"type":602,"tag":700,"props":1334,"children":1335},{},[1336],{"type":602,"tag":622,"props":1337,"children":1338},{},[1339],{"type":607,"value":1340},"https:\u002F\u002Fdeployment.convex.site\u002F.well-known\u002Foauth-protected-resource\u002Fmcp",{"type":602,"tag":603,"props":1342,"children":1343},{},[1344],{"type":607,"value":1345},"The Convex MCP handler publishes the protected-resource document from trusted configuration:",{"type":602,"tag":787,"props":1347,"children":1349},{"language":1348,"class":790},"json",[1350],{"type":602,"tag":622,"props":1351,"children":1353},{"class":1352},"language-json",[1354,1362,1363,1386,1387,1409,1410,1441,1442,1464,1465],{"type":602,"tag":797,"props":1355,"children":1356},{"class":799,"style":800},[1357],{"type":602,"tag":797,"props":1358,"children":1359},{"style":1039},[1360],{"type":607,"value":1361},"{",{"type":607,"value":1044},{"type":602,"tag":797,"props":1364,"children":1365},{"class":799,"style":800},[1366,1372,1377,1382],{"type":602,"tag":797,"props":1367,"children":1369},{"style":1368},"color:#0451A5;--shiki-dark:#9CDCFE",[1370],{"type":607,"value":1371},"  \"resource\"",{"type":602,"tag":797,"props":1373,"children":1374},{"style":1039},[1375],{"type":607,"value":1376},": ",{"type":602,"tag":797,"props":1378,"children":1379},{"style":810},[1380],{"type":607,"value":1381},"\"https:\u002F\u002Fdeployment.convex.site\u002Fmcp\"",{"type":602,"tag":797,"props":1383,"children":1384},{"style":1039},[1385],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":1388,"children":1389},{"class":799,"style":800},[1390,1395,1400,1405],{"type":602,"tag":797,"props":1391,"children":1392},{"style":1368},[1393],{"type":607,"value":1394},"  \"authorization_servers\"",{"type":602,"tag":797,"props":1396,"children":1397},{"style":1039},[1398],{"type":607,"value":1399},": [",{"type":602,"tag":797,"props":1401,"children":1402},{"style":810},[1403],{"type":607,"value":1404},"\"https:\u002F\u002Fapp.example.com\u002Fapi\u002Fauth\"",{"type":602,"tag":797,"props":1406,"children":1407},{"style":1039},[1408],{"type":607,"value":1068},{"type":607,"value":1044},{"type":602,"tag":797,"props":1411,"children":1412},{"class":799,"style":800},[1413,1418,1422,1427,1432,1437],{"type":602,"tag":797,"props":1414,"children":1415},{"style":1368},[1416],{"type":607,"value":1417},"  \"scopes_supported\"",{"type":602,"tag":797,"props":1419,"children":1420},{"style":1039},[1421],{"type":607,"value":1399},{"type":602,"tag":797,"props":1423,"children":1424},{"style":810},[1425],{"type":607,"value":1426},"\"mcp:read\"",{"type":602,"tag":797,"props":1428,"children":1429},{"style":1039},[1430],{"type":607,"value":1431},", ",{"type":602,"tag":797,"props":1433,"children":1434},{"style":810},[1435],{"type":607,"value":1436},"\"mcp:write\"",{"type":602,"tag":797,"props":1438,"children":1439},{"style":1039},[1440],{"type":607,"value":1068},{"type":607,"value":1044},{"type":602,"tag":797,"props":1443,"children":1444},{"class":799,"style":800},[1445,1450,1454,1459],{"type":602,"tag":797,"props":1446,"children":1447},{"style":1368},[1448],{"type":607,"value":1449},"  \"bearer_methods_supported\"",{"type":602,"tag":797,"props":1451,"children":1452},{"style":1039},[1453],{"type":607,"value":1399},{"type":602,"tag":797,"props":1455,"children":1456},{"style":810},[1457],{"type":607,"value":1458},"\"header\"",{"type":602,"tag":797,"props":1460,"children":1461},{"style":1039},[1462],{"type":607,"value":1463},"]",{"type":607,"value":1044},{"type":602,"tag":797,"props":1466,"children":1467},{"class":799,"style":800},[1468],{"type":602,"tag":797,"props":1469,"children":1470},{"style":1039},[1471],{"type":607,"value":1472},"}",{"type":602,"tag":603,"props":1474,"children":1475},{},[1476],{"type":607,"value":1477},"The authorization-server metadata is a validated projection of the official provider's metadata. Convex owns the resource document; Nuxt does not maintain a second capability document or MCP relay.",{"type":602,"tag":603,"props":1479,"children":1480},{},[1481,1483,1488,1490,1495,1497,1502,1504,1509,1511,1516],{"type":607,"value":1482},"Both metadata documents are public and may be fetched by browser-based clients\nwith ",{"type":602,"tag":622,"props":1484,"children":1485},{},[1486],{"type":607,"value":1487},"Access-Control-Allow-Origin: *",{"type":607,"value":1489},"; they never enable credentialed CORS. The\nonly cross-origin browser exception under ",{"type":602,"tag":622,"props":1491,"children":1492},{},[1493],{"type":607,"value":1494},"\u002Fapi\u002Fauth",{"type":607,"value":1496}," is the exact public-client\nform exchange at ",{"type":602,"tag":622,"props":1498,"children":1499},{},[1500],{"type":607,"value":1501},"POST \u002Foauth2\u002Ftoken",{"type":607,"value":1503}," and its exact ",{"type":602,"tag":622,"props":1505,"children":1506},{},[1507],{"type":607,"value":1508},"OPTIONS",{"type":607,"value":1510}," preflight. It\naccepts no query, Cookie, Authorization, proxy authorization, or DPoP header and\nkeeps the body bounded to ",{"type":602,"tag":622,"props":1512,"children":1513},{},[1514],{"type":607,"value":1515},"application\u002Fx-www-form-urlencoded",{"type":607,"value":1517},". Authorize,\nrevoke, session, consent, administration, and every other auth route remain\nsame-origin. BCN's boundary proves the stored client\u002Fresource\u002Flink profile and\nrequires one resource before consent; the official provider owns authorization\nrequest parsing, PKCE, scopes, redirect trust, state preservation, and OAuth\nerror responses. The token\u002Frevocation guard separately proves the registered\nclient authentication shape, redirect shape, resource, and grant before the\nprovider's consume boundary.",{"type":602,"tag":603,"props":1519,"children":1520},{},[1521,1523,1528,1530,1535,1536,1541,1543,1548,1550,1554,1556,1560,1561,1565,1567,1572,1574,1579,1581,1585,1587,1591,1593,1598],{"type":607,"value":1522},"Register one Convex HTTP action at ",{"type":602,"tag":622,"props":1524,"children":1525},{},[1526],{"type":607,"value":1527},"\u002Fmcp",{"type":607,"value":1529},"; that action is the resource server.\nThere is no Nuxt MCP route, bearer relay, or caller-selected upstream\u002Ffunction.\nThe OAuth resource uses exactly five Convex route registrations: ",{"type":602,"tag":622,"props":1531,"children":1532},{},[1533],{"type":607,"value":1534},"POST",{"type":607,"value":1431},{"type":602,"tag":622,"props":1537,"children":1538},{},[1539],{"type":607,"value":1540},"GET",{"type":607,"value":1542},",\nand ",{"type":602,"tag":622,"props":1544,"children":1545},{},[1546],{"type":607,"value":1547},"DELETE",{"type":607,"value":1549}," at ",{"type":602,"tag":622,"props":1551,"children":1552},{},[1553],{"type":607,"value":1527},{"type":607,"value":1555},", followed by ",{"type":602,"tag":622,"props":1557,"children":1558},{},[1559],{"type":607,"value":1540},{"type":607,"value":745},{"type":602,"tag":622,"props":1562,"children":1563},{},[1564],{"type":607,"value":1508},{"type":607,"value":1566}," at\n",{"type":602,"tag":622,"props":1568,"children":1569},{},[1570],{"type":607,"value":1571},"\u002F.well-known\u002Foauth-protected-resource\u002Fmcp",{"type":607,"value":1573},". Convex maps ",{"type":602,"tag":622,"props":1575,"children":1576},{},[1577],{"type":607,"value":1578},"HEAD",{"type":607,"value":1580}," discovery to the\nmetadata ",{"type":602,"tag":622,"props":1582,"children":1583},{},[1584],{"type":607,"value":1540},{"type":607,"value":1586}," route. The metadata ",{"type":602,"tag":622,"props":1588,"children":1589},{},[1590],{"type":607,"value":1508},{"type":607,"value":1592}," route serves public,\ncredential-free discovery CORS; it does not enable cross-origin MCP transport,\nand there is no ",{"type":602,"tag":622,"props":1594,"children":1595},{},[1596],{"type":607,"value":1597},"OPTIONS \u002Fmcp",{"type":607,"value":1599}," route.",{"type":602,"tag":653,"props":1601,"children":1603},{"id":1602},"configure-one-reviewed-provider-profile",[1604],{"type":607,"value":1605},"Configure one reviewed provider profile",{"type":602,"tag":603,"props":1607,"children":1608},{},[1609,1611,1616,1618,1622,1623,1627,1629,1634,1635,1639,1641,1645],{"type":607,"value":1610},"Create one ",{"type":602,"tag":622,"props":1612,"children":1613},{},[1614],{"type":607,"value":1615},"OAuthOptions",{"type":607,"value":1617}," object per request and pass that same object to both ",{"type":602,"tag":622,"props":1619,"children":1620},{},[1621],{"type":607,"value":743},{"type":607,"value":745},{"type":602,"tag":622,"props":1624,"children":1625},{},[1626],{"type":607,"value":750},{"type":607,"value":1628},". The supported plugin order is ",{"type":602,"tag":622,"props":1630,"children":1631},{},[1632],{"type":607,"value":1633},"jwt()",{"type":607,"value":1431},{"type":602,"tag":622,"props":1636,"children":1637},{},[1638],{"type":607,"value":743},{"type":607,"value":1640},", then ",{"type":602,"tag":622,"props":1642,"children":1643},{},[1644],{"type":607,"value":750},{"type":607,"value":651},{"type":602,"tag":603,"props":1647,"children":1648},{},[1649],{"type":607,"value":1650},"The fixed controls are:",{"type":602,"tag":1652,"props":1653,"children":1654},"ul",{},[1655,1661,1666,1671,1676,1694,1699,1722,1740,1745],{"type":602,"tag":1656,"props":1657,"children":1658},"li",{},[1659],{"type":607,"value":1660},"authorization code only, with codes expiring in at most 120 seconds;",{"type":602,"tag":1656,"props":1662,"children":1663},{},[1664],{"type":607,"value":1665},"access tokens expiring in at most 600 seconds;",{"type":602,"tag":1656,"props":1667,"children":1668},{},[1669],{"type":607,"value":1670},"PKCE S256 for every client, including confidential clients;",{"type":602,"tag":1656,"props":1672,"children":1673},{},[1674],{"type":607,"value":1675},"exact HTTPS redirects or RFC 8252 loopback-IP redirects, plus one linked resource;",{"type":602,"tag":1656,"props":1677,"children":1678},{},[1679,1681,1686,1687,1692],{"type":607,"value":1680},"explicit consent and the exact ",{"type":602,"tag":622,"props":1682,"children":1683},{},[1684],{"type":607,"value":1685},"mcp:read",{"type":607,"value":593},{"type":602,"tag":622,"props":1688,"children":1689},{},[1690],{"type":607,"value":1691},"mcp:write",{"type":607,"value":1693}," scope allowlist;",{"type":602,"tag":1656,"props":1695,"children":1696},{},[1697],{"type":607,"value":1698},"encrypted social-account access, refresh, and ID tokens, plus hashed delegated OAuth client secrets and stored provider token records; the delegated profile issues no refresh token;",{"type":602,"tag":1656,"props":1700,"children":1701},{},[1702,1707,1709,1714,1715,1720],{"type":602,"tag":622,"props":1703,"children":1704},{},[1705],{"type":607,"value":1706},"account.storeAccountCookie: false",{"type":607,"value":1708}," and disabled ",{"type":602,"tag":622,"props":1710,"children":1711},{},[1712],{"type":607,"value":1713},"\u002Fget-access-token",{"type":607,"value":745},{"type":602,"tag":622,"props":1716,"children":1717},{},[1718],{"type":607,"value":1719},"\u002Frefresh-token",{"type":607,"value":1721}," routes, so provider credentials remain inside the auth process;",{"type":602,"tag":1656,"props":1723,"children":1724},{},[1725,1727,1732,1733,1738],{"type":607,"value":1726},"RS256 access tokens with ",{"type":602,"tag":622,"props":1728,"children":1729},{},[1730],{"type":607,"value":1731},"typ = \"at+jwt\"",{"type":607,"value":745},{"type":602,"tag":622,"props":1734,"children":1735},{},[1736],{"type":607,"value":1737},"token_use = \"oauth-access\"",{"type":607,"value":1739},";",{"type":602,"tag":1656,"props":1741,"children":1742},{},[1743],{"type":607,"value":1744},"database-backed Better Auth rate limiting;",{"type":602,"tag":1656,"props":1746,"children":1747},{},[1748,1750,1755,1756,1761,1763,1768],{"type":607,"value":1749},"mandatory ",{"type":602,"tag":622,"props":1751,"children":1752},{},[1753],{"type":607,"value":1754},"clientPrivileges",{"type":607,"value":745},{"type":602,"tag":622,"props":1757,"children":1758},{},[1759],{"type":607,"value":1760},"resourcePrivileges",{"type":607,"value":1762}," callbacks that return ",{"type":602,"tag":622,"props":1764,"children":1765},{},[1766],{"type":607,"value":1767},"true",{"type":607,"value":1769}," only for the application's current authorized OAuth administrator.",{"type":602,"tag":603,"props":1771,"children":1772},{},[1773,1775,1780,1781,1786],{"type":607,"value":1774},"The callbacks fail closed on a missing session\u002Fuser, ",{"type":602,"tag":622,"props":1776,"children":1777},{},[1778],{"type":607,"value":1779},"false",{"type":607,"value":1431},{"type":602,"tag":622,"props":1782,"children":1783},{},[1784],{"type":607,"value":1785},"undefined",{"type":607,"value":1787},", an exception, or timeout. They authorize administration only; they never replace per-tool product authorization.",{"type":602,"tag":603,"props":1789,"children":1790},{},[1791,1793,1797],{"type":607,"value":1792},"Administrator revocation is a request-start gate: after the revocation commits,\nnew provider administration requests are denied, but it cannot cancel a provider\nmutation whose privilege callback already returned ",{"type":602,"tag":622,"props":1794,"children":1795},{},[1796],{"type":607,"value":1767},{"type":607,"value":1798},". If incident response\nrequires a terminal cutover, close or drain auth ingress first, wait for bounded\nin-flight requests to finish, commit the revocation, and then reopen traffic.",{"type":602,"tag":603,"props":1800,"children":1801},{},[1802],{"type":607,"value":1803},"Use the exact server shape in the maintained starter rather than copying a partial options list. Better Convex Nuxt rejects startup when the provider, JWT graph, storage controls, grants, algorithms, privilege callbacks, or plugin ordering drift from the reviewed profile.",{"type":602,"tag":603,"props":1805,"children":1806},{},[1807],{"type":607,"value":1808},"The pinned Better Auth RC encrypts account access\u002Frefresh tokens but misses provider ID tokens at several persistence sites. Better Convex Nuxt closes that gap at the single adapter boundary: it encrypts the ID token before the component write and decrypts it only when Better Auth reads the account inside the auth process. Social-provider sign-in and account identity continue to work. Exporting provider API tokens to application code or the browser is outside the supported profile.",{"type":602,"tag":653,"props":1810,"children":1812},{"id":1811},"preregister-clients-through-the-provider",[1813],{"type":607,"value":1814},"Preregister clients through the provider",{"type":602,"tag":603,"props":1816,"children":1817},{},[1818,1820,1824,1825,1829],{"type":607,"value":1819},"Do not insert or patch OAuth tables directly. An application-owned, authenticated admin operation should call the official provider's admin endpoints to create the resource, create the client, and link them. Gate that operation with the same application authorization used by ",{"type":602,"tag":622,"props":1821,"children":1822},{},[1823],{"type":607,"value":1754},{"type":607,"value":745},{"type":602,"tag":622,"props":1826,"children":1827},{},[1828],{"type":607,"value":1760},{"type":607,"value":1830},", and verify the stored profile after creation.",{"type":602,"tag":665,"props":1832,"children":1833},{},[1834,1850],{"type":602,"tag":669,"props":1835,"children":1836},{},[1837],{"type":602,"tag":673,"props":1838,"children":1839},{},[1840,1845],{"type":602,"tag":677,"props":1841,"children":1842},{},[1843],{"type":607,"value":1844},"Client kind",{"type":602,"tag":677,"props":1846,"children":1847},{},[1848],{"type":607,"value":1849},"Required stored profile",{"type":602,"tag":693,"props":1851,"children":1852},{},[1853,1877],{"type":602,"tag":673,"props":1854,"children":1855},{},[1856,1861],{"type":602,"tag":700,"props":1857,"children":1858},{},[1859],{"type":607,"value":1860},"Confidential web client",{"type":602,"tag":700,"props":1862,"children":1863},{},[1864,1869,1870,1875],{"type":602,"tag":622,"props":1865,"children":1866},{},[1867],{"type":607,"value":1868},"public: false",{"type":607,"value":1431},{"type":602,"tag":622,"props":1871,"children":1872},{},[1873],{"type":607,"value":1874},"token_endpoint_auth_method: \"client_secret_basic\"",{"type":607,"value":1876},", exact HTTPS redirects",{"type":602,"tag":673,"props":1878,"children":1879},{},[1880,1885],{"type":602,"tag":700,"props":1881,"children":1882},{},[1883],{"type":607,"value":1884},"Public agent\u002Fnative client",{"type":602,"tag":700,"props":1886,"children":1887},{},[1888,1893,1894,1899],{"type":602,"tag":622,"props":1889,"children":1890},{},[1891],{"type":607,"value":1892},"public: true",{"type":607,"value":1431},{"type":602,"tag":622,"props":1895,"children":1896},{},[1897],{"type":607,"value":1898},"token_endpoint_auth_method: \"none\"",{"type":607,"value":1900},", exact HTTPS or registered loopback redirects, no secret",{"type":602,"tag":603,"props":1902,"children":1903},{},[1904,1906,1911,1912,1917,1918,1923,1924,1929,1931,1935],{"type":607,"value":1905},"Both kinds use only ",{"type":602,"tag":622,"props":1907,"children":1908},{},[1909],{"type":607,"value":1910},"grant_types: [\"authorization_code\"]",{"type":607,"value":1431},{"type":602,"tag":622,"props":1913,"children":1914},{},[1915],{"type":607,"value":1916},"response_types: [\"code\"]",{"type":607,"value":1431},{"type":602,"tag":622,"props":1919,"children":1920},{},[1921],{"type":607,"value":1922},"require_pkce: true",{"type":607,"value":1431},{"type":602,"tag":622,"props":1925,"children":1926},{},[1927],{"type":607,"value":1928},"skip_consent: false",{"type":607,"value":1930},", one exact linked ",{"type":602,"tag":622,"props":1932,"children":1933},{},[1934],{"type":607,"value":1527},{"type":607,"value":1936}," resource, and the approved scopes.",{"type":602,"tag":603,"props":1938,"children":1939},{},[1940,1942,1947,1948,1953,1955,1960],{"type":607,"value":1941},"HTTP loopback registrations use one canonical callback with an explicit port.\nFor ",{"type":602,"tag":622,"props":1943,"children":1944},{},[1945],{"type":607,"value":1946},"127.0.0.1",{"type":607,"value":745},{"type":602,"tag":622,"props":1949,"children":1950},{},[1951],{"type":607,"value":1952},"[::1]",{"type":607,"value":1954},", RFC 8252 permits the native client to choose an\nephemeral port at authorization time; scheme, IP literal, path, and query still\nmatch exactly, and token redemption must repeat the exact callback used for the\nauthorization code. ",{"type":602,"tag":622,"props":1956,"children":1957},{},[1958],{"type":607,"value":1959},"localhost",{"type":607,"value":1961}," is a DNS name, so its port remains exact.",{"type":602,"tag":603,"props":1963,"children":1964},{},[1965,1967,1972],{"type":607,"value":1966},"For a confidential client, deliver the provider's one-time secret result directly into that client's secret manager. The client authenticates at token and revocation endpoints with HTTP Basic; ",{"type":602,"tag":622,"props":1968,"children":1969},{},[1970],{"type":607,"value":1971},"client_secret_post",{"type":607,"value":1973},", assertions, and mixed Basic\u002Fbody identities are rejected. A public client receives no secret, identifies itself with its preregistered client ID, and must complete S256 PKCE.",{"type":602,"tag":603,"props":1975,"children":1976},{},[1977],{"type":607,"value":1978},"Dynamic registration is not a fallback. If an MCP client cannot use preregistered static client information, it is not compatible with this beta profile.",{"type":602,"tag":653,"props":1980,"children":1982},{"id":1981},"build-a-verified-login-and-consent-ui",[1983],{"type":607,"value":1984},"Build a verified login and consent UI",{"type":602,"tag":603,"props":1986,"children":1987},{},[1988],{"type":607,"value":1989},"OAuth query parameters are not trustworthy display data. The login and consent pages must:",{"type":602,"tag":1991,"props":1992,"children":1993},"ol",{},[1994,1999,2004,2009,2021,2026,2031,2036],{"type":602,"tag":1656,"props":1995,"children":1996},{},[1997],{"type":607,"value":1998},"accept one bounded provider transaction query;",{"type":602,"tag":1656,"props":2000,"children":2001},{},[2002],{"type":607,"value":2003},"require exactly one client ID, resource, and scope value;",{"type":602,"tag":1656,"props":2005,"children":2006},{},[2007],{"type":607,"value":2008},"verify the preregistered client through the provider-owned prelogin\u002Ftransaction path before rendering its name;",{"type":602,"tag":1656,"props":2010,"children":2011},{},[2012,2014,2019],{"type":607,"value":2013},"compare the resource to the exact deployment-owned ",{"type":602,"tag":622,"props":2015,"children":2016},{},[2017],{"type":607,"value":2018},"CONVEX_SITE_URL + \"\u002Fmcp\"",{"type":607,"value":2020}," identifier and the scopes to the fixed allowlist;",{"type":602,"tag":1656,"props":2022,"children":2023},{},[2024],{"type":607,"value":2025},"display the verified client name, exact resource, and requested scopes;",{"type":602,"tag":1656,"props":2027,"children":2028},{},[2029],{"type":607,"value":2030},"submit the original bounded transaction state back to the provider;",{"type":602,"tag":1656,"props":2032,"children":2033},{},[2034],{"type":607,"value":2035},"let approval preserve or narrow the requested scope set, never widen it;",{"type":602,"tag":1656,"props":2037,"children":2038},{},[2039],{"type":607,"value":2040},"provide an explicit denial path.",{"type":602,"tag":603,"props":2042,"children":2043},{},[2044,2046,2051,2052,2057,2058,2063,2065,2070],{"type":607,"value":2045},"Use the existing Better Auth session, CSRF, and origin protections. Serve both pages with ",{"type":602,"tag":622,"props":2047,"children":2048},{},[2049],{"type":607,"value":2050},"Cache-Control: no-store",{"type":607,"value":1431},{"type":602,"tag":622,"props":2053,"children":2054},{},[2055],{"type":607,"value":2056},"Content-Security-Policy: frame-ancestors 'none'",{"type":607,"value":1431},{"type":602,"tag":622,"props":2059,"children":2060},{},[2061],{"type":607,"value":2062},"X-Frame-Options: DENY",{"type":607,"value":2064},", and ",{"type":602,"tag":622,"props":2066,"children":2067},{},[2068],{"type":607,"value":2069},"Referrer-Policy: strict-origin",{"type":607,"value":2071},". This preserves an exact same-origin POST check while sending only the origin—not the transaction path—as Referer. Never render a client name, redirect URI, resource, or scope copied only from the browser URL.",{"type":602,"tag":653,"props":2073,"children":2075},{"id":2074},"verify-the-bearer-and-current-provider-grant-in-the-convex-action",[2076],{"type":607,"value":2077},"Verify the bearer and current provider grant in the Convex action",{"type":602,"tag":603,"props":2079,"children":2080},{},[2081,2083,2087,2089,2094],{"type":607,"value":2082},"The Convex ",{"type":602,"tag":622,"props":2084,"children":2085},{},[2086],{"type":607,"value":1527},{"type":607,"value":2088}," HTTP action accepts the bearer only from the ",{"type":602,"tag":622,"props":2090,"children":2091},{},[2092],{"type":607,"value":2093},"Authorization",{"type":607,"value":2095}," header. Keep the delegated scopes in one application-owned constant and use it for provider configuration, resource metadata, verification, and transaction validators. The package verifier combines official JOSE\u002FJWKS processing with Better Convex Nuxt's exact claim checks, while the existing auth component owns current Better Auth authority:",{"type":602,"tag":603,"props":2097,"children":2098},{},[2099,2101,2106,2108,2114],{"type":607,"value":2100},"Create ",{"type":602,"tag":622,"props":2102,"children":2103},{},[2104],{"type":607,"value":2105},"convex\u002Fmcp\u002Fscopes.ts",{"type":607,"value":2107}," once using the exact module in\n",{"type":602,"tag":610,"props":2109,"children":2111},{"href":2110},"\u002Fdocs\u002Fbuild\u002Fagents\u002Fmcp#configure-one-scope-authority",[2112],{"type":607,"value":2113},"Configure one scope authority",{"type":607,"value":651},{"type":602,"tag":787,"props":2116,"children":2118},{"language":1011,"filename":2117,"class":790},"convex\u002Fmcp.ts",[2119],{"type":602,"tag":622,"props":2120,"children":2121},{"class":1016},[2122,2134,2135,2147,2148,2160,2161,2179,2180,2183,2184,2219,2220,2249,2250,2279,2280,2283,2284,2326,2327,2364,2365,2405,2406,2409,2410,2427,2428,2445,2446,2481,2482,2500,2501,2569,2570,2578,2579],{"type":602,"tag":797,"props":2123,"children":2124},{"class":799,"style":800},[2125,2130],{"type":602,"tag":797,"props":2126,"children":2127},{"style":1023},[2128],{"type":607,"value":2129},"import",{"type":602,"tag":797,"props":2131,"children":2132},{"style":1039},[2133],{"type":607,"value":1082},{"type":607,"value":1044},{"type":602,"tag":797,"props":2136,"children":2137},{"class":799,"style":800},[2138,2143],{"type":602,"tag":797,"props":2139,"children":2140},{"style":1050},[2141],{"type":607,"value":2142},"  createBetterAuthMcpAccessVerifier",{"type":602,"tag":797,"props":2144,"children":2145},{"style":1039},[2146],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":2149,"children":2150},{"class":799,"style":800},[2151,2156],{"type":602,"tag":797,"props":2152,"children":2153},{"style":1050},[2154],{"type":607,"value":2155},"  requireAuthOrigin",{"type":602,"tag":797,"props":2157,"children":2158},{"style":1039},[2159],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":2162,"children":2163},{"class":799,"style":800},[2164,2169,2174],{"type":602,"tag":797,"props":2165,"children":2166},{"style":1039},[2167],{"type":607,"value":2168},"} ",{"type":602,"tag":797,"props":2170,"children":2171},{"style":1023},[2172],{"type":607,"value":2173},"from",{"type":602,"tag":797,"props":2175,"children":2176},{"style":810},[2177],{"type":607,"value":2178}," '@lupinum\u002Fbetter-convex-nuxt\u002Fconvex-auth'",{"type":607,"value":1044},{"type":602,"tag":797,"props":2181,"children":2182},{"class":799,"style":800},[],{"type":607,"value":1044},{"type":602,"tag":797,"props":2185,"children":2186},{"class":799,"style":800},[2187,2191,2196,2200,2205,2210,2214],{"type":602,"tag":797,"props":2188,"children":2189},{"style":1023},[2190],{"type":607,"value":2129},{"type":602,"tag":797,"props":2192,"children":2193},{"style":1023},[2194],{"type":607,"value":2195}," type",{"type":602,"tag":797,"props":2197,"children":2198},{"style":1039},[2199],{"type":607,"value":1168},{"type":602,"tag":797,"props":2201,"children":2202},{"style":1050},[2203],{"type":607,"value":2204},"ActionCtx",{"type":602,"tag":797,"props":2206,"children":2207},{"style":1039},[2208],{"type":607,"value":2209}," } ",{"type":602,"tag":797,"props":2211,"children":2212},{"style":1023},[2213],{"type":607,"value":2173},{"type":602,"tag":797,"props":2215,"children":2216},{"style":810},[2217],{"type":607,"value":2218}," '.\u002F_generated\u002Fserver'",{"type":607,"value":1044},{"type":602,"tag":797,"props":2221,"children":2222},{"class":799,"style":800},[2223,2227,2231,2236,2240,2244],{"type":602,"tag":797,"props":2224,"children":2225},{"style":1023},[2226],{"type":607,"value":2129},{"type":602,"tag":797,"props":2228,"children":2229},{"style":1039},[2230],{"type":607,"value":1168},{"type":602,"tag":797,"props":2232,"children":2233},{"style":1050},[2234],{"type":607,"value":2235},"authComponent",{"type":602,"tag":797,"props":2237,"children":2238},{"style":1039},[2239],{"type":607,"value":2209},{"type":602,"tag":797,"props":2241,"children":2242},{"style":1023},[2243],{"type":607,"value":2173},{"type":602,"tag":797,"props":2245,"children":2246},{"style":810},[2247],{"type":607,"value":2248}," '.\u002Fauth'",{"type":607,"value":1044},{"type":602,"tag":797,"props":2251,"children":2252},{"class":799,"style":800},[2253,2257,2261,2266,2270,2274],{"type":602,"tag":797,"props":2254,"children":2255},{"style":1023},[2256],{"type":607,"value":2129},{"type":602,"tag":797,"props":2258,"children":2259},{"style":1039},[2260],{"type":607,"value":1168},{"type":602,"tag":797,"props":2262,"children":2263},{"style":1050},[2264],{"type":607,"value":2265},"MCP_SCOPES",{"type":602,"tag":797,"props":2267,"children":2268},{"style":1039},[2269],{"type":607,"value":2209},{"type":602,"tag":797,"props":2271,"children":2272},{"style":1023},[2273],{"type":607,"value":2173},{"type":602,"tag":797,"props":2275,"children":2276},{"style":810},[2277],{"type":607,"value":2278}," '.\u002Fmcp\u002Fscopes'",{"type":607,"value":1044},{"type":602,"tag":797,"props":2281,"children":2282},{"class":799,"style":800},[],{"type":607,"value":1044},{"type":602,"tag":797,"props":2285,"children":2286},{"class":799,"style":800},[2287,2291,2297,2302,2307,2312,2316,2321],{"type":602,"tag":797,"props":2288,"children":2289},{"style":1023},[2290],{"type":607,"value":1026},{"type":602,"tag":797,"props":2292,"children":2294},{"style":2293},"color:#0000FF;--shiki-dark:#569CD6",[2295],{"type":607,"value":2296}," function",{"type":602,"tag":797,"props":2298,"children":2299},{"style":804},[2300],{"type":607,"value":2301}," createMcpVerifier",{"type":602,"tag":797,"props":2303,"children":2304},{"style":1039},[2305],{"type":607,"value":2306},"(",{"type":602,"tag":797,"props":2308,"children":2309},{"style":1050},[2310],{"type":607,"value":2311},"ctx",{"type":602,"tag":797,"props":2313,"children":2314},{"style":1039},[2315],{"type":607,"value":1376},{"type":602,"tag":797,"props":2317,"children":2319},{"style":2318},"color:#267F99;--shiki-dark:#4EC9B0",[2320],{"type":607,"value":2204},{"type":602,"tag":797,"props":2322,"children":2323},{"style":1039},[2324],{"type":607,"value":2325},") {",{"type":607,"value":1044},{"type":602,"tag":797,"props":2328,"children":2329},{"class":799,"style":800},[2330,2335,2340,2345,2350,2354,2359],{"type":602,"tag":797,"props":2331,"children":2332},{"style":2293},[2333],{"type":607,"value":2334},"  const",{"type":602,"tag":797,"props":2336,"children":2337},{"style":1112},[2338],{"type":607,"value":2339}," origin",{"type":602,"tag":797,"props":2341,"children":2342},{"style":1039},[2343],{"type":607,"value":2344}," = ",{"type":602,"tag":797,"props":2346,"children":2347},{"style":804},[2348],{"type":607,"value":2349},"requireAuthOrigin",{"type":602,"tag":797,"props":2351,"children":2352},{"style":1039},[2353],{"type":607,"value":2306},{"type":602,"tag":797,"props":2355,"children":2356},{"style":810},[2357],{"type":607,"value":2358},"'SITE_URL'",{"type":602,"tag":797,"props":2360,"children":2361},{"style":1039},[2362],{"type":607,"value":2363},")",{"type":607,"value":1044},{"type":602,"tag":797,"props":2366,"children":2367},{"class":799,"style":800},[2368,2372,2377,2381,2386,2391,2396,2400],{"type":602,"tag":797,"props":2369,"children":2370},{"style":2293},[2371],{"type":607,"value":2334},{"type":602,"tag":797,"props":2373,"children":2374},{"style":1112},[2375],{"type":607,"value":2376}," issuer",{"type":602,"tag":797,"props":2378,"children":2379},{"style":1039},[2380],{"type":607,"value":2344},{"type":602,"tag":797,"props":2382,"children":2383},{"style":810},[2384],{"type":607,"value":2385},"`",{"type":602,"tag":797,"props":2387,"children":2388},{"style":2293},[2389],{"type":607,"value":2390},"${",{"type":602,"tag":797,"props":2392,"children":2393},{"style":1050},[2394],{"type":607,"value":2395},"origin",{"type":602,"tag":797,"props":2397,"children":2398},{"style":2293},[2399],{"type":607,"value":1472},{"type":602,"tag":797,"props":2401,"children":2402},{"style":810},[2403],{"type":607,"value":2404},"\u002Fapi\u002Fauth`",{"type":607,"value":1044},{"type":602,"tag":797,"props":2407,"children":2408},{"class":799,"style":800},[],{"type":607,"value":1044},{"type":602,"tag":797,"props":2411,"children":2412},{"class":799,"style":800},[2413,2418,2423],{"type":602,"tag":797,"props":2414,"children":2415},{"style":1023},[2416],{"type":607,"value":2417},"  return",{"type":602,"tag":797,"props":2419,"children":2420},{"style":804},[2421],{"type":607,"value":2422}," createBetterAuthMcpAccessVerifier",{"type":602,"tag":797,"props":2424,"children":2425},{"style":1039},[2426],{"type":607,"value":1042},{"type":607,"value":1044},{"type":602,"tag":797,"props":2429,"children":2430},{"class":799,"style":800},[2431,2436,2441],{"type":602,"tag":797,"props":2432,"children":2433},{"style":1050},[2434],{"type":607,"value":2435},"    allowedScopes:",{"type":602,"tag":797,"props":2437,"children":2438},{"style":1112},[2439],{"type":607,"value":2440}," MCP_SCOPES",{"type":602,"tag":797,"props":2442,"children":2443},{"style":1039},[2444],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":2447,"children":2448},{"class":799,"style":800},[2449,2454,2459,2463,2468,2472,2477],{"type":602,"tag":797,"props":2450,"children":2451},{"style":1050},[2452],{"type":607,"value":2453},"    jwksUrl:",{"type":602,"tag":797,"props":2455,"children":2456},{"style":810},[2457],{"type":607,"value":2458}," `",{"type":602,"tag":797,"props":2460,"children":2461},{"style":2293},[2462],{"type":607,"value":2390},{"type":602,"tag":797,"props":2464,"children":2465},{"style":1050},[2466],{"type":607,"value":2467},"issuer",{"type":602,"tag":797,"props":2469,"children":2470},{"style":2293},[2471],{"type":607,"value":1472},{"type":602,"tag":797,"props":2473,"children":2474},{"style":810},[2475],{"type":607,"value":2476},"\u002Fjwks`",{"type":602,"tag":797,"props":2478,"children":2479},{"style":1039},[2480],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":2483,"children":2484},{"class":799,"style":800},[2485,2490,2496],{"type":602,"tag":797,"props":2486,"children":2487},{"style":1050},[2488],{"type":607,"value":2489},"    maxLifetimeSeconds:",{"type":602,"tag":797,"props":2491,"children":2493},{"style":2492},"color:#098658;--shiki-dark:#B5CEA8",[2494],{"type":607,"value":2495}," 600",{"type":602,"tag":797,"props":2497,"children":2498},{"style":1039},[2499],{"type":607,"value":1120},{"type":607,"value":1044},{"type":602,"tag":797,"props":2502,"children":2503},{"class":799,"style":800},[2504,2509,2514,2519,2524,2529,2534,2539,2543,2548,2552,2556,2560,2564],{"type":602,"tag":797,"props":2505,"children":2506},{"style":804},[2507],{"type":607,"value":2508},"    validateLiveAccess",{"type":602,"tag":797,"props":2510,"children":2511},{"style":1050},[2512],{"type":607,"value":2513},":",{"type":602,"tag":797,"props":2515,"children":2516},{"style":1039},[2517],{"type":607,"value":2518}," (",{"type":602,"tag":797,"props":2520,"children":2521},{"style":1050},[2522],{"type":607,"value":2523},"access",{"type":602,"tag":797,"props":2525,"children":2526},{"style":1039},[2527],{"type":607,"value":2528},") ",{"type":602,"tag":797,"props":2530,"children":2531},{"style":2293},[2532],{"type":607,"value":2533},"=>",{"type":602,"tag":797,"props":2535,"children":2536},{"style":1050},[2537],{"type":607,"value":2538}," authComponent",{"type":602,"tag":797,"props":2540,"children":2541},{"style":1039},[2542],{"type":607,"value":651},{"type":602,"tag":797,"props":2544,"children":2545},{"style":804},[2546],{"type":607,"value":2547},"validateOAuthAccess",{"type":602,"tag":797,"props":2549,"children":2550},{"style":1039},[2551],{"type":607,"value":2306},{"type":602,"tag":797,"props":2553,"children":2554},{"style":1050},[2555],{"type":607,"value":2311},{"type":602,"tag":797,"props":2557,"children":2558},{"style":1039},[2559],{"type":607,"value":1431},{"type":602,"tag":797,"props":2561,"children":2562},{"style":1050},[2563],{"type":607,"value":2523},{"type":602,"tag":797,"props":2565,"children":2566},{"style":1039},[2567],{"type":607,"value":2568},"),",{"type":607,"value":1044},{"type":602,"tag":797,"props":2571,"children":2572},{"class":799,"style":800},[2573],{"type":602,"tag":797,"props":2574,"children":2575},{"style":1039},[2576],{"type":607,"value":2577},"  })",{"type":607,"value":1044},{"type":602,"tag":797,"props":2580,"children":2581},{"class":799,"style":800},[2582],{"type":602,"tag":797,"props":2583,"children":2584},{"style":1039},[2585],{"type":607,"value":1472},{"type":602,"tag":603,"props":2587,"children":2588},{},[2589,2591,2596,2598,2603,2605,2609],{"type":607,"value":2590},"Pass that request-local verifier under ",{"type":602,"tag":622,"props":2592,"children":2593},{},[2594],{"type":607,"value":2595},"authorization.verifier",{"type":607,"value":2597}," in ",{"type":602,"tag":622,"props":2599,"children":2600},{},[2601],{"type":607,"value":2602},"handleMcpRequest",{"type":607,"value":2604},". The MCP boundary supplies the exact issuer and resource to the verifier, so neither is configured twice. The verifier requires RS256, ",{"type":602,"tag":622,"props":2606,"children":2607},{},[2608],{"type":607,"value":1731},{"type":607,"value":2610},", the OAuth access-token class, the exact scalar issuer and audience, matching client\u002Fauthorized-party claims, subject, session, bounded timestamps, and allowlisted scopes. A Convex session token, ID token, array audience, foreign resource, or unknown claim is rejected.",{"type":602,"tag":603,"props":2612,"children":2613},{},[2614],{"type":607,"value":2615},"After verification, keep only the narrow subject, session ID, client ID, resource, and scopes in action memory. Map the MCP method through a closed tool allowlist to one tool-specific internal Convex function. Never pass the raw token, a caller-supplied principal, or a caller-selected function to a public Convex query\u002Fmutation.",{"type":602,"tag":653,"props":2617,"children":2619},{"id":2618},"keep-authorization-live-in-convex",[2620],{"type":607,"value":2621},"Keep authorization live in Convex",{"type":602,"tag":603,"props":2623,"children":2624},{},[2625,2627,2632],{"type":607,"value":2626},"Scopes and consent are ceilings. ",{"type":602,"tag":622,"props":2628,"children":2629},{},[2630],{"type":607,"value":2631},"authComponent.validateOAuthAccess(ctx, access)",{"type":607,"value":2633}," re-reads the provider-owned session, user, OAuth client, resource, client-resource link, consent, and scope grants. Each tool-specific internal mutation calls it again, then reads only the application-owned:",{"type":602,"tag":1652,"props":2635,"children":2636},{},[2637,2642,2647],{"type":602,"tag":1656,"props":2638,"children":2639},{},[2640],{"type":607,"value":2641},"application user, organization membership, role, and delegation;",{"type":602,"tag":1656,"props":2643,"children":2644},{},[2645],{"type":607,"value":2646},"requested resource ownership and product capability;",{"type":602,"tag":1656,"props":2648,"children":2649},{},[2650],{"type":607,"value":2651},"operation-specific rate limit and any destructive-action approval.",{"type":602,"tag":603,"props":2653,"children":2654},{},[2655],{"type":607,"value":2656},"Perform those checks and the state change in the same Convex transaction. Removing a membership, delegation, session, client, resource link, or consent must deny the next tool call even when the access token has not expired.",{"type":602,"tag":603,"props":2658,"children":2659},{},[2660],{"type":607,"value":2661},"Provider semantics distinguish disabling from deletion: disabling an OAuth resource blocks new issuance but does not revoke an already-issued token. Delete the resource or its client link to invalidate existing access. If your product wants disable-as-immediate-revocation, add that stronger rule explicitly to application policy.",{"type":602,"tag":603,"props":2663,"children":2664},{},[2665],{"type":607,"value":2666},"The self-contained access token can otherwise remain a valid bearer until its maximum ten-minute expiry. Do not describe the provider's individual-token revocation response as an immediate JWT blacklist.",{"type":602,"tag":603,"props":2668,"children":2669},{},[2670],{"type":607,"value":2671},"Return a resource challenge for missing\u002Finvalid tokens and insufficient scopes:",{"type":602,"tag":787,"props":2673,"children":2674},{"language":607,"class":790},[2675],{"type":602,"tag":622,"props":2676,"children":2678},{"class":2677},"language-text",[2679],{"type":602,"tag":797,"props":2680,"children":2681},{"class":799,"style":800},[2682],{"type":602,"tag":797,"props":2683,"children":2684},{},[2685],{"type":607,"value":2686},"WWW-Authenticate: Bearer resource_metadata=\"https:\u002F\u002Fdeployment.convex.site\u002F.well-known\u002Foauth-protected-resource\u002Fmcp\"",{"type":602,"tag":603,"props":2688,"children":2689},{},[2690,2692,2697,2699,2704],{"type":607,"value":2691},"Add ",{"type":602,"tag":622,"props":2693,"children":2694},{},[2695],{"type":607,"value":2696},"scope=\"mcp:read\"",{"type":607,"value":2698}," or ",{"type":602,"tag":622,"props":2700,"children":2701},{},[2702],{"type":607,"value":2703},"scope=\"mcp:write\"",{"type":607,"value":2705}," only when the rejected operation has that concrete requirement.",{"type":602,"tag":653,"props":2707,"children":2709},{"id":2708},"provision-the-signing-key-before-traffic",[2710],{"type":607,"value":2711},"Provision the signing key before traffic",{"type":602,"tag":603,"props":2713,"children":2714},{},[2715,2717,2721],{"type":607,"value":2716},"Do not let the first public token request create signing-key state. Export the internal operator action beside ",{"type":602,"tag":622,"props":2718,"children":2719},{},[2720],{"type":607,"value":719},{"type":607,"value":2513},{"type":602,"tag":787,"props":2723,"children":2725},{"language":1011,"filename":2724,"class":790},"convex\u002Fauth.ts",[2726],{"type":602,"tag":622,"props":2727,"children":2728},{"class":1016},[2729],{"type":602,"tag":797,"props":2730,"children":2731},{"class":799,"style":800},[2732,2736,2741,2745,2750,2755,2759,2763,2768,2772,2776],{"type":602,"tag":797,"props":2733,"children":2734},{"style":1023},[2735],{"type":607,"value":1026},{"type":602,"tag":797,"props":2737,"children":2738},{"style":2293},[2739],{"type":607,"value":2740}," const",{"type":602,"tag":797,"props":2742,"children":2743},{"style":1039},[2744],{"type":607,"value":1168},{"type":602,"tag":797,"props":2746,"children":2747},{"style":1112},[2748],{"type":607,"value":2749},"rotateSigningKey",{"type":602,"tag":797,"props":2751,"children":2752},{"style":1039},[2753],{"type":607,"value":2754}," } = ",{"type":602,"tag":797,"props":2756,"children":2757},{"style":1050},[2758],{"type":607,"value":2235},{"type":602,"tag":797,"props":2760,"children":2761},{"style":1039},[2762],{"type":607,"value":651},{"type":602,"tag":797,"props":2764,"children":2765},{"style":804},[2766],{"type":607,"value":2767},"jwksOperatorFunctions",{"type":602,"tag":797,"props":2769,"children":2770},{"style":1039},[2771],{"type":607,"value":2306},{"type":602,"tag":797,"props":2773,"children":2774},{"style":1050},[2775],{"type":607,"value":719},{"type":602,"tag":797,"props":2777,"children":2778},{"style":1039},[2779],{"type":607,"value":2363},{"type":602,"tag":603,"props":2781,"children":2782},{},[2783],{"type":607,"value":2784},"After the final schema, functions, secrets, and HTTP routes are deployed—but before auth or OAuth traffic is admitted—run it with deployment-admin tooling:",{"type":602,"tag":787,"props":2786,"children":2787},{"language":789,"class":790},[2788],{"type":602,"tag":622,"props":2789,"children":2790},{"class":794},[2791],{"type":602,"tag":797,"props":2792,"children":2793},{"class":799,"style":800},[2794,2798,2803,2808,2813,2818],{"type":602,"tag":797,"props":2795,"children":2796},{"style":804},[2797],{"type":607,"value":807},{"type":602,"tag":797,"props":2799,"children":2800},{"style":810},[2801],{"type":607,"value":2802}," exec",{"type":602,"tag":797,"props":2804,"children":2805},{"style":810},[2806],{"type":607,"value":2807}," better-convex-nuxt-convex",{"type":602,"tag":797,"props":2809,"children":2810},{"style":810},[2811],{"type":607,"value":2812}," run",{"type":602,"tag":797,"props":2814,"children":2815},{"style":810},[2816],{"type":607,"value":2817}," auth:rotateSigningKey",{"type":602,"tag":797,"props":2819,"children":2820},{"style":810},[2821],{"type":607,"value":2822}," '{}'",{"type":602,"tag":603,"props":2824,"children":2825},{},[2826,2828,2833,2835,2840,2841,2846,2847,2852,2854,2859],{"type":607,"value":2827},"For a fresh environment, require ",{"type":602,"tag":622,"props":2829,"children":2830},{},[2831],{"type":607,"value":2832},"previousKids",{"type":607,"value":2834}," to be empty and record the returned ",{"type":602,"tag":622,"props":2836,"children":2837},{},[2838],{"type":607,"value":2839},"newKid",{"type":607,"value":1431},{"type":602,"tag":622,"props":2842,"children":2843},{},[2844],{"type":607,"value":2845},"rotatedAt",{"type":607,"value":2064},{"type":602,"tag":622,"props":2848,"children":2849},{},[2850],{"type":607,"value":2851},"previousVerifyUntil",{"type":607,"value":2853},". After Nuxt is deployed behind a closed traffic gate, verify the new ID appears at the public ",{"type":602,"tag":622,"props":2855,"children":2856},{},[2857],{"type":607,"value":2858},"\u002Fapi\u002Fauth\u002Fjwks",{"type":607,"value":2860}," endpoint before opening ingress. The action returns bounded metadata only; it never returns private or public key rows. If a supposedly fresh deployment reports an earlier key, stop and inventory the environment instead of deleting data.",{"type":602,"tag":603,"props":2862,"children":2863},{},[2864],{"type":607,"value":2865},"Keep the action internal. Do not add a public HTTP route, public Convex wrapper, private-key export, or second current-key registry.",{"type":602,"tag":603,"props":2867,"children":2868},{},[2869],{"type":607,"value":2870},"Use the same action for later rotations. It generates an encrypted RS256 key through Better Auth, then one atomic Convex mutation inserts the new current key and retires keys current at commit time. The 21-minute verification grace covers the 15-minute Convex session-token lifetime, five-minute public JWKS cache, and one-minute clock allowance; it also exceeds the OAuth token lifetime. Concurrent rotations preserve every verification key through its full grace period.",{"type":602,"tag":603,"props":2872,"children":2873},{},[2874],{"type":607,"value":2875},"Never delete all JWKS rows. After a rotation:",{"type":602,"tag":1991,"props":2877,"children":2878},{},[2879,2890,2895,2906],{"type":602,"tag":1656,"props":2880,"children":2881},{},[2882,2884,2888],{"type":607,"value":2883},"verify the returned ",{"type":602,"tag":622,"props":2885,"children":2886},{},[2887],{"type":607,"value":2839},{"type":607,"value":2889}," is published;",{"type":602,"tag":1656,"props":2891,"children":2892},{},[2893],{"type":607,"value":2894},"verify new session and OAuth tokens use the new key;",{"type":602,"tag":1656,"props":2896,"children":2897},{},[2898,2900,2904],{"type":607,"value":2899},"retain prior keys through at least ",{"type":602,"tag":622,"props":2901,"children":2902},{},[2903],{"type":607,"value":2851},{"type":607,"value":2905}," and all cache\u002Ftoken bounds;",{"type":602,"tag":1656,"props":2907,"children":2908},{},[2909,2911,2916],{"type":607,"value":2910},"rotate ",{"type":602,"tag":622,"props":2912,"children":2913},{},[2914],{"type":607,"value":2915},"BETTER_AUTH_SECRETS",{"type":607,"value":2917}," separately, retaining every version needed to decrypt stored keys and other ciphertext until an inventory and decryption rehearsal passes.",{"type":602,"tag":653,"props":2919,"children":2921},{"id":2920},"deploy-and-recover-safely",[2922],{"type":607,"value":2923},"Deploy and recover safely",{"type":602,"tag":603,"props":2925,"children":2926},{},[2927],{"type":607,"value":2928},"Use an empty environment and keep public ingress closed until the complete profile is ready:",{"type":602,"tag":1991,"props":2930,"children":2931},{},[2932,2937,2948,2959,2970,2975,2986],{"type":602,"tag":1656,"props":2933,"children":2934},{},[2935],{"type":607,"value":2936},"install the exact tuple and generate the final packaged or local schema\u002Fmetadata pair;",{"type":602,"tag":1656,"props":2938,"children":2939},{},[2940,2942,2947],{"type":607,"value":2941},"set the exact Nuxt\u002FConvex origins and independent secrets described in ",{"type":602,"tag":610,"props":2943,"children":2944},{"href":565},[2945],{"type":607,"value":2946},"environment variables",{"type":607,"value":1739},{"type":602,"tag":1656,"props":2949,"children":2950},{},[2951,2953,2957],{"type":607,"value":2952},"deploy the single ",{"type":602,"tag":622,"props":2954,"children":2955},{},[2956],{"type":607,"value":972},{"type":607,"value":2958}," component, application schema, functions, and HTTP routes;",{"type":602,"tag":1656,"props":2960,"children":2961},{},[2962,2964,2968],{"type":607,"value":2963},"run the pre-traffic ",{"type":602,"tag":622,"props":2965,"children":2966},{},[2967],{"type":607,"value":2749},{"type":607,"value":2969}," ceremony and require the fresh-environment metadata shape;",{"type":602,"tag":1656,"props":2971,"children":2972},{},[2973],{"type":607,"value":2974},"deploy Nuxt behind a closed traffic gate and verify the returned key through public JWKS;",{"type":602,"tag":1656,"props":2976,"children":2977},{},[2978,2980,2984],{"type":607,"value":2979},"use the provider-owned admin flow to create and verify the ",{"type":602,"tag":622,"props":2981,"children":2982},{},[2983],{"type":607,"value":1527},{"type":607,"value":2985}," resource, clients, and resource links, then verify both metadata documents, login, consent, PKCE, wrong-client\u002Fresource\u002Fscope denial, and live authorization revocation;",{"type":602,"tag":1656,"props":2987,"children":2988},{},[2989],{"type":607,"value":2990},"admit public traffic only after those checks pass.",{"type":602,"tag":603,"props":2992,"children":2993},{},[2994],{"type":607,"value":2995},"Before public traffic, discard and recreate a disposable environment if provisioning is incomplete. After users, clients, consent, or audit state exist, preserve that state and forward-fix. Do not attach an older auth runtime, restore an incompatible schema, run an identity conversion, mount a second component, or delete JWKS\u002FOAuth rows to simulate rollback.",{"type":602,"tag":603,"props":2997,"children":2998},{},[2999],{"type":607,"value":3000},"To contain a delegated-access incident, disable the affected provider-owned clients\u002Fresources and the public MCP route, preserve evidence, and ship a reviewed fix through the normal immutable release path. Roll back only to an already tested artifact that uses the identical schema and security profile; otherwise deploy a new fixed artifact.",{"type":602,"tag":603,"props":3002,"children":3003},{},[3004,3006,3011,3012,3017],{"type":607,"value":3005},"Continue with the ",{"type":602,"tag":610,"props":3007,"children":3008},{"href":571},[3009],{"type":607,"value":3010},"deployment checklist",{"type":607,"value":745},{"type":602,"tag":610,"props":3013,"children":3014},{"href":577},[3015],{"type":607,"value":3016},"security model",{"type":607,"value":651},{"type":602,"tag":653,"props":3019,"children":3021},{"id":3020},"disabled-beta-capabilities",[3022],{"type":607,"value":3023},"Disabled beta capabilities",{"type":602,"tag":603,"props":3025,"children":3026},{},[3027],{"type":607,"value":3028},"The public metadata and raw routes must not advertise or enable:",{"type":602,"tag":1652,"props":3030,"children":3031},{},[3032,3043,3048,3053,3058,3063,3078],{"type":602,"tag":1656,"props":3033,"children":3034},{},[3035,3037,3042],{"type":607,"value":3036},"refresh tokens or ",{"type":602,"tag":622,"props":3038,"children":3039},{},[3040],{"type":607,"value":3041},"offline_access",{"type":607,"value":1739},{"type":602,"tag":1656,"props":3044,"children":3045},{},[3046],{"type":607,"value":3047},"dynamic\u002Funauthenticated registration or Client ID Metadata Documents;",{"type":602,"tag":1656,"props":3049,"children":3050},{},[3051],{"type":607,"value":3052},"client credentials, implicit, password, device, or assertion grants;",{"type":602,"tag":1656,"props":3054,"children":3055},{},[3056],{"type":607,"value":3057},"DPoP, PAR, JAR, request objects, or multi-resource access tokens;",{"type":602,"tag":1656,"props":3059,"children":3060},{},[3061],{"type":607,"value":3062},"introspection, UserInfo, end-session, or OIDC discovery\u002FID tokens;",{"type":602,"tag":1656,"props":3064,"children":3065},{},[3066,3068,3072,3073,3077],{"type":607,"value":3067},"Better Auth provider-token export through ",{"type":602,"tag":622,"props":3069,"children":3070},{},[3071],{"type":607,"value":1713},{"type":607,"value":2698},{"type":602,"tag":622,"props":3074,"children":3075},{},[3076],{"type":607,"value":1719},{"type":607,"value":1739},{"type":602,"tag":1656,"props":3079,"children":3080},{},[3081],{"type":607,"value":3082},"outbound OIDC identity-provider or enterprise workforce SSO behavior.",{"type":602,"tag":603,"props":3084,"children":3085},{},[3086,3088,3093],{"type":607,"value":3087},"Do not turn on one of these features to accommodate a client. Treat it as a new security design requiring its own schema, protocol, threat-model, interoperability, and release review. See ",{"type":602,"tag":610,"props":3089,"children":3090},{"href":54},[3091],{"type":607,"value":3092},"limitations and trade-offs",{"type":607,"value":651},{"type":602,"tag":653,"props":3095,"children":3097},{"id":3096},"verify-the-profile",[3098],{"type":607,"value":3099},"Verify the profile",{"type":602,"tag":603,"props":3101,"children":3102},{},[3103],{"type":607,"value":3104},"For an application deployment, test the real public origin with at least two users and the actual preregistered clients. Exercise consent denial, exact redirect and resource binding, missing\u002Fwrong scopes, session\u002Fclient\u002Fconsent\u002Fmembership revocation, tenant crossover, destructive approval, key rotation, restart, and token expiry.",{"type":602,"tag":603,"props":3106,"children":3107},{},[3108],{"type":607,"value":3109},"Repository changes to this profile run these focused gates:",{"type":602,"tag":665,"props":3111,"children":3112},{},[3113,3129],{"type":602,"tag":669,"props":3114,"children":3115},{},[3116],{"type":602,"tag":673,"props":3117,"children":3118},{},[3119,3124],{"type":602,"tag":677,"props":3120,"children":3121},{},[3122],{"type":607,"value":3123},"Command",{"type":602,"tag":677,"props":3125,"children":3126},{},[3127],{"type":607,"value":3128},"Evidence",{"type":602,"tag":693,"props":3130,"children":3131},{},[3132,3148,3164,3180,3196,3212,3228,3244],{"type":602,"tag":673,"props":3133,"children":3134},{},[3135,3143],{"type":602,"tag":700,"props":3136,"children":3137},{},[3138],{"type":602,"tag":622,"props":3139,"children":3140},{},[3141],{"type":607,"value":3142},"pnpm check:auth-schema",{"type":602,"tag":700,"props":3144,"children":3145},{},[3146],{"type":607,"value":3147},"Fresh schema, metadata, codegen, component mount, and first-deploy shape",{"type":602,"tag":673,"props":3149,"children":3150},{},[3151,3159],{"type":602,"tag":700,"props":3152,"children":3153},{},[3154],{"type":602,"tag":622,"props":3155,"children":3156},{},[3157],{"type":607,"value":3158},"pnpm test:oauth",{"type":602,"tag":700,"props":3160,"children":3161},{},[3162],{"type":607,"value":3163},"Discovery, PKCE, bindings, claims, replay, failures, and disabled routes",{"type":602,"tag":673,"props":3165,"children":3166},{},[3167,3175],{"type":602,"tag":700,"props":3168,"children":3169},{},[3170],{"type":602,"tag":622,"props":3171,"children":3172},{},[3173],{"type":607,"value":3174},"pnpm test:mcp-auth",{"type":602,"tag":700,"props":3176,"children":3177},{},[3178],{"type":607,"value":3179},"Two direct preregistered public-client PKCE flows plus live MCP authorization",{"type":602,"tag":673,"props":3181,"children":3182},{},[3183,3191],{"type":602,"tag":700,"props":3184,"children":3185},{},[3186],{"type":602,"tag":622,"props":3187,"children":3188},{},[3189],{"type":607,"value":3190},"pnpm test:mcp-conformance",{"type":602,"tag":700,"props":3192,"children":3193},{},[3194],{"type":607,"value":3195},"Stable-SDK contract proof plus published 2025 protocol scenarios",{"type":602,"tag":673,"props":3197,"children":3198},{},[3199,3207],{"type":602,"tag":700,"props":3200,"children":3201},{},[3202],{"type":602,"tag":622,"props":3203,"children":3204},{},[3205],{"type":607,"value":3206},"pnpm test:auth-concurrency",{"type":602,"tag":700,"props":3208,"children":3209},{},[3210],{"type":607,"value":3211},"Real-backend atomics, rate limits, and concurrent JWKS rotation",{"type":602,"tag":673,"props":3213,"children":3214},{},[3215,3223],{"type":602,"tag":700,"props":3216,"children":3217},{},[3218],{"type":602,"tag":622,"props":3219,"children":3220},{},[3221],{"type":607,"value":3222},"pnpm test:auth-export-sentinels",{"type":602,"tag":700,"props":3224,"children":3225},{},[3226],{"type":607,"value":3227},"Real component export plus browser-persistence credential canaries",{"type":602,"tag":673,"props":3229,"children":3230},{},[3231,3239],{"type":602,"tag":700,"props":3232,"children":3233},{},[3234],{"type":602,"tag":622,"props":3235,"children":3236},{},[3237],{"type":607,"value":3238},"pnpm test:auth-fuzz",{"type":602,"tag":700,"props":3240,"children":3241},{},[3242],{"type":607,"value":3243},"Bounded hostile auth\u002FOAuth HTTP inputs",{"type":602,"tag":673,"props":3245,"children":3246},{},[3247,3255],{"type":602,"tag":700,"props":3248,"children":3249},{},[3250],{"type":602,"tag":622,"props":3251,"children":3252},{},[3253],{"type":607,"value":3254},"pnpm verify:auth",{"type":602,"tag":700,"props":3256,"children":3257},{},[3258],{"type":607,"value":3259},"Complete auth\u002FOAuth\u002FMCP repository gate",{"type":602,"tag":603,"props":3261,"children":3262},{},[3263,3268,3270,3275,3277,3282,3284,3289,3291,3295],{"type":602,"tag":622,"props":3264,"children":3265},{},[3266],{"type":607,"value":3267},"test:mcp-conformance",{"type":607,"value":3269}," uses the stable official ",{"type":602,"tag":622,"props":3271,"children":3272},{},[3273],{"type":607,"value":3274},"2.0.0",{"type":607,"value":3276}," client for the\n",{"type":602,"tag":622,"props":3278,"children":3279},{},[3280],{"type":607,"value":3281},"2026-07-28",{"type":607,"value":3283}," request envelope. The older official conformance package is retained\nonly for the published ",{"type":602,"tag":622,"props":3285,"children":3286},{},[3287],{"type":607,"value":3288},"2025-11-25",{"type":607,"value":3290}," initialize, ping, and tools-list scenarios\nbecause it advertises no ",{"type":602,"tag":622,"props":3292,"children":3293},{},[3294],{"type":607,"value":3281},{"type":607,"value":3296}," scenarios. Neither path certifies the OAuth\nauthorization server; keep MCP protocol evidence, direct PKCE interoperability,\nand independent OAuth security review as separate results.",{"title":3298,"searchDepth":3299,"depth":3299,"links":3300},"",4,[3301,3303,3304,3305,3306,3307,3308,3309,3310,3311,3312,3313,3314],{"id":655,"depth":3302,"text":658},2,{"id":777,"depth":3302,"text":780},{"id":959,"depth":3302,"text":962},{"id":1000,"depth":3302,"text":1003},{"id":1602,"depth":3302,"text":1605},{"id":1811,"depth":3302,"text":1814},{"id":1981,"depth":3302,"text":1984},{"id":2074,"depth":3302,"text":2077},{"id":2618,"depth":3302,"text":2621},{"id":2708,"depth":3302,"text":2711},{"id":2920,"depth":3302,"text":2923},{"id":3020,"depth":3302,"text":3023},{"id":3096,"depth":3302,"text":3099},"markdown","docs",{"source":3318,"path":3319,"stem":3320,"dir":3321,"extension":3322},"content","docs\u002F4.build\u002F3.authentication\u002F10.delegated-oauth-and-mcp.md","docs\u002F4.build\u002F3.authentication\u002F10.delegated-oauth-and-mcp","authentication","md",{"requestedPath":335,"resolvedPath":335,"alternates":3324},[],{"requested":3326,"resolved":3327,"usedFallback":6},{},{"locale":8},{"previous":3329,"next":3331},{"title":323,"id":324,"canonicalKey":325,"locale":8,"draft":6,"navigation":3330,"icon":327,"path":328},{"icon":327},{"title":341,"id":342,"canonicalKey":343,"locale":8,"draft":6,"navigation":3332,"icon":345,"path":346},{"icon":345},{"left":3334,"top":3334,"width":3335,"height":3336,"rotate":3334,"vFlip":6,"hFlip":6,"body":3337},0,256,168,"\u003Cpath fill=\"#00dc82\" d=\"M143.618 167.029h95.166c3.023 0 5.992-.771 8.61-2.237a16.96 16.96 0 0 0 6.302-6.115a16.3 16.3 0 0 0 2.304-8.352c0-2.932-.799-5.811-2.312-8.35L189.778 34.6a16.97 16.97 0 0 0-6.301-6.113a17.6 17.6 0 0 0-8.608-2.238c-3.023 0-5.991.772-8.609 2.238a16.96 16.96 0 0 0-6.3 6.113l-16.342 27.473l-31.95-53.724a17 17 0 0 0-6.304-6.112A17.64 17.64 0 0 0 96.754 0c-3.022 0-5.992.772-8.61 2.237a17 17 0 0 0-6.303 6.112L2.31 141.975a16.3 16.3 0 0 0-2.31 8.35c0 2.932.793 5.813 2.304 8.352a16.96 16.96 0 0 0 6.302 6.115a17.6 17.6 0 0 0 8.61 2.237h59.737c23.669 0 41.123-10.084 53.134-29.758l29.159-48.983l15.618-26.215l46.874 78.742h-62.492zm-67.64-26.24l-41.688-.01L96.782 35.796l31.181 52.492l-20.877 35.084c-7.976 12.765-17.037 17.416-31.107 17.416\"\u002F>",{"left":3334,"top":3334,"width":3339,"height":3339,"rotate":3334,"vFlip":6,"hFlip":6,"body":3340},24,"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 3H7a2 2 0 0 0-2 2v5a2 2 0 0 1-2 2a2 2 0 0 1 2 2v5c0 1.1.9 2 2 2h1m8 0h1a2 2 0 0 0 2-2v-5c0-1.1.9-2 2-2a2 2 0 0 1-2-2V5a2 2 0 0 0-2-2h-1\"\u002F>",{"left":3334,"top":3334,"width":3335,"height":3335,"rotate":3334,"vFlip":6,"hFlip":6,"body":3342},"\u003Cpath fill=\"#3178c6\" d=\"M20 0h216c11.046 0 20 8.954 20 20v216c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20V20C0 8.954 8.954 0 20 0\"\u002F>\u003Cpath fill=\"#fff\" d=\"M150.518 200.475v27.62q6.738 3.453 15.938 5.179T185.849 235q9.934 0 18.874-1.899t15.678-6.257q6.738-4.359 10.669-11.394q3.93-7.033 3.93-17.391q0-7.51-2.246-13.163a30.8 30.8 0 0 0-6.479-10.055q-4.232-4.402-10.149-7.898t-13.347-6.602q-5.442-2.245-9.761-4.359t-7.342-4.316q-3.024-2.2-4.665-4.661t-1.641-5.567q0-2.848 1.468-5.135q1.469-2.288 4.147-3.927t6.565-2.547q3.887-.906 8.638-.906q3.456 0 7.299.518q3.844.517 7.732 1.597a54 54 0 0 1 7.558 2.719a41.7 41.7 0 0 1 6.781 3.797v-25.807q-6.306-2.417-13.778-3.582T198.633 107q-9.847 0-18.658 2.115q-8.811 2.114-15.506 6.602q-6.694 4.49-10.582 11.437Q150 134.102 150 143.769q0 12.342 7.127 21.06t21.638 14.759a292 292 0 0 1 10.625 4.575q4.924 2.244 8.509 4.66t5.658 5.265t2.073 6.474a9.9 9.9 0 0 1-1.296 4.963q-1.295 2.287-3.93 3.97t-6.565 2.632t-9.2.95q-8.983 0-17.794-3.151t-16.327-9.451m-46.036-68.733H140V109H41v22.742h35.345V233h28.137z\"\u002F>",{"left":3334,"top":3334,"width":3339,"height":3339,"rotate":3334,"vFlip":6,"hFlip":6,"body":3344},"\u003Cpath fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 19h8M4 17l6-6l-6-6\"\u002F>",{"left":3334,"top":3334,"width":3339,"height":3339,"rotate":3334,"vFlip":6,"hFlip":6,"body":3346},"\u003Cg fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\">\u003Crect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"\u002F>\u003Cpath d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"\u002F>\u003C\u002Fg>",1786627518246]