diff --git a/apps/cloud/src/routeTree.gen.ts b/apps/cloud/src/routeTree.gen.ts
index bc0ab8b70..ecffa48b2 100644
--- a/apps/cloud/src/routeTree.gen.ts
+++ b/apps/cloud/src/routeTree.gen.ts
@@ -10,9 +10,11 @@
import { Route as rootRouteImport } from './routes/__root'
import { Route as ToolsRouteImport } from './routes/tools'
+import { Route as SetupMcpRouteImport } from './routes/setup-mcp'
import { Route as SecretsRouteImport } from './routes/secrets'
import { Route as PoliciesRouteImport } from './routes/policies'
import { Route as OrgRouteImport } from './routes/org'
+import { Route as CreateOrgRouteImport } from './routes/create-org'
import { Route as ConnectionsRouteImport } from './routes/connections'
import { Route as BillingRouteImport } from './routes/billing'
import { Route as ApiKeysRouteImport } from './routes/api-keys'
@@ -26,6 +28,11 @@ const ToolsRoute = ToolsRouteImport.update({
path: '/tools',
getParentRoute: () => rootRouteImport,
} as any)
+const SetupMcpRoute = SetupMcpRouteImport.update({
+ id: '/setup-mcp',
+ path: '/setup-mcp',
+ getParentRoute: () => rootRouteImport,
+} as any)
const SecretsRoute = SecretsRouteImport.update({
id: '/secrets',
path: '/secrets',
@@ -41,6 +48,11 @@ const OrgRoute = OrgRouteImport.update({
path: '/org',
getParentRoute: () => rootRouteImport,
} as any)
+const CreateOrgRoute = CreateOrgRouteImport.update({
+ id: '/create-org',
+ path: '/create-org',
+ getParentRoute: () => rootRouteImport,
+} as any)
const ConnectionsRoute = ConnectionsRouteImport.update({
id: '/connections',
path: '/connections',
@@ -82,9 +94,11 @@ export interface FileRoutesByFullPath {
'/api-keys': typeof ApiKeysRoute
'/billing': typeof BillingRoute
'/connections': typeof ConnectionsRoute
+ '/create-org': typeof CreateOrgRoute
'/org': typeof OrgRoute
'/policies': typeof PoliciesRoute
'/secrets': typeof SecretsRoute
+ '/setup-mcp': typeof SetupMcpRoute
'/tools': typeof ToolsRoute
'/billing/plans': typeof BillingPlansRoute
'/sources/$namespace': typeof SourcesNamespaceRoute
@@ -95,9 +109,11 @@ export interface FileRoutesByTo {
'/api-keys': typeof ApiKeysRoute
'/billing': typeof BillingRoute
'/connections': typeof ConnectionsRoute
+ '/create-org': typeof CreateOrgRoute
'/org': typeof OrgRoute
'/policies': typeof PoliciesRoute
'/secrets': typeof SecretsRoute
+ '/setup-mcp': typeof SetupMcpRoute
'/tools': typeof ToolsRoute
'/billing/plans': typeof BillingPlansRoute
'/sources/$namespace': typeof SourcesNamespaceRoute
@@ -109,9 +125,11 @@ export interface FileRoutesById {
'/api-keys': typeof ApiKeysRoute
'/billing': typeof BillingRoute
'/connections': typeof ConnectionsRoute
+ '/create-org': typeof CreateOrgRoute
'/org': typeof OrgRoute
'/policies': typeof PoliciesRoute
'/secrets': typeof SecretsRoute
+ '/setup-mcp': typeof SetupMcpRoute
'/tools': typeof ToolsRoute
'/billing_/plans': typeof BillingPlansRoute
'/sources/$namespace': typeof SourcesNamespaceRoute
@@ -124,9 +142,11 @@ export interface FileRouteTypes {
| '/api-keys'
| '/billing'
| '/connections'
+ | '/create-org'
| '/org'
| '/policies'
| '/secrets'
+ | '/setup-mcp'
| '/tools'
| '/billing/plans'
| '/sources/$namespace'
@@ -137,9 +157,11 @@ export interface FileRouteTypes {
| '/api-keys'
| '/billing'
| '/connections'
+ | '/create-org'
| '/org'
| '/policies'
| '/secrets'
+ | '/setup-mcp'
| '/tools'
| '/billing/plans'
| '/sources/$namespace'
@@ -150,9 +172,11 @@ export interface FileRouteTypes {
| '/api-keys'
| '/billing'
| '/connections'
+ | '/create-org'
| '/org'
| '/policies'
| '/secrets'
+ | '/setup-mcp'
| '/tools'
| '/billing_/plans'
| '/sources/$namespace'
@@ -164,9 +188,11 @@ export interface RootRouteChildren {
ApiKeysRoute: typeof ApiKeysRoute
BillingRoute: typeof BillingRoute
ConnectionsRoute: typeof ConnectionsRoute
+ CreateOrgRoute: typeof CreateOrgRoute
OrgRoute: typeof OrgRoute
PoliciesRoute: typeof PoliciesRoute
SecretsRoute: typeof SecretsRoute
+ SetupMcpRoute: typeof SetupMcpRoute
ToolsRoute: typeof ToolsRoute
BillingPlansRoute: typeof BillingPlansRoute
SourcesNamespaceRoute: typeof SourcesNamespaceRoute
@@ -182,6 +208,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof ToolsRouteImport
parentRoute: typeof rootRouteImport
}
+ '/setup-mcp': {
+ id: '/setup-mcp'
+ path: '/setup-mcp'
+ fullPath: '/setup-mcp'
+ preLoaderRoute: typeof SetupMcpRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/secrets': {
id: '/secrets'
path: '/secrets'
@@ -203,6 +236,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof OrgRouteImport
parentRoute: typeof rootRouteImport
}
+ '/create-org': {
+ id: '/create-org'
+ path: '/create-org'
+ fullPath: '/create-org'
+ preLoaderRoute: typeof CreateOrgRouteImport
+ parentRoute: typeof rootRouteImport
+ }
'/connections': {
id: '/connections'
path: '/connections'
@@ -260,9 +300,11 @@ const rootRouteChildren: RootRouteChildren = {
ApiKeysRoute: ApiKeysRoute,
BillingRoute: BillingRoute,
ConnectionsRoute: ConnectionsRoute,
+ CreateOrgRoute: CreateOrgRoute,
OrgRoute: OrgRoute,
PoliciesRoute: PoliciesRoute,
SecretsRoute: SecretsRoute,
+ SetupMcpRoute: SetupMcpRoute,
ToolsRoute: ToolsRoute,
BillingPlansRoute: BillingPlansRoute,
SourcesNamespaceRoute: SourcesNamespaceRoute,
diff --git a/apps/cloud/src/routes/__root.tsx b/apps/cloud/src/routes/__root.tsx
index 334fbe9ef..787206f06 100644
--- a/apps/cloud/src/routes/__root.tsx
+++ b/apps/cloud/src/routes/__root.tsx
@@ -1,6 +1,13 @@
import React from "react";
import * as Sentry from "@sentry/react";
-import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router";
+import {
+ HeadContent,
+ Outlet,
+ Scripts,
+ createRootRoute,
+ useLocation,
+ useNavigate,
+} from "@tanstack/react-router";
import { AutumnProvider } from "autumn-js/react";
import posthog from "posthog-js";
import { PostHogProvider } from "posthog-js/react";
@@ -13,10 +20,11 @@ import { plugins as clientPlugins } from "virtual:executor/plugins-client";
import { AuthProvider, useAuth } from "../web/auth";
import { SupportOptions } from "../web/components/support-options";
import { LoginPage } from "../web/pages/login";
-import { OnboardingPage } from "../web/pages/onboarding";
import { Shell } from "../web/shell";
import appCss from "@executor-js/react/globals.css?url";
+const ONBOARDING_PATHS = new Set(["/create-org", "/setup-mcp"]);
+
if (typeof window !== "undefined" && import.meta.env.VITE_PUBLIC_SENTRY_DSN) {
Sentry.init({
dsn: import.meta.env.VITE_PUBLIC_SENTRY_DSN,
@@ -198,6 +206,18 @@ function ShellErrorFallback() {
function AuthGate() {
const auth = useAuth();
+ const location = useLocation();
+ const navigate = useNavigate();
+ const isOnboardingRoute = ONBOARDING_PATHS.has(location.pathname);
+
+ const needsOrgRedirect =
+ auth.status === "authenticated" && auth.organization == null && !isOnboardingRoute;
+
+ React.useEffect(() => {
+ if (needsOrgRedirect) {
+ void navigate({ to: "/create-org", replace: true });
+ }
+ }, [needsOrgRedirect, navigate]);
if (auth.status === "loading") {
return
+ Step 1 of 2 +
+ Step 2 of 2 +
++ Executor exposes your sources, secrets, and tools to any MCP-compatible agent. Copy the + URL into your client, or run the install command. +
++ MCP server URL +
+Paste this into your MCP client config.
++ Install command +
+Adds the server to a supported agent.
+