diff --git a/.claude/reference/feature-flags.md b/.claude/reference/feature-flags.md
index 0d74bd969b..dbe9dd3f50 100644
--- a/.claude/reference/feature-flags.md
+++ b/.claude/reference/feature-flags.md
@@ -33,6 +33,7 @@ if (features.platform) {
| `branding` | Rivet branding chrome. |
| `datacenter` | Datacenter-related UI. |
| `danger-zone` | Destructive settings actions (`features.dangerZone`). |
+| `mcp` | MCP connection settings card on the namespace settings drawer. Flavor-dependent content: `platform` renders the hosted `mcp.rivet.dev` endpoint pinned to this namespace, everything else renders the local stdio (`npx @rivet-dev/mcp`) config. |
Deployment flavors map to flag sets roughly as: **cloud** = all on; **OSS** = `auth`/`platform`/`acl` off; **enterprise** = `acl` on, `auth`/`platform` off (engine enforces auth without a login UI). Do not treat `platform`/`auth` as "engine requires credentials" — that is `acl`. **`compute` is opt-in even on cloud** — each Railway service adds it to `VITE_FEATURE_FLAGS` per-environment (e.g. staging on, prod off) rather than inheriting the cloud default-on set.
@@ -48,15 +49,18 @@ Switch flavors in dev without restarting the server by setting the `localStorage
// OSS self-host: everything off
localStorage.setItem("FEATURE_FLAGS", ""); location.reload();
+// OSS self-host with the local MCP snippet shown
+localStorage.setItem("FEATURE_FLAGS", "mcp"); location.reload();
+
// Full cloud: all flags on (see the commented canonical list in frontend/.env.local)
localStorage.setItem(
"FEATURE_FLAGS",
- "compute,platform,acl,auth,captcha,branding,support,billing,datacenter,danger-zone,multitenancy",
+ "compute,platform,acl,auth,captcha,branding,support,billing,datacenter,danger-zone,multitenancy,mcp",
);
location.reload();
// Enterprise: acl on, no login UI
-localStorage.setItem("FEATURE_FLAGS", "acl,branding,support,datacenter,danger-zone"); location.reload();
+localStorage.setItem("FEATURE_FLAGS", "acl,branding,support,datacenter,danger-zone,mcp"); location.reload();
```
In an agent-browser / DevTools session, paste those into the page console. `localStorage` persists across reloads, so run `localStorage.removeItem("FEATURE_FLAGS")` to return to the env default when finished. Confirm the active flavor with `JSON.stringify(features)` after importing, or just observe whether auth/cloud chrome is present.
diff --git a/frontend/apps/inspector-ui/mcp-index.html b/frontend/apps/inspector-ui/mcp-index.html
new file mode 100644
index 0000000000..0aaa4e8a72
--- /dev/null
+++ b/frontend/apps/inspector-ui/mcp-index.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+ Rivet Actor Inspector
+
+
+
+
+
+
+
diff --git a/frontend/apps/inspector-ui/src/main.tsx b/frontend/apps/inspector-ui/src/main.tsx
index ef56887310..171ecd5588 100644
--- a/frontend/apps/inspector-ui/src/main.tsx
+++ b/frontend/apps/inspector-ui/src/main.tsx
@@ -62,32 +62,65 @@ function InspectorContent({
actorId,
activeTab,
bridge,
+ standalone = false,
}: {
actorId: ActorId;
activeTab: string | undefined;
- bridge: BridgeClient;
+ bridge?: BridgeClient;
+ standalone?: boolean;
}) {
const availableTabs = useAvailableInspectorTabs(actorId);
+ const [standaloneTab, setStandaloneTab] = useState();
useEffect(() => {
- if (availableTabs) bridge.sendTabsAvailable(availableTabs);
+ if (availableTabs) bridge?.sendTabsAvailable(availableTabs);
}, [bridge, availableTabs]);
- return ;
+ const selectedTab = activeTab ?? standaloneTab ?? availableTabs?.[0]?.id;
+ return (
+
+ {standalone && availableTabs ? (
+
+ {availableTabs.map((tab) => (
+ setStandaloneTab(tab.id)}
+ >
+ {tab.label}
+
+ ))}
+
+ ) : null}
+
+
+
+
+ );
}
-function InspectorApp({
+export function InspectorApp({
actorId,
credentials,
bridge,
activeTab,
initialVersion,
+ standalone,
}: {
actorId: ActorId;
credentials: { url: string; inspectorToken: string; token: string };
- bridge: BridgeClient;
+ bridge?: BridgeClient;
activeTab: string | undefined;
initialVersion?: string;
+ standalone?: boolean;
}) {
const queryClient = useMemo(
() =>
@@ -123,6 +156,7 @@ function InspectorApp({
actorId={actorId}
activeTab={activeTab}
bridge={bridge}
+ standalone={standalone}
/>
@@ -192,13 +226,15 @@ function BootGate({ bridge }: { bridge: BridgeClient }) {
);
}
-const bridge = new BridgeClient();
-const rootEl = document.getElementById("root");
-if (!rootEl) throw new Error("Inspector UI: #root element missing");
-ReactDOM.createRoot(rootEl).render(
-
-
-
-
- ,
-);
+if (!__MCP_APP__) {
+ const bridge = new BridgeClient();
+ const rootEl = document.getElementById("root");
+ if (!rootEl) throw new Error("Inspector UI: #root element missing");
+ ReactDOM.createRoot(rootEl).render(
+
+
+
+
+ ,
+ );
+}
diff --git a/frontend/apps/inspector-ui/src/mcp-main.tsx b/frontend/apps/inspector-ui/src/mcp-main.tsx
new file mode 100644
index 0000000000..c84c981474
--- /dev/null
+++ b/frontend/apps/inspector-ui/src/mcp-main.tsx
@@ -0,0 +1,204 @@
+import { App } from "@modelcontextprotocol/ext-apps";
+import { useEffect, useState } from "react";
+import ReactDOM from "react-dom/client";
+import type { ActorId } from "@/components/actors/queries";
+import "@/index.css";
+import { InspectorApp } from "./main";
+
+type ActorTarget =
+ | { actorId: string }
+ | { name: string; key?: string[]; method: "get"; skipReadyWait?: boolean }
+ | {
+ name: string;
+ key?: string[];
+ method: "getOrCreate";
+ pool: string;
+ input?: unknown;
+ region?: string;
+ crashPolicy?: "restart" | "sleep" | "destroy";
+ skipReadyWait?: boolean;
+ };
+
+type InspectorGrant = {
+ token: string;
+ proxyUrl: string;
+ expiresAt: string;
+ actorId: string;
+ dashboardUrl?: string;
+};
+
+const app = new App(
+ { name: "Rivet Actor Inspector", version: "0.1.0" },
+ {},
+ { strict: true },
+);
+
+let currentActor: ActorTarget | undefined;
+let currentGrant: InspectorGrant | undefined;
+
+function structuredGrant(
+ result: Awaited>,
+): InspectorGrant {
+ if (result.isError || !result.structuredContent) {
+ throw new Error("Could not create the temporary Inspector session");
+ }
+ const value = result.structuredContent as Record;
+ for (const key of ["token", "proxyUrl", "expiresAt", "actorId"] as const) {
+ if (typeof value[key] !== "string")
+ throw new Error("Invalid Inspector session response");
+ }
+ return value as InspectorGrant;
+}
+
+async function createSession(actor: ActorTarget): Promise {
+ return structuredGrant(
+ await app.callServerTool({
+ name: "rivet.ui.actor.session.create",
+ arguments: { actor },
+ }),
+ );
+}
+
+async function renewSession(token: string): Promise {
+ return structuredGrant(
+ await app.callServerTool({
+ name: "rivet.ui.actor.session.renew",
+ arguments: { token },
+ }),
+ );
+}
+
+async function revokeSession(token: string): Promise {
+ await app.callServerTool({
+ name: "rivet.ui.actor.session.revoke",
+ arguments: { token },
+ });
+}
+
+// `create` mints a new session record rather than rotating the current one, so
+// the grant it replaces stays valid until its own TTL and keeps counting
+// against the per-principal session limit. `renew` rotates in place and needs
+// no revocation. Hosts may fire tool results back to back, so swaps are
+// serialized to keep a concurrent pair from both reading the same outgoing
+// grant and leaking one of them.
+let sessionSwap: Promise = Promise.resolve();
+
+function replaceSession(actor: ActorTarget): Promise {
+ const swap = sessionSwap.then(async () => {
+ const superseded = currentGrant;
+ const next = await createSession(actor);
+ currentGrant = next;
+ if (superseded) await revokeSession(superseded.token).catch(() => {});
+ return next;
+ });
+ sessionSwap = swap.catch(() => {});
+ return swap;
+}
+
+function McpInspector() {
+ const [grant, setGrant] = useState();
+ const [error, setError] = useState();
+
+ useEffect(() => {
+ const receiveInput = (params: {
+ arguments?: Record;
+ }) => {
+ const actor = params.arguments?.actor;
+ if (actor && typeof actor === "object")
+ currentActor = actor as ActorTarget;
+ };
+ const receiveResult = () => {
+ if (!currentActor) return;
+ void replaceSession(currentActor)
+ .then(setGrant)
+ .catch(() =>
+ setError("Could not authenticate the embedded Inspector."),
+ );
+ };
+ app.addEventListener("toolinput", receiveInput);
+ app.addEventListener("toolresult", receiveResult);
+ app.onhostcontextchanged = (context) => {
+ document.documentElement.classList.toggle(
+ "dark",
+ context.theme !== "light",
+ );
+ };
+ app.onteardown = async () => {
+ if (currentGrant) await revokeSession(currentGrant.token);
+ return {};
+ };
+ void app
+ .connect()
+ .catch(() =>
+ setError("This host could not initialize the MCP App."),
+ );
+ return () => {
+ app.removeEventListener("toolinput", receiveInput);
+ app.removeEventListener("toolresult", receiveResult);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (!grant) return;
+ const renewAt = Math.max(
+ 1_000,
+ new Date(grant.expiresAt).getTime() - Date.now() - 30_000,
+ );
+ const timer = window.setTimeout(() => {
+ void renewSession(grant.token)
+ .then((next) => {
+ currentGrant = next;
+ setGrant(next);
+ })
+ .catch(() =>
+ setError(
+ "The Inspector session expired. Reopen the Inspector to continue.",
+ ),
+ );
+ }, renewAt);
+ return () => window.clearTimeout(timer);
+ }, [grant]);
+
+ if (error) return {error}
;
+ if (!grant)
+ return (
+
+ Connecting to the Rivet Actor Inspector…
+
+ );
+ return (
+
+ {grant.dashboardUrl ? (
+
+ ) : null}
+
+
+
+
+ );
+}
+
+const root = document.getElementById("root");
+if (!root) throw new Error("Inspector UI: #root element missing");
+ReactDOM.createRoot(root).render( );
diff --git a/frontend/apps/inspector-ui/src/vite-env.d.ts b/frontend/apps/inspector-ui/src/vite-env.d.ts
index de5cc2235c..08f95bb406 100644
--- a/frontend/apps/inspector-ui/src/vite-env.d.ts
+++ b/frontend/apps/inspector-ui/src/vite-env.d.ts
@@ -1,4 +1,6 @@
///
+declare const __MCP_APP__: boolean;
+
// rivetkit's package version, baked in at build time. See vite.config.ts.
declare const __RIVETKIT_VERSION__: string;
diff --git a/frontend/apps/inspector-ui/vite.config.ts b/frontend/apps/inspector-ui/vite.config.ts
index aa35a76ed1..e6eb64636a 100644
--- a/frontend/apps/inspector-ui/vite.config.ts
+++ b/frontend/apps/inspector-ui/vite.config.ts
@@ -31,6 +31,7 @@ export default defineConfig({
envDir: path.resolve(__dirname, "../.."),
plugins: [react(), tsconfigPaths()],
define: {
+ __MCP_APP__: JSON.stringify(false),
__APP_TYPE__: JSON.stringify("inspector"),
__APP_BUILD_ID__: JSON.stringify(
`${new Date().toISOString()}@${crypto.randomUUID()}`,
diff --git a/frontend/apps/inspector-ui/vite.mcp.config.ts b/frontend/apps/inspector-ui/vite.mcp.config.ts
new file mode 100644
index 0000000000..8042047b22
--- /dev/null
+++ b/frontend/apps/inspector-ui/vite.mcp.config.ts
@@ -0,0 +1,119 @@
+import { readFileSync } from "node:fs";
+import { createRequire } from "node:module";
+import path from "node:path";
+import react from "@vitejs/plugin-react";
+import { defineConfig } from "vite";
+import { viteSingleFile } from "vite-plugin-singlefile";
+import tsconfigPaths from "vite-tsconfig-paths";
+
+const rivetkitVersion = JSON.parse(
+ readFileSync(
+ path.resolve(
+ __dirname,
+ "../../../rivetkit-typescript/packages/rivetkit/package.json",
+ ),
+ "utf8",
+ ),
+).version as string;
+const require = createRequire(path.resolve(__dirname, "package.json"));
+const WORKER_IMPORT = 'import ActorWorker from "./actor-repl.worker?worker";';
+let sawConsoleWorker = false;
+
+export default defineConfig({
+ root: path.resolve(__dirname),
+ base: "./",
+ plugins: [
+ {
+ name: "fallback-unavailable-mcp-icons",
+ enforce: "pre",
+ transform(code, id) {
+ if (!id.endsWith("/packages/icons/src/index.gen.js")) return;
+ let usedFallback = false;
+ const transformed = code.replace(
+ /export \{([^}]+)\} from "([^"]+)";/g,
+ (statement, names: string, specifier: string) => {
+ try {
+ require.resolve(specifier);
+ return statement;
+ } catch {
+ usedFallback = true;
+ const aliases = names.split(",").map((entry) => {
+ const parts = entry.trim().split(/\s+as\s+/);
+ return `__mcpFallbackIcon as ${parts.at(-1)}`;
+ });
+ return `export { ${aliases.join(", ")} };`;
+ }
+ },
+ );
+ if (!usedFallback) return transformed;
+ return `${transformed}\nconst __mcpFallbackIcon = { prefix: "fas", iconName: "circle", icon: [16, 16, [], "", "M8 1a7 7 0 1 0 0 14A7 7 0 0 0 8 1Z"] };`;
+ },
+ },
+ react(),
+ {
+ name: "disable-unsupported-mcp-console-worker",
+ enforce: "pre",
+ transform(code, id) {
+ if (!id.endsWith("/actor-worker-container.ts")) return;
+ // viteSingleFile cannot inline a `?worker` chunk, so a silently
+ // unmatched import ships a bundle whose console throws at load.
+ if (!code.includes(WORKER_IMPORT)) {
+ throw new Error(
+ `${id} no longer contains ${WORKER_IMPORT}; update the MCP console worker stub`,
+ );
+ }
+ sawConsoleWorker = true;
+ return code.replace(
+ WORKER_IMPORT,
+ `class ActorWorker extends EventTarget {
+ constructor() {
+ super();
+ throw new Error("The actor console is unavailable in the embedded Inspector.");
+ }
+ postMessage() {}
+ terminate() {}
+}`,
+ );
+ },
+ buildEnd() {
+ if (!sawConsoleWorker) {
+ throw new Error(
+ "actor-worker-container.ts was never transformed; the MCP console worker stub did not apply",
+ );
+ }
+ },
+ },
+ tsconfigPaths({ projects: [path.resolve(__dirname, "tsconfig.json")] }),
+ viteSingleFile(),
+ ],
+ resolve: {
+ alias: {
+ "@rivet-gg/icons": path.resolve(
+ __dirname,
+ "../../packages/icons/src/index.gen.js",
+ ),
+ "@": path.resolve(__dirname, "../../src"),
+ },
+ },
+ define: {
+ __MCP_APP__: JSON.stringify(true),
+ __APP_TYPE__: JSON.stringify("inspector"),
+ __APP_BUILD_ID__: JSON.stringify("mcp-actor-inspector"),
+ __RIVETKIT_VERSION__: JSON.stringify(rivetkitVersion),
+ },
+ optimizeDeps: {
+ include: ["@fortawesome/*", "@rivet-gg/icons", "@rivet-gg/cloud"],
+ },
+ worker: { format: "es" },
+ build: {
+ outDir: "../../dist/mcp-inspector-ui",
+ emptyOutDir: true,
+ sourcemap: false,
+ cssCodeSplit: false,
+ rollupOptions: {
+ input: path.resolve(__dirname, "mcp-index.html"),
+ output: { inlineDynamicImports: true },
+ },
+ commonjsOptions: { include: [/@rivet-gg\/components/, /node_modules/] },
+ },
+});
diff --git a/frontend/package.json b/frontend/package.json
index cade20f977..f1bb728c7a 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -19,6 +19,7 @@
"build:ladle": "ladle build"
},
"dependencies": {
+ "@better-auth/oauth-provider": "1.6.23",
"@codemirror/autocomplete": "^6.18.7",
"@codemirror/commands": "^6.8.1",
"@codemirror/lang-javascript": "^6.2.4",
@@ -37,6 +38,8 @@
"@ladle/react": "^5.1.1",
"@marsidev/react-turnstile": "^1.5.0",
"@microsoft/fetch-event-source": "^2.0.1",
+ "@modelcontextprotocol/ext-apps": "1.7.4",
+ "@modelcontextprotocol/sdk": "1.29.0",
"@radix-ui/react-accordion": "^1.2.12",
"@radix-ui/react-avatar": "^1.1.10",
"@radix-ui/react-checkbox": "^1.3.3",
@@ -117,7 +120,7 @@
"actor-core": "^0.6.3",
"autoprefixer": "^10.4.21",
"bcryptjs": "^2.4.3",
- "better-auth": "^1.5.6",
+ "better-auth": "1.6.23",
"canvas-confetti": "^1.9.3",
"cbor-x": "^1.6.0",
"class-variance-authority": "^0.7.1",
@@ -162,6 +165,7 @@
"usehooks-ts": "^3.1.1",
"vite": "^5.4.20",
"vite-plugin-favicons-inject": "^2.2.0",
+ "vite-plugin-singlefile": "2.3.3",
"vite-tsconfig-paths": "^5.1.4",
"zod": "^3.25.76"
},
diff --git a/frontend/src/app/settings-pages/mcp-connection.tsx b/frontend/src/app/settings-pages/mcp-connection.tsx
new file mode 100644
index 0000000000..3d07eaf49b
--- /dev/null
+++ b/frontend/src/app/settings-pages/mcp-connection.tsx
@@ -0,0 +1,231 @@
+import {
+ faChevronRight,
+ faClaude,
+ faCursor,
+ faGemini,
+ faPlug,
+ faVscode,
+ Icon,
+ type IconProp,
+} from "@rivet-gg/icons";
+import { useParams } from "@tanstack/react-router";
+import { useState } from "react";
+import {
+ CodeFrame,
+ CodeGroup,
+ CodePreview,
+ getConfig,
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components";
+import { useEngineCompatDataProvider } from "@/components/actors";
+import { getMcpUrl } from "@/lib/env";
+import { features } from "@/lib/features";
+import {
+ type HostedTarget,
+ hostedUrl,
+ SCOPE_ORDER,
+ SCOPES,
+ type Scope,
+} from "./mcp-scope";
+import { SettingsCard } from "./settings-card";
+
+const DOCS_URL = "https://rivet.dev/mcp";
+
+const DESCRIPTION =
+ "Let AI tools like Claude Code and Cursor read and manage your actors.";
+
+type Language = "json" | "bash";
+
+interface ClientTab {
+ title: string;
+ icon: IconProp;
+ language: Language;
+ code: string;
+}
+
+function json(value: unknown) {
+ return JSON.stringify(value, null, 2);
+}
+
+function hostedTabs(url: string): ClientTab[] {
+ return [
+ {
+ title: "Claude Code",
+ icon: faClaude,
+ language: "bash",
+ code: `claude mcp add --transport http rivet "${url}"`,
+ },
+ {
+ title: "Cursor",
+ icon: faCursor,
+ language: "json",
+ code: json({ mcpServers: { rivet: { url } } }),
+ },
+ {
+ title: "VS Code",
+ icon: faVscode,
+ language: "bash",
+ code: `code --add-mcp '${JSON.stringify({ name: "rivet", type: "http", url })}'`,
+ },
+ {
+ title: "Gemini CLI",
+ icon: faGemini,
+ language: "json",
+ code: json({ mcpServers: { rivet: { httpUrl: url } } }),
+ },
+ {
+ title: "Other",
+ icon: faPlug,
+ language: "json",
+ code: json({ mcpServers: { rivet: { type: "http", url } } }),
+ },
+ ];
+}
+
+function localTabs(endpoint: string, namespace: string): ClientTab[] {
+ const command = "npx";
+ const args = ["-y", "@rivet-dev/mcp", "--target", "local"];
+ const env = { RIVET_ENDPOINT: endpoint, RIVET_NAMESPACE: namespace };
+ const server = { command, args, env };
+
+ return [
+ {
+ title: "Claude Code",
+ icon: faClaude,
+ language: "bash",
+ code: `claude mcp add rivet \\
+ --env RIVET_ENDPOINT=${endpoint} \\
+ --env RIVET_NAMESPACE=${namespace} \\
+ -- ${command} ${args.join(" ")}`,
+ },
+ {
+ title: "Cursor",
+ icon: faCursor,
+ language: "json",
+ code: json({ mcpServers: { rivet: server } }),
+ },
+ {
+ title: "VS Code",
+ icon: faVscode,
+ language: "bash",
+ code: `code --add-mcp '${JSON.stringify({ name: "rivet", ...server })}'`,
+ },
+ {
+ title: "Gemini CLI",
+ icon: faGemini,
+ language: "json",
+ code: json({ mcpServers: { rivet: server } }),
+ },
+ {
+ title: "Other",
+ icon: faPlug,
+ language: "json",
+ code: json({ mcpServers: { rivet: server } }),
+ },
+ ];
+}
+
+function DocsFooter() {
+ return (
+
+
+ See MCP Documentation{" "}
+
+
+
+ );
+}
+
+function ClientTabs({ tabs }: { tabs: ClientTab[] }) {
+ return (
+
+ {tabs.map((tab) => (
+ tab.code}
+ footer={ }
+ >
+
+
+ ))}
+
+ );
+}
+
+function ScopeSelect({
+ value,
+ onValueChange,
+}: {
+ value: Scope;
+ onValueChange: (value: Scope) => void;
+}) {
+ return (
+ onValueChange(next as Scope)}
+ >
+
+
+
+
+ {SCOPE_ORDER.map((scope) => (
+
+ {SCOPES[scope].label}
+
+ ))}
+
+
+ );
+}
+
+function HostedMcp() {
+ const params = useParams({ strict: false }) as Partial;
+ const [scope, setScope] = useState("namespace");
+
+ if (!params.organization || !params.project || !params.namespace) {
+ return null;
+ }
+
+ const target: HostedTarget = {
+ organization: params.organization,
+ project: params.project,
+ namespace: params.namespace,
+ };
+ return (
+ }
+ >
+
+
+ );
+}
+
+function LocalMcp() {
+ const namespace = useEngineCompatDataProvider().engineNamespace;
+ const endpoint = getConfig().apiUrl;
+
+ return (
+
+
+
+ );
+}
+
+export function McpConnection() {
+ if (!features.mcp) return null;
+ return features.platform ? : ;
+}
diff --git a/frontend/src/app/settings-pages/mcp-scope.test.ts b/frontend/src/app/settings-pages/mcp-scope.test.ts
new file mode 100644
index 0000000000..7601e14b8e
--- /dev/null
+++ b/frontend/src/app/settings-pages/mcp-scope.test.ts
@@ -0,0 +1,36 @@
+import { describe, expect, it } from "vitest";
+import { hostedUrl, type Scope } from "./mcp-scope";
+
+const BASE = "https://mcp.rivet.dev/mcp";
+const TARGET = {
+ organization: "acme",
+ project: "prod",
+ namespace: "canary",
+};
+
+function params(scope: Scope) {
+ return Object.fromEntries(
+ new URL(hostedUrl(BASE, TARGET, scope)).searchParams,
+ );
+}
+
+describe("hostedUrl", () => {
+ it("pins every level for the namespace scope", () => {
+ expect(params("namespace")).toEqual(TARGET);
+ });
+
+ it("leaves the namespace open for the project scope", () => {
+ expect(params("project")).toEqual({
+ organization: "acme",
+ project: "prod",
+ });
+ });
+
+ it("leaves the project open for the organization scope", () => {
+ expect(params("organization")).toEqual({ organization: "acme" });
+ });
+
+ it("emits no query at all for the account scope", () => {
+ expect(hostedUrl(BASE, TARGET, "account")).toBe(BASE);
+ });
+});
diff --git a/frontend/src/app/settings-pages/mcp-scope.ts b/frontend/src/app/settings-pages/mcp-scope.ts
new file mode 100644
index 0000000000..edeb46e577
--- /dev/null
+++ b/frontend/src/app/settings-pages/mcp-scope.ts
@@ -0,0 +1,54 @@
+export type Scope = "namespace" | "project" | "organization" | "account";
+
+export interface HostedTarget {
+ organization: string;
+ project: string;
+ namespace: string;
+}
+
+export const SCOPES: Record<
+ Scope,
+ { label: string; reach: string; pins: (keyof HostedTarget)[] }
+> = {
+ namespace: {
+ label: "This namespace",
+ reach: "only this namespace",
+ pins: ["organization", "project", "namespace"],
+ },
+ project: {
+ label: "This project",
+ reach: "any namespace in this project",
+ pins: ["organization", "project"],
+ },
+ organization: {
+ label: "This organization",
+ reach: "any project in this organization",
+ pins: ["organization"],
+ },
+ account: {
+ label: "Entire account",
+ reach: "any project in your account",
+ pins: [],
+ },
+};
+
+export const SCOPE_ORDER: Scope[] = [
+ "namespace",
+ "project",
+ "organization",
+ "account",
+];
+
+// Levels left out of the query stay open for the agent to name per call. Every
+// level that is present is a hard pin the session cannot move off, so a
+// narrower scope is the safer default.
+export function hostedUrl(
+ base: string,
+ target: HostedTarget,
+ scope: Scope,
+): string {
+ const query = new URLSearchParams();
+ for (const level of SCOPES[scope].pins) query.set(level, target[level]);
+ const search = query.toString();
+ return search ? `${base}?${search}` : base;
+}
diff --git a/frontend/src/app/settings-pages/namespace-settings.tsx b/frontend/src/app/settings-pages/namespace-settings.tsx
index a75967fa7d..a6451a1f80 100644
--- a/frontend/src/app/settings-pages/namespace-settings.tsx
+++ b/frontend/src/app/settings-pages/namespace-settings.tsx
@@ -24,6 +24,7 @@ import {
PublishableToken,
SecretToken,
} from "@/routes/_context/orgs.$organization/projects.$project/ns.$namespace/tokens";
+import { McpConnection } from "./mcp-connection";
import { SettingsCard } from "./settings-card";
export function NamespaceSettingsContent() {
@@ -52,6 +53,7 @@ export function NamespaceAdvancedContent() {
{features.auth ? : null}
{features.auth ? : null}
+
{features.dangerZone ? : null}
diff --git a/frontend/src/components/actors/actor-inspector-context.tsx b/frontend/src/components/actors/actor-inspector-context.tsx
index 67dceaa67b..ebdcf4ec33 100644
--- a/frontend/src/components/actors/actor-inspector-context.tsx
+++ b/frontend/src/components/actors/actor-inspector-context.tsx
@@ -658,8 +658,11 @@ export const createDefaultActorInspectorContext = ({
},
});
+// The base may carry a path prefix (the MCP Inspector proxy is mounted under
+// /mcp/inspector-proxy), so the segment must stay relative. A leading slash
+// would resolve against the origin and drop that prefix.
const computeActorUrl = ({ url, actorId }: { url: string; actorId: ActorId }) =>
- new URL(`/gateway/${actorId}`, url).href;
+ new URL(`gateway/${actorId}`, url.endsWith("/") ? url : `${url}/`).href;
function transformWorkflowHistoryFromJson(raw: number[] | null): {
history: WorkflowHistory | null;
diff --git a/frontend/src/components/actors/inspector-tab-registry.tsx b/frontend/src/components/actors/inspector-tab-registry.tsx
index e314dc34ce..d0511f467e 100644
--- a/frontend/src/components/actors/inspector-tab-registry.tsx
+++ b/frontend/src/components/actors/inspector-tab-registry.tsx
@@ -124,6 +124,12 @@ export const INSPECTOR_TAB_REGISTRATIONS: readonly TabRegistration[] = [
},
] as const;
+const availableInspectorRegistrations = __MCP_APP__
+ ? INSPECTOR_TAB_REGISTRATIONS.filter(
+ (registration) => registration.descriptor.id !== "console",
+ )
+ : INSPECTOR_TAB_REGISTRATIONS;
+
/**
* Returns the descriptors of all inspector tabs available for this actor,
* filtered by the live capability flags from the inspector context. Returns
@@ -179,12 +185,15 @@ export function useAvailableInspectorTabs(
.filter((t) => t.hidden === true)
.map((t) => t.id),
);
- const builtIns = INSPECTOR_TAB_REGISTRATIONS.filter((t) =>
+ const builtIns = availableInspectorRegistrations.filter((t) =>
t.available(caps),
)
.map((t) => t.descriptor)
.filter((d) => !hideSet.has(d.id));
- const customs: InspectorTabDescriptor[] = (tabConfig?.tabs ?? [])
+ const customs: InspectorTabDescriptor[] = (__MCP_APP__
+ ? []
+ : (tabConfig?.tabs ?? [])
+ )
.filter((t) => t.hidden !== true && typeof t.label === "string")
.map((t) => ({
id: t.id,
@@ -224,7 +233,7 @@ export function InspectorTabContent({
actorId: ActorId;
activeTab: string | undefined;
}) {
- const registration = INSPECTOR_TAB_REGISTRATIONS.find(
+ const registration = availableInspectorRegistrations.find(
(t) => t.descriptor.id === activeTab,
);
if (!registration) return null;
diff --git a/frontend/src/lib/auth.ts b/frontend/src/lib/auth.ts
index bad7a6f077..34c7ea5e13 100644
--- a/frontend/src/lib/auth.ts
+++ b/frontend/src/lib/auth.ts
@@ -1,4 +1,5 @@
import { notFound, redirect } from "@tanstack/react-router";
+import { oauthProviderClient } from "@better-auth/oauth-provider/client";
import { adminClient, organizationClient } from "better-auth/client/plugins";
import { createAuthClient } from "better-auth/react";
import { cloudEnv } from "./env";
@@ -8,7 +9,7 @@ const createClient = () =>
createAuthClient({
baseURL: cloudEnv().VITE_APP_CLOUD_API_URL,
fetchOptions: { credentials: "include" },
- plugins: [organizationClient(), adminClient()],
+ plugins: [organizationClient(), adminClient(), oauthProviderClient()],
});
type AuthClient = ReturnType;
diff --git a/frontend/src/lib/env.ts b/frontend/src/lib/env.ts
index 89483f012f..6d4522379d 100644
--- a/frontend/src/lib/env.ts
+++ b/frontend/src/lib/env.ts
@@ -28,6 +28,9 @@ export const cloudEnvSchema = commonEnvSchema.merge(
z.object({
// Cloud API endpoint - direct URL without transformation, used for cloud-specific operations
VITE_APP_CLOUD_API_URL: z.string().url(),
+ // Hosted MCP endpoint. Unset on Rivet Cloud; self-hosted deployments
+ // point this at their own MCP service.
+ VITE_APP_MCP_URL: z.string().url().optional(),
VITE_APP_SENTRY_TUNNEL: z.string().optional(),
VITE_APP_TURNSTILE_SITE_KEY: z.string().optional(),
}),
@@ -35,6 +38,9 @@ export const cloudEnvSchema = commonEnvSchema.merge(
export const cloudEnv = () => cloudEnvSchema.parse(import.meta.env);
+export const getMcpUrl = () =>
+ cloudEnv().VITE_APP_MCP_URL ?? "https://mcp.rivet.dev/mcp";
+
export const getRivetRunUrl = (engineNsName: string) => {
return cloudEnv().VITE_DEPLOYMENT_TYPE === "production"
? `https://${engineNsName}.rivet.run/`
diff --git a/frontend/src/lib/features.ts b/frontend/src/lib/features.ts
index f111bc9d05..0ba2e5ecf0 100644
--- a/frontend/src/lib/features.ts
+++ b/frontend/src/lib/features.ts
@@ -37,6 +37,9 @@ export const features = {
compute: isEnabled("compute") && platform,
// `agentOs` gates the agentOS (coding-agent VM) onboarding template. Beta.
agentOs: isEnabled("agent-os"),
+ // `mcp` gates the MCP connection settings. The snippet differs per flavor:
+ // platform points at the hosted endpoint, OSS at the local stdio server.
+ mcp: isEnabled("mcp"),
support: isEnabled("support"),
branding: isEnabled("branding"),
datacenter: isEnabled("datacenter"),
diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts
index 301f4ed881..f7754a6c3e 100644
--- a/frontend/src/routeTree.gen.ts
+++ b/frontend/src/routeTree.gen.ts
@@ -18,6 +18,7 @@ import { Route as ForgotPasswordRouteImport } from './routes/forgot-password'
import { Route as AcceptInvitationRouteImport } from './routes/accept-invitation'
import { Route as ContextRouteImport } from './routes/_context'
import { Route as ContextIndexRouteImport } from './routes/_context/index'
+import { Route as OauthConsentRouteImport } from './routes/oauth.consent'
import { Route as ContextNewIndexRouteImport } from './routes/_context/new/index'
import { Route as ContextNewOrgIndexRouteImport } from './routes/_context/new-org/index'
import { Route as ContextOrgsOrganizationRouteImport } from './routes/_context/orgs.$organization'
@@ -84,6 +85,11 @@ const ContextIndexRoute = ContextIndexRouteImport.update({
path: '/',
getParentRoute: () => ContextRoute,
} as any)
+const OauthConsentRoute = OauthConsentRouteImport.update({
+ id: '/oauth/consent',
+ path: '/oauth/consent',
+ getParentRoute: () => rootRouteImport,
+} as any)
const ContextNewIndexRoute = ContextNewIndexRouteImport.update({
id: '/new/',
path: '/new/',
@@ -224,6 +230,7 @@ export interface FileRoutesByFullPath {
'/onboarding': typeof OnboardingRoute
'/reset-password': typeof ResetPasswordRoute
'/verify-email-pending': typeof VerifyEmailPendingRoute
+ '/oauth/consent': typeof OauthConsentRoute
'/ns/$namespace': typeof ContextNsNamespaceRouteWithChildren
'/orgs/$organization': typeof ContextOrgsOrganizationRouteWithChildren
'/new-org/': typeof ContextNewOrgIndexRoute
@@ -254,6 +261,7 @@ export interface FileRoutesByTo {
'/onboarding': typeof OnboardingRoute
'/reset-password': typeof ResetPasswordRoute
'/verify-email-pending': typeof VerifyEmailPendingRoute
+ '/oauth/consent': typeof OauthConsentRoute
'/': typeof ContextIndexRoute
'/new-org': typeof ContextNewOrgIndexRoute
'/new': typeof ContextNewIndexRoute
@@ -283,6 +291,7 @@ export interface FileRoutesById {
'/onboarding': typeof OnboardingRoute
'/reset-password': typeof ResetPasswordRoute
'/verify-email-pending': typeof VerifyEmailPendingRoute
+ '/oauth/consent': typeof OauthConsentRoute
'/_context/': typeof ContextIndexRoute
'/_context/ns/$namespace': typeof ContextNsNamespaceRouteWithChildren
'/_context/orgs/$organization': typeof ContextOrgsOrganizationRouteWithChildren
@@ -317,6 +326,7 @@ export interface FileRouteTypes {
| '/onboarding'
| '/reset-password'
| '/verify-email-pending'
+ | '/oauth/consent'
| '/ns/$namespace'
| '/orgs/$organization'
| '/new-org/'
@@ -347,6 +357,7 @@ export interface FileRouteTypes {
| '/onboarding'
| '/reset-password'
| '/verify-email-pending'
+ | '/oauth/consent'
| '/'
| '/new-org'
| '/new'
@@ -375,6 +386,7 @@ export interface FileRouteTypes {
| '/onboarding'
| '/reset-password'
| '/verify-email-pending'
+ | '/oauth/consent'
| '/_context/'
| '/_context/ns/$namespace'
| '/_context/orgs/$organization'
@@ -408,6 +420,7 @@ export interface RootRouteChildren {
OnboardingRoute: typeof OnboardingRoute
ResetPasswordRoute: typeof ResetPasswordRoute
VerifyEmailPendingRoute: typeof VerifyEmailPendingRoute
+ OauthConsentRoute: typeof OauthConsentRoute
}
declare module '@tanstack/react-router' {
@@ -475,6 +488,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ContextIndexRouteImport
parentRoute: typeof ContextRoute
}
+ '/oauth/consent': {
+ id: '/oauth/consent'
+ path: '/oauth/consent'
+ fullPath: '/oauth/consent'
+ preLoaderRoute: typeof OauthConsentRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/_context/new/': {
id: '/_context/new/'
path: '/new'
@@ -746,6 +766,7 @@ const rootRouteChildren: RootRouteChildren = {
OnboardingRoute: OnboardingRoute,
ResetPasswordRoute: ResetPasswordRoute,
VerifyEmailPendingRoute: VerifyEmailPendingRoute,
+ OauthConsentRoute: OauthConsentRoute,
}
export const routeTree = rootRouteImport
._addFileChildren(rootRouteChildren)
diff --git a/frontend/src/routes/oauth.consent.tsx b/frontend/src/routes/oauth.consent.tsx
new file mode 100644
index 0000000000..16d7f19cbf
--- /dev/null
+++ b/frontend/src/routes/oauth.consent.tsx
@@ -0,0 +1,309 @@
+import { useMutation, useQuery } from "@tanstack/react-query";
+import { createFileRoute, redirect } from "@tanstack/react-router";
+import { useMemo } from "react";
+import { Controller, useForm } from "react-hook-form";
+import { z } from "zod";
+import { Logo } from "@/app/logo";
+import { Button } from "@/components/ui/button";
+import { Checkbox } from "@/components/ui/checkbox";
+import { Skeleton } from "@/components/ui/skeleton";
+import { authClient } from "@/lib/auth";
+
+const searchSchema = z.object({
+ client_id: z.string(),
+ scope: z.string(),
+ oauth_query: z.string().optional(),
+});
+
+interface ScopeDetail {
+ title: string;
+ description: string;
+}
+
+// The MCP entrypoint verifies every request against rivet:cloud:read, so a
+// grant without it yields a token that cannot call anything.
+const REQUIRED_SCOPES = new Set(["rivet:cloud:read"]);
+
+const SCOPE_DETAILS: Record = {
+ openid: {
+ title: "Confirm your identity",
+ description:
+ "Share your Rivet user ID so the client knows who signed in.",
+ },
+ offline_access: {
+ title: "Stay signed in",
+ description:
+ "Reconnect without asking you again. Access tokens expire after 15 minutes.",
+ },
+ "rivet:cloud:read": {
+ title: "View your organizations and projects",
+ description:
+ "List organizations, projects, and namespaces, and read their usage metrics.",
+ },
+ "rivet:cloud:write": {
+ title: "Manage your organizations and projects",
+ description:
+ "Change cloud resources on your behalf. Destructive and credential operations stay unavailable.",
+ },
+ "rivet:actors:read": {
+ title: "View your actors",
+ description:
+ "List actors in the selected namespace and send them read-only requests.",
+ },
+ "rivet:actors:write": {
+ title: "Modify your actors",
+ description: "Send requests that change actor state or lifecycle.",
+ },
+ "rivet:inspector:read": {
+ title: "Inspect actor internals",
+ description:
+ "Read actor state, database contents, and logs through the Actor Inspector.",
+ },
+ "rivet:inspector:write": {
+ title: "Modify actor internals",
+ description:
+ "Edit state and run commands against an actor through the Actor Inspector.",
+ },
+};
+
+export const Route = createFileRoute("/oauth/consent")({
+ validateSearch: searchSchema,
+ beforeLoad: async ({ location }) => {
+ const session = await authClient.getSession();
+ if (!session.data) {
+ throw redirect({
+ to: "/login",
+ search: { from: `${location.pathname}${location.searchStr}` },
+ });
+ }
+ },
+ component: OAuthConsent,
+});
+
+interface ConsentFormValues {
+ scopes: Record;
+}
+
+function OAuthConsent() {
+ const search = Route.useSearch();
+ const requestedScopes = useMemo(
+ () => search.scope.split(/\s+/).filter(Boolean),
+ [search.scope],
+ );
+ const { control, handleSubmit, watch } = useForm({
+ defaultValues: {
+ scopes: Object.fromEntries(
+ requestedScopes.map((scope) => [scope, true]),
+ ),
+ },
+ });
+ const granted = watch("scopes");
+ const grantedCount = requestedScopes.filter(
+ (scope) => granted[scope],
+ ).length;
+
+ // Dynamically registered clients pick their own opaque client_id, so the
+ // name they registered under is the only human-readable identifier.
+ const { data: client, isPending: isClientPending } = useQuery({
+ queryKey: ["oauth", "public-client", search.client_id],
+ queryFn: async () => {
+ const result = await authClient.oauth2.publicClient({
+ query: { client_id: search.client_id },
+ });
+ if (result.error) {
+ throw new Error(
+ result.error.message ?? "Could not load client.",
+ );
+ }
+ return result.data;
+ },
+ retry: false,
+ });
+
+ const consent = useMutation({
+ mutationFn: async ({
+ accept,
+ values,
+ }: {
+ accept: boolean;
+ values: ConsentFormValues;
+ }) => {
+ const result = await authClient.oauth2.consent({
+ accept,
+ // Only ever a subset of the originally requested scopes; the
+ // provider rejects anything that was not asked for.
+ scope: requestedScopes
+ .filter((scope) => values.scopes[scope])
+ .join(" "),
+ // The provider verifies a signature over the full authorize
+ // query. validateSearch drops the params it does not declare,
+ // so the router's searchStr would fail that check.
+ oauth_query:
+ search.oauth_query ??
+ window.location.search.replace(/^\?/, ""),
+ });
+ if (result.error || !result.data?.url) {
+ throw new Error(
+ result.error?.message ??
+ "Could not complete OAuth consent.",
+ );
+ }
+ return result.data.url;
+ },
+ onSuccess: (url) => window.location.assign(url),
+ });
+
+ const submit = (accept: boolean) =>
+ handleSubmit((values) => consent.mutate({ accept, values }));
+
+ return (
+
+
+
+
+
+ {client?.logo_uri ? (
+
+ ) : null}
+
+
+ Authorize MCP access
+
+ {isClientPending ? (
+
+ ) : (
+
+ {client?.client_name ? (
+ <>
+
+ {client.client_name}
+ {" "}
+ is requesting access to your Rivet
+ account.
+ >
+ ) : (
+ "An application is requesting access to your Rivet account."
+ )}
+
+ )}
+
+
+
+
+ Choose what to allow
+
+
+ {requestedScopes.map((scope) => {
+ const detail = SCOPE_DETAILS[scope];
+ const required = REQUIRED_SCOPES.has(scope);
+ const id = `scope-${scope}`;
+ return (
+
+ (
+
+ field.onChange(checked === true)
+ }
+ className="mt-0.5"
+ />
+ )}
+ />
+
+
+
+ {detail?.title ?? scope}
+
+ {detail ? (
+
+ {scope}
+
+ ) : null}
+ {required ? (
+
+ Required
+
+ ) : null}
+
+
+ {detail?.description ??
+ "Grants the client additional access to your Rivet account."}
+
+
+
+ );
+ })}
+
+
+ {granted["rivet:cloud:write"] ||
+ granted["rivet:actors:write"] ||
+ granted["rivet:inspector:write"] ? (
+
+ Write access also requires the MCP service's write
+ policy to be enabled, so approving it here does not by
+ itself allow changes.
+
+ ) : null}
+
+ {consent.error ? (
+
+ {consent.error.message}
+
+ ) : null}
+
+
+
+ Deny
+
+
+ Authorize
+
+
+
+
+
+
Client ID
+
+ {search.client_id}
+
+
+ {client?.client_uri ? (
+
+ ) : null}
+
+
+
+ );
+}
diff --git a/frontend/src/vite-env.d.ts b/frontend/src/vite-env.d.ts
index 836993a9ca..c9103c1e03 100644
--- a/frontend/src/vite-env.d.ts
+++ b/frontend/src/vite-env.d.ts
@@ -1,6 +1,7 @@
///
declare const __APP_BUILD_ID__: string;
+declare const __MCP_APP__: boolean;
declare module "*.module.css" {
const classes: { [key: string]: string };
diff --git a/frontend/vite.base.config.ts b/frontend/vite.base.config.ts
index 26f2b53c10..954e5eb25c 100644
--- a/frontend/vite.base.config.ts
+++ b/frontend/vite.base.config.ts
@@ -11,6 +11,7 @@ export function baseViteConfig(): UserConfig {
__APP_BUILD_ID__: JSON.stringify(
`${new Date().toISOString()}@${crypto.randomUUID()}`,
),
+ __MCP_APP__: JSON.stringify(false),
},
resolve: {
alias: {
diff --git a/frontend/vite.mcp-inspector-ui.config.ts b/frontend/vite.mcp-inspector-ui.config.ts
new file mode 100644
index 0000000000..fe87901813
--- /dev/null
+++ b/frontend/vite.mcp-inspector-ui.config.ts
@@ -0,0 +1 @@
+export { default } from "./apps/inspector-ui/vite.mcp.config";
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 5575a5c5ac..04bcc0581b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -908,7 +908,7 @@ importers:
version: 19.2.3(@types/react@19.2.13)
drizzle-orm:
specifier: ^0.38.0
- version: 0.38.4(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/react@19.2.13)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(react@19.1.0)(sql.js@1.13.0)
+ version: 0.38.4(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/react@19.2.13)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(react@19.1.0)(sql.js@1.13.0)
typescript:
specifier: ^5.7.3
version: 5.9.3
@@ -1414,7 +1414,7 @@ importers:
version: 4.3.19(react@19.1.0)(zod@3.25.76)
drizzle-orm:
specifier: ^0.44.2
- version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
+ version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)
fdb-tuple:
specifier: ^1.0.0
version: 1.0.0
@@ -2042,7 +2042,7 @@ importers:
version: 0.31.5
drizzle-orm:
specifier: ^0.44.2
- version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
+ version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)
devDependencies:
'@types/node':
specifier: ^22.13.9
@@ -2315,7 +2315,7 @@ importers:
version: 4.12.25
nitro:
specifier: 3.0.260610-beta
- version: 3.0.260610-beta(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(better-sqlite3@12.8.0)(chokidar@5.0.0)(dotenv@17.4.2)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(giget@3.3.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.2.6)(miniflare@4.20260611.0)(rollup@4.62.2)(vite@7.3.1(@types/node@24.7.1)(jiti@2.7.0)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))(wrangler@4.100.0)(xml2js@0.6.2)
+ version: 3.0.260610-beta(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(better-sqlite3@12.8.0)(chokidar@5.0.0)(dotenv@17.4.2)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0))(giget@3.3.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.2.6)(miniflare@4.20260611.0)(rollup@4.62.2)(vite@7.3.1(@types/node@24.7.1)(jiti@2.7.0)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))(wrangler@4.100.0)(xml2js@0.6.2)
rollup:
specifier: ^4.62.2
version: 4.62.2
@@ -2341,6 +2341,9 @@ importers:
frontend:
dependencies:
+ '@better-auth/oauth-provider':
+ specifier: 1.6.23
+ version: 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.6.23(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0)))(better-call@1.3.7(zod@3.25.76))
'@codemirror/autocomplete':
specifier: 6.18.7
version: 6.18.7
@@ -2395,6 +2398,12 @@ importers:
'@microsoft/fetch-event-source':
specifier: ^2.0.1
version: 2.0.1
+ '@modelcontextprotocol/ext-apps':
+ specifier: 1.7.4
+ version: 1.7.4(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@3.25.76)
+ '@modelcontextprotocol/sdk':
+ specifier: 1.29.0
+ version: 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)
'@radix-ui/react-accordion':
specifier: ^1.2.12
version: 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
@@ -2636,8 +2645,8 @@ importers:
specifier: ^2.4.3
version: 2.4.3
better-auth:
- specifier: ^1.5.6
- version: 1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))
+ specifier: 1.6.23
+ version: 1.6.23(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))
canvas-confetti:
specifier: ^1.9.3
version: 1.9.3
@@ -2770,6 +2779,9 @@ importers:
vite-plugin-favicons-inject:
specifier: ^2.2.0
version: 2.2.0
+ vite-plugin-singlefile:
+ specifier: 2.3.3
+ version: 2.3.3(rollup@4.62.2)(vite@5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0))
vite-tsconfig-paths:
specifier: ^5.1.4
version: 5.1.4(typescript@5.9.3)(vite@5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0))
@@ -3348,7 +3360,7 @@ importers:
devDependencies:
'@modelcontextprotocol/inspector':
specifier: ^0.14.0
- version: 0.14.3(@cfworker/json-schema@4.1.1)(@swc/core@1.15.11(@swc/helpers@0.5.17))(@types/node@22.19.10)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(hono@4.12.25)(typescript@5.9.3)
+ version: 0.14.3(@cfworker/json-schema@4.1.1)(@swc/core@1.15.11(@swc/helpers@0.5.17))(@types/node@22.19.10)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(typescript@5.9.3)
'@types/node':
specifier: ^22.13.1
version: 22.19.10
@@ -3470,7 +3482,7 @@ importers:
version: 0.31.5
drizzle-orm:
specifier: ^0.44.2
- version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
+ version: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)
hono:
specifier: ^4.7.0
version: 4.11.9
@@ -4641,62 +4653,73 @@ packages:
resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==}
engines: {node: '>=18'}
- '@better-auth/core@1.5.6':
- resolution: {integrity: sha512-Ez9DZdIMFyxHremmoLz1emFPGNQomDC1jqqBPnZ6Ci+6TiGN3R9w/Y03cJn6I8r1ycKgOzeVMZtJ/erOZ27Gsw==}
+ '@better-auth/core@1.6.23':
+ resolution: {integrity: sha512-beEhOs0uVeOxYOZKUfIEBd/nQV2Bd4/6wyLxZ0OFkn6CMTK2Vi+hXuZLnyPBeB6RdHpebEoJWiHqwHxBIxgPDQ==}
peerDependencies:
- '@better-auth/utils': 0.3.1
- '@better-fetch/fetch': 1.1.21
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
'@cloudflare/workers-types': '>=4'
'@opentelemetry/api': ^1.9.0
- better-call: 1.3.2
+ better-call: 1.3.7
jose: ^6.1.0
- kysely: ^0.28.5
+ kysely: ^0.28.5 || ^0.29.0
nanostores: ^1.0.1
peerDependenciesMeta:
'@cloudflare/workers-types':
optional: true
+ '@opentelemetry/api':
+ optional: true
- '@better-auth/drizzle-adapter@1.5.6':
- resolution: {integrity: sha512-VfFFmaoFw3ug12SiSuIwzrMoHyIVmkMGWm9gZ4sXdYYVX4HboCL4m3fjzOhppcmK5OGatRuU+N1UX6wxCITcXw==}
+ '@better-auth/drizzle-adapter@1.6.23':
+ resolution: {integrity: sha512-2+/PTVfIP9E7iz6af8TB3lhnowHUj9ljC66kECmHaFEdUqPgzHoWux9epotKwO7XDg2ui4ttWQ8CMeNFLvQeKQ==}
peerDependencies:
- '@better-auth/core': 1.5.6
- '@better-auth/utils': ^0.3.0
- drizzle-orm: '>=0.41.0'
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
+ drizzle-orm: ^0.45.2
peerDependenciesMeta:
drizzle-orm:
optional: true
- '@better-auth/kysely-adapter@1.5.6':
- resolution: {integrity: sha512-Fnf+h8WVKtw6lEOmVmiVVzDf3shJtM60AYf9XTnbdCeUd6MxN/KnaJZpkgtYnRs7a+nwtkVB+fg4lGETebGFXQ==}
+ '@better-auth/kysely-adapter@1.6.23':
+ resolution: {integrity: sha512-zbNJsMbG09exfkGyvFqBLLqWoMPAUWjxCuUnEK5AsjbYoZeIjj/QGZgdf4CapVWryKxjA9Q6Jlr6fbiPpC3VAg==}
peerDependencies:
- '@better-auth/core': 1.5.6
- '@better-auth/utils': ^0.3.0
- kysely: ^0.27.0 || ^0.28.0
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
+ kysely: ^0.28.17 || ^0.29.0
peerDependenciesMeta:
kysely:
optional: true
- '@better-auth/memory-adapter@1.5.6':
- resolution: {integrity: sha512-rS7ZsrIl5uvloUgNN0u9LOZJMMXnsZXVdUZ3MrTBKWM2KpoJjzPr9yN3Szyma5+0V7SltnzSGHPkYj2bEzzmlA==}
+ '@better-auth/memory-adapter@1.6.23':
+ resolution: {integrity: sha512-krIiR0pIVkaKlAzm690n5bcMW4NGbqeMg0HQSD9fz/KcQF/eWLqcq9gG/BhHTj2i/y96qH+W5JWPmaSOS5iTgQ==}
peerDependencies:
- '@better-auth/core': 1.5.6
- '@better-auth/utils': ^0.3.0
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
- '@better-auth/mongo-adapter@1.5.6':
- resolution: {integrity: sha512-6+M3MS2mor8fTUV3EI1FBLP0cs6QfbN+Ovx9+XxR/GdfKIBoNFzmPEPRbdGt+ft6PvrITsUm+T70+kkHgVSP6w==}
+ '@better-auth/mongo-adapter@1.6.23':
+ resolution: {integrity: sha512-7+QdevitGlKBbP6JbiSk5SBnzPsKV/mDrQBGBn8hwByQLeJwqpqbuBPw7ZI8vzUlFfAAnyFiqwP3Eb8mxnp7pA==}
peerDependencies:
- '@better-auth/core': 1.5.6
- '@better-auth/utils': ^0.3.0
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
mongodb: ^6.0.0 || ^7.0.0
peerDependenciesMeta:
mongodb:
optional: true
- '@better-auth/prisma-adapter@1.5.6':
- resolution: {integrity: sha512-UxY9vQJs1Tt+O+T2YQnseDMlWmUSQvFZSBb5YiFRg7zcm+TEzujh4iX2/csA0YiZptLheovIuVWTP9nriewEBA==}
+ '@better-auth/oauth-provider@1.6.23':
+ resolution: {integrity: sha512-1sDN+N4Sztmpk8ziCU3MXicxOTfvYoHvHvhJMQ7PSfr+pLXnYN+dJFI9S3zBRwstmTeJx/OhRIZWrwFJ0TgBnA==}
peerDependencies:
- '@better-auth/core': 1.5.6
- '@better-auth/utils': ^0.3.0
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
+ better-auth: ^1.6.23
+ better-call: 1.3.7
+
+ '@better-auth/prisma-adapter@1.6.23':
+ resolution: {integrity: sha512-2qSdzidq4tkb1eS5TTqb4Nzg0mdZWm3Qky9SYeXeb8PpVQbC2sxqJhEM5mK7y12uU6I8hc64wO9f7AFVNL+6UQ==}
+ peerDependencies:
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
'@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
prisma: ^5.0.0 || ^6.0.0 || ^7.0.0
peerDependenciesMeta:
@@ -4705,16 +4728,18 @@ packages:
prisma:
optional: true
- '@better-auth/telemetry@1.5.6':
- resolution: {integrity: sha512-yXC7NSxnIFlxDkGdpD7KA+J9nqIQAPCJKe77GoaC5bWoe/DALo1MYorZfTgOafS7wrslNtsPT4feV/LJi1ubqQ==}
+ '@better-auth/telemetry@1.6.23':
+ resolution: {integrity: sha512-/R2Kb+z2BpDOOWwVHqOk+c0VNpuwfCv4Hp5Yr9003WIZPax/zyNraGLB9CFE8qF2gZW8Dsz419k4I8CPrGzpDA==}
peerDependencies:
- '@better-auth/core': 1.5.6
+ '@better-auth/core': ^1.6.23
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
- '@better-auth/utils@0.3.1':
- resolution: {integrity: sha512-+CGp4UmZSUrHHnpHhLPYu6cV+wSUSvVbZbNykxhUDocpVNTo9uFFxw/NqJlh1iC4wQ9HKKWGCKuZ5wUgS0v6Kg==}
+ '@better-auth/utils@0.4.2':
+ resolution: {integrity: sha512-AUxrvu+HaaODsUyzDxFgwd/8RZ1yZaYo42LXKSrU2oGgR38pS1ij8nqQKNgtTWoYGpNevNXtCfgTy6loHveW9A==}
- '@better-fetch/fetch@1.1.21':
- resolution: {integrity: sha512-/ImESw0sskqlVR94jB+5+Pxjf+xBwDZF/N5+y2/q4EqD7IARUTSpPfIo8uf39SYpCxyOCtbyYpUrZ3F/k0zT4A==}
+ '@better-fetch/fetch@1.3.1':
+ resolution: {integrity: sha512-ABkD1WhyfPZprKRQI3bhATjeiFuNWC9PXhfGWqL+sg/gKrM977oFrYkdb4msM3hgUGonr7KlOsOFT5TU2rht9g==}
'@biomejs/biome@2.3.11':
resolution: {integrity: sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==}
@@ -6866,6 +6891,20 @@ packages:
'@mixmark-io/domino@2.2.0':
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
+ '@modelcontextprotocol/ext-apps@1.7.4':
+ resolution: {integrity: sha512-QQqysE549cf/Y0VabBmAACXhj92EhB3t8yVct2BHbkWiPTFA1S91EqTVjYXXcZEefXU0pmHcdObhsNMcomJIOQ==}
+ engines: {node: '>=20'}
+ peerDependencies:
+ '@modelcontextprotocol/sdk': ^1.29.0
+ react: 19.1.0
+ react-dom: 19.1.0
+ zod: ^3.25.0 || ^4.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-dom:
+ optional: true
+
'@modelcontextprotocol/inspector-cli@0.14.3':
resolution: {integrity: sha512-cAjCfwJUfN1WHc/sGgY/yAQ7K02WOKIso+LzVoKzEr50Nf4R+WKEuq6lhnLfG3f61sU823V8TxRscc8NTYTgww==}
deprecated: 'v1 is deprecated. Upgrade to v2: npm i @modelcontextprotocol/inspector@latest. v1 gets security fixes only, published under the v1-latest tag.'
@@ -11008,8 +11047,8 @@ packages:
bcryptjs@2.4.3:
resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==}
- better-auth@1.5.6:
- resolution: {integrity: sha512-QSpJTqaT1XVfWRQe/fm3PgeuwOIlz1nWX/Dx7nsHStJ382bLzmDbQk2u7IT0IJ6wS5SRxfqEE1Ev9TXontgyAQ==}
+ better-auth@1.6.23:
+ resolution: {integrity: sha512-4vOaRd9UiKGKm9R+ej0jjU1es3MiJIiNc9Qq3VCnYqOZ4/nb5272QqTxWYoDxyUXl5x6A2x2we5KZKQO9teTQQ==}
peerDependencies:
'@lynx-js/react': '*'
'@prisma/client': ^5.0.0 || ^6.0.0 || ^7.0.0
@@ -11018,7 +11057,7 @@ packages:
'@tanstack/solid-start': ^1.0.0
better-sqlite3: ^12.0.0
drizzle-kit: '>=0.31.4'
- drizzle-orm: '>=0.41.0'
+ drizzle-orm: ^0.45.2
mongodb: ^6.0.0 || ^7.0.0
mysql2: ^3.0.0
next: ^14.0.0 || ^15.0.0 || ^16.0.0
@@ -11070,8 +11109,8 @@ packages:
vue:
optional: true
- better-call@1.3.2:
- resolution: {integrity: sha512-4cZIfrerDsNTn3cm+MhLbUePN0gdwkhSXEuG7r/zuQ8c/H7iU0/jSK5TD3FW7U0MgKHce/8jGpPYNO4Ve+4NBw==}
+ better-call@1.3.7:
+ resolution: {integrity: sha512-Al51/hjp2SSp6CRTa3F2ptcx4yQVS1xWKoY6jcVXqNYOap6mHFP2jUBn5EwIL4iIed1/Sq4hlQ+Umm6EflZG+w==}
peerDependencies:
zod: ^4.0.0
peerDependenciesMeta:
@@ -12093,9 +12132,6 @@ packages:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
- defu@6.1.4:
- resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
-
defu@6.1.7:
resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==}
@@ -14126,9 +14162,9 @@ packages:
kubernetes-types@1.30.0:
resolution: {integrity: sha512-Dew1okvhM/SQcIa2rcgujNndZwU8VnSapDgdxlYoB84ZlpAD43U6KLAFqYo17ykSFGHNPrg0qry0bP+GJd9v7Q==}
- kysely@0.28.15:
- resolution: {integrity: sha512-r2clcf7HLWvDXaVUEvQymXJY4i3bSOIV3xsL/Upy3ZfSv5HeKsk9tsqbBptLvth5qHEIhxeHTA2jNLyQABkLBA==}
- engines: {node: '>=20.0.0'}
+ kysely@0.29.5:
+ resolution: {integrity: sha512-ooa+eSbBNPTo3MycPEuW5jdrxQdQwdtB3LC3h43FiXQbIry5tR0C5lDG7eealK0E4D7XjrnOP5DIUg/LyjRMYQ==}
+ engines: {node: '>=22.0.0'}
lan-network@0.1.7:
resolution: {integrity: sha512-mnIlAEMu4OyEvUNdzco9xpuB9YVcPkQec+QsgycBCtPZvEqWPCDPfbAE4OJMdBBWpZWtpCn1xw9jJYlwjWI5zQ==}
@@ -15630,9 +15666,6 @@ packages:
path-to-regexp@6.3.0:
resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==}
- path-to-regexp@8.3.0:
- resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==}
-
path-to-regexp@8.4.2:
resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
@@ -17973,6 +18006,16 @@ packages:
vite-plugin-favicons-inject@2.2.0:
resolution: {integrity: sha512-MaqZE3IjwFffIED38yKcI5BKGkV039N6ilhPeOfW4TILzSKMBNd8Q0ehu0mwbl1emWH2tGcuwV3ZIzDKfb0vIQ==}
+ vite-plugin-singlefile@2.3.3:
+ resolution: {integrity: sha512-XVnGH0QzbOa8fxRSsHdCarVN1BSBXNi7uLMQYlrGRN5apdHkk62XQWRJhVever0lnfuyBkwn+kvVChdm/OoOUg==}
+ engines: {node: '>18.0.0'}
+ peerDependencies:
+ rollup: ^4.59.0
+ vite: ^5.4.21 || ^6.0.0 || ^7.0.0 || ^8.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
vite-plugin-srvx@1.0.2:
resolution: {integrity: sha512-y11gH+CBkbQvfbFE14TJcl7HAkjqaZbGEb3CXnEdu0fXlsPzHJST7Khyq021WKOWbDYb8PaCabjzMQ+pS1oDPw==}
peerDependencies:
@@ -20190,59 +20233,69 @@ snapshots:
'@bcoe/v8-coverage@1.0.2': {}
- '@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)':
+ '@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)':
dependencies:
- '@better-auth/utils': 0.3.1
- '@better-fetch/fetch': 1.1.21
- '@opentelemetry/api': 1.9.0
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
'@opentelemetry/semantic-conventions': 1.40.0
'@standard-schema/spec': 1.1.0
- better-call: 1.3.2(zod@4.3.6)
+ better-call: 1.3.7(zod@3.25.76)
jose: 6.1.3
- kysely: 0.28.15
+ kysely: 0.29.5
nanostores: 1.2.0
zod: 4.3.6
optionalDependencies:
'@cloudflare/workers-types': 4.20251014.0
+ '@opentelemetry/api': 1.9.0
- '@better-auth/drizzle-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))':
+ '@better-auth/drizzle-adapter@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
- optionalDependencies:
- drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
- '@better-auth/kysely-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.15)':
+ '@better-auth/kysely-adapter@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
optionalDependencies:
- kysely: 0.28.15
+ kysely: 0.29.5
- '@better-auth/memory-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)':
+ '@better-auth/memory-adapter@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
- '@better-auth/mongo-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)':
+ '@better-auth/mongo-adapter@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
- '@better-auth/prisma-adapter@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)':
+ '@better-auth/oauth-provider@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(better-auth@1.6.23(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0)))(better-call@1.3.7(zod@3.25.76))':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
+ better-auth: 1.6.23(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))
+ better-call: 1.3.7(zod@3.25.76)
+ jose: 6.1.3
+ zod: 4.3.6
- '@better-auth/telemetry@1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))':
+ '@better-auth/prisma-adapter@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)':
dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/utils': 0.3.1
- '@better-fetch/fetch': 1.1.21
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
- '@better-auth/utils@0.3.1': {}
+ '@better-auth/telemetry@1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)':
+ dependencies:
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
- '@better-fetch/fetch@1.1.21': {}
+ '@better-auth/utils@0.4.2':
+ dependencies:
+ '@noble/hashes': 2.0.1
+
+ '@better-fetch/fetch@1.3.1': {}
'@biomejs/biome@2.3.11':
optionalDependencies:
@@ -22636,6 +22689,15 @@ snapshots:
'@mixmark-io/domino@2.2.0': {}
+ '@modelcontextprotocol/ext-apps@1.7.4(@modelcontextprotocol/sdk@1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(zod@3.25.76)':
+ dependencies:
+ '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)
+ '@standard-schema/spec': 1.1.0
+ zod: 3.25.76
+ optionalDependencies:
+ react: 19.1.0
+ react-dom: 19.1.0(react@19.1.0)
+
'@modelcontextprotocol/inspector-cli@0.14.3(@cfworker/json-schema@4.1.1)(zod@3.25.76)':
dependencies:
'@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)
@@ -22693,12 +22755,12 @@ snapshots:
- supports-color
- utf-8-validate
- '@modelcontextprotocol/inspector@0.14.3(@cfworker/json-schema@4.1.1)(@swc/core@1.15.11(@swc/helpers@0.5.17))(@types/node@22.19.10)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(hono@4.12.25)(typescript@5.9.3)':
+ '@modelcontextprotocol/inspector@0.14.3(@cfworker/json-schema@4.1.1)(@swc/core@1.15.11(@swc/helpers@0.5.17))(@types/node@22.19.10)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)(typescript@5.9.3)':
dependencies:
'@modelcontextprotocol/inspector-cli': 0.14.3(@cfworker/json-schema@4.1.1)(zod@3.25.76)
'@modelcontextprotocol/inspector-client': 0.14.3(@cfworker/json-schema@4.1.1)(@types/react-dom@19.2.3(@types/react@19.2.13))(@types/react@19.2.13)
'@modelcontextprotocol/inspector-server': 0.14.3(@cfworker/json-schema@4.1.1)
- '@modelcontextprotocol/sdk': 1.25.3(@cfworker/json-schema@4.1.1)(hono@4.12.25)(zod@3.25.76)
+ '@modelcontextprotocol/sdk': 1.29.0(@cfworker/json-schema@4.1.1)(zod@3.25.76)
concurrently: 9.2.1
open: 10.2.0
shell-quote: 1.8.3
@@ -22713,7 +22775,6 @@ snapshots:
- '@types/react'
- '@types/react-dom'
- bufferutil
- - hono
- supports-color
- tailwindcss
- typescript
@@ -27768,29 +27829,28 @@ snapshots:
bcryptjs@2.4.3: {}
- better-auth@1.5.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0)):
- dependencies:
- '@better-auth/core': 1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0)
- '@better-auth/drizzle-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))
- '@better-auth/kysely-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)(kysely@0.28.15)
- '@better-auth/memory-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)
- '@better-auth/mongo-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)
- '@better-auth/prisma-adapter': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))(@better-auth/utils@0.3.1)
- '@better-auth/telemetry': 1.5.6(@better-auth/core@1.5.6(@better-auth/utils@0.3.1)(@better-fetch/fetch@1.1.21)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.2(zod@3.25.76))(jose@6.1.3)(kysely@0.28.15)(nanostores@1.2.0))
- '@better-auth/utils': 0.3.1
- '@better-fetch/fetch': 1.1.21
+ better-auth@1.6.23(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-sqlite3@12.8.0)(drizzle-kit@0.31.5)(next@16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2))(pg@8.17.2)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(vitest@4.0.18(@opentelemetry/api@1.9.0)(@types/node@20.19.13)(jiti@1.21.7)(less@4.4.1)(lightningcss@1.32.0)(msw@2.14.4(@types/node@20.19.13)(typescript@5.9.3))(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0)):
+ dependencies:
+ '@better-auth/core': 1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0)
+ '@better-auth/drizzle-adapter': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)
+ '@better-auth/kysely-adapter': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(kysely@0.29.5)
+ '@better-auth/memory-adapter': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)
+ '@better-auth/mongo-adapter': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)
+ '@better-auth/prisma-adapter': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)
+ '@better-auth/telemetry': 1.6.23(@better-auth/core@1.6.23(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(better-call@1.3.7(zod@4.3.6))(jose@6.1.3)(kysely@0.29.5)(nanostores@1.2.0))(@better-auth/utils@0.4.2)(@better-fetch/fetch@1.3.1)
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
'@noble/ciphers': 2.1.1
'@noble/hashes': 2.0.1
- better-call: 1.3.2(zod@4.3.6)
- defu: 6.1.4
+ better-call: 1.3.7(zod@3.25.76)
+ defu: 6.1.7
jose: 6.1.3
- kysely: 0.28.15
+ kysely: 0.29.5
nanostores: 1.2.0
zod: 4.3.6
optionalDependencies:
better-sqlite3: 12.8.0
drizzle-kit: 0.31.5
- drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
next: 16.1.4(@babel/core@7.29.0)(@opentelemetry/api@1.9.0)(@playwright/test@1.57.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)(sass@1.93.2)
pg: 8.17.2
react: 19.1.0
@@ -27800,14 +27860,14 @@ snapshots:
- '@cloudflare/workers-types'
- '@opentelemetry/api'
- better-call@1.3.2(zod@4.3.6):
+ better-call@1.3.7(zod@3.25.76):
dependencies:
- '@better-auth/utils': 0.3.1
- '@better-fetch/fetch': 1.1.21
+ '@better-auth/utils': 0.4.2
+ '@better-fetch/fetch': 1.3.1
rou3: 0.7.12
set-cookie-parser: 3.1.0
optionalDependencies:
- zod: 4.3.6
+ zod: 3.25.76
better-opn@3.0.2:
dependencies:
@@ -28829,10 +28889,10 @@ snapshots:
dayjs@1.11.19: {}
- db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)):
+ db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)):
optionalDependencies:
better-sqlite3: 12.8.0
- drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)
+ drizzle-orm: 0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)
de-indent@1.0.2: {}
@@ -28911,8 +28971,6 @@ snapshots:
has-property-descriptors: 1.0.2
object-keys: 1.1.1
- defu@6.1.4: {}
-
defu@6.1.7: {}
degenerator@5.0.1:
@@ -29018,7 +29076,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
- drizzle-orm@0.38.4(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/react@19.2.13)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(react@19.1.0)(sql.js@1.13.0):
+ drizzle-orm@0.38.4(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/react@19.2.13)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(react@19.1.0)(sql.js@1.13.0):
optionalDependencies:
'@cloudflare/workers-types': 4.20251014.0
'@opentelemetry/api': 1.9.0
@@ -29028,12 +29086,12 @@ snapshots:
'@types/sql.js': 1.4.9
better-sqlite3: 12.8.0
bun-types: 1.3.11
- kysely: 0.28.15
+ kysely: 0.29.5
pg: 8.17.2
react: 19.1.0
sql.js: 1.13.0
- drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0):
+ drizzle-orm@0.44.6(@cloudflare/workers-types@4.20251014.0)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0):
optionalDependencies:
'@cloudflare/workers-types': 4.20251014.0
'@opentelemetry/api': 1.9.0
@@ -29042,7 +29100,7 @@ snapshots:
'@types/sql.js': 1.4.9
better-sqlite3: 12.8.0
bun-types: 1.3.11
- kysely: 0.28.15
+ kysely: 0.29.5
pg: 8.17.2
sql.js: 1.13.0
@@ -31136,7 +31194,7 @@ snapshots:
kubernetes-types@1.30.0: {}
- kysely@0.28.15: {}
+ kysely@0.29.5: {}
lan-network@0.1.7: {}
@@ -32712,11 +32770,11 @@ snapshots:
nf3@0.3.22: {}
- nitro@3.0.260610-beta(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(better-sqlite3@12.8.0)(chokidar@5.0.0)(dotenv@17.4.2)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))(giget@3.3.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.2.6)(miniflare@4.20260611.0)(rollup@4.62.2)(vite@7.3.1(@types/node@24.7.1)(jiti@2.7.0)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))(wrangler@4.100.0)(xml2js@0.6.2):
+ nitro@3.0.260610-beta(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(better-sqlite3@12.8.0)(chokidar@5.0.0)(dotenv@17.4.2)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0))(giget@3.3.0)(ioredis@5.10.1)(jiti@2.7.0)(lru-cache@11.2.6)(miniflare@4.20260611.0)(rollup@4.62.2)(vite@7.3.1(@types/node@24.7.1)(jiti@2.7.0)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)(tsx@4.23.1)(yaml@2.9.0))(wrangler@4.100.0)(xml2js@0.6.2):
dependencies:
consola: 3.4.2
crossws: 0.4.10(srvx@0.11.22)
- db0: 0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))
+ db0: 0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0))
env-runner: 0.1.16(miniflare@4.20260611.0)(wrangler@4.100.0)
h3: 2.0.1-rc.22(crossws@0.4.10(srvx@0.11.22))
hookable: 6.1.1
@@ -32727,7 +32785,7 @@ snapshots:
rolldown: 1.2.0
srvx: 0.11.22
unenv: 2.0.0-rc.24
- unstorage: 2.0.0-alpha.7(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(chokidar@5.0.0)(db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)))(ioredis@5.10.1)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3)
+ unstorage: 2.0.0-alpha.7(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(chokidar@5.0.0)(db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)))(ioredis@5.10.1)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3)
optionalDependencies:
dotenv: 17.4.2
giget: 3.3.0
@@ -33259,8 +33317,6 @@ snapshots:
path-to-regexp@6.3.0: {}
- path-to-regexp@8.3.0: {}
-
path-to-regexp@8.4.2: {}
path-type@4.0.0: {}
@@ -34426,7 +34482,7 @@ snapshots:
depd: 2.0.0
is-promise: 4.0.0
parseurl: 1.3.3
- path-to-regexp: 8.3.0
+ path-to-regexp: 8.4.2
transitivePeerDependencies:
- supports-color
@@ -35922,11 +35978,11 @@ snapshots:
picomatch: 4.0.3
webpack-virtual-modules: 0.6.2
- unstorage@2.0.0-alpha.7(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(chokidar@5.0.0)(db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0)))(ioredis@5.10.1)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3):
+ unstorage@2.0.0-alpha.7(@vercel/functions@3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1))(chokidar@5.0.0)(db0@0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0)))(ioredis@5.10.1)(lru-cache@11.2.6)(ofetch@2.0.0-alpha.3):
optionalDependencies:
'@vercel/functions': 3.7.5(@aws-sdk/credential-provider-web-identity@3.972.49)(ws@8.20.1)
chokidar: 5.0.0
- db0: 0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.28.15)(pg@8.17.2)(sql.js@1.13.0))
+ db0: 0.3.4(better-sqlite3@12.8.0)(drizzle-orm@0.44.6(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.16.0)(@types/sql.js@1.4.9)(better-sqlite3@12.8.0)(bun-types@1.3.11)(kysely@0.29.5)(pg@8.17.2)(sql.js@1.13.0))
ioredis: 5.10.1
lru-cache: 11.2.6
ofetch: 2.0.0-alpha.3
@@ -36219,6 +36275,13 @@ snapshots:
dependencies:
favicons: 7.2.0
+ vite-plugin-singlefile@2.3.3(rollup@4.62.2)(vite@5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)):
+ dependencies:
+ micromatch: 4.0.8
+ vite: 5.4.21(@types/node@20.19.13)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)
+ optionalDependencies:
+ rollup: 4.62.2
+
vite-plugin-srvx@1.0.2(srvx@0.10.0)(vite@5.4.21(@types/node@22.19.15)(less@4.4.1)(lightningcss@1.32.0)(sass@1.93.2)(stylus@0.62.0)(terser@5.46.0)):
dependencies:
srvx: 0.10.0