diff --git a/surfsense_web/app/(home)/mcp-server/page.tsx b/surfsense_web/app/(home)/mcp-server/page.tsx
index 6dfc69622..5e4961b1e 100644
--- a/surfsense_web/app/(home)/mcp-server/page.tsx
+++ b/surfsense_web/app/(home)/mcp-server/page.tsx
@@ -50,16 +50,13 @@ export const metadata: Metadata = {
},
};
-/* Mirrors surfsense_mcp/README.md: the real Cursor config. */
+/* The hosted Cursor config; mirrors lib/mcp/clients.ts. */
const CURSOR_CONFIG = `{
"mcpServers": {
"surfsense": {
- "command": "uv",
- "args": ["run", "--directory", ".../surfsense_mcp",
- "python", "-m", "surfsense_mcp"],
- "env": {
- "SURFSENSE_BASE_URL": "https://api.surfsense.com",
- "SURFSENSE_API_KEY": "ss_pat_..."
+ "url": "https://mcp.surfsense.com/mcp",
+ "headers": {
+ "Authorization": "Bearer ss_pat_..."
}
}
}
@@ -76,7 +73,7 @@ const STEPS = [
icon: TerminalSquare,
title: "Add the server to your client",
description:
- "Drop the config into Cursor's mcp.json, run claude mcp add for Claude Code, or paste it into Claude Desktop. Point it at the cloud or your own self-hosted instance.",
+ "Point your client at https://mcp.surfsense.com/mcp with your key in an Authorization header — the hosted config for Cursor, Claude Code, and others is one paste. Prefer stdio? Switch to Self-host and run it against your own backend.",
},
{
icon: Server,
@@ -135,7 +132,7 @@ const FAQ: FaqItem[] = [
{
question: "Which MCP clients does it work with?",
answer:
- "Any MCP client that supports stdio servers. Claude Code, Codex, OpenCode, Cursor, Claude Desktop, VS Code, Windsurf, and Gemini CLI are documented with copy-paste configs on this page, and the same command works in custom agent harnesses built on the MCP SDK.",
+ "Any MCP client that speaks remote (streamable HTTP) or stdio. Claude Code, Codex, OpenCode, Cursor, Claude Desktop, VS Code, Windsurf, and Gemini CLI all have copy-paste configs on this page — Hosted for the one-paste https://mcp.surfsense.com/mcp endpoint, or Self-host for stdio against your own backend.",
},
{
question: "How is usage billed?",
@@ -278,9 +275,9 @@ export default function McpServerPage() {
Step-by-step setup for every agent
- Pick your client, follow its two steps, and paste the config. Replace the placeholder
- path with your surfsense_mcp checkout and the key with one from API Playground → API
- Keys — or grab a pre-filled config from the playground itself.
+ Pick your client, choose Hosted or Self-host, and
+ paste the config. Replace the key with one from API Playground → API Keys — or grab a
+ pre-filled config from the playground itself.
diff --git a/surfsense_web/components/connectors-marketing/api-mcp-tabs.tsx b/surfsense_web/components/connectors-marketing/api-mcp-tabs.tsx
index 6ca19c47b..f25faf95b 100644
--- a/surfsense_web/components/connectors-marketing/api-mcp-tabs.tsx
+++ b/surfsense_web/components/connectors-marketing/api-mcp-tabs.tsx
@@ -206,7 +206,7 @@ function buildMcp({ mcpTool }: ApiSample): string {
const config = {
mcpServers: {
surfsense: {
- url: "https://mcp.surfsense.com",
+ url: "https://mcp.surfsense.com/mcp",
headers: { Authorization: "Bearer ${SURFSENSE_API_KEY}" },
},
},
diff --git a/surfsense_web/components/mcp/agent-setup-tabs.tsx b/surfsense_web/components/mcp/agent-setup-tabs.tsx
index 1701b8924..3790441f2 100644
--- a/surfsense_web/components/mcp/agent-setup-tabs.tsx
+++ b/surfsense_web/components/mcp/agent-setup-tabs.tsx
@@ -9,6 +9,8 @@ import {
DEFAULT_SERVER_DIR,
MCP_CLIENTS,
type McpSnippetOptions,
+ type McpTransport,
+ REMOTE_URL,
} from "@/lib/mcp/clients";
function CopyButton({ text }: { text: string }) {
@@ -38,48 +40,82 @@ function CopyButton({ text }: { text: string }) {
);
}
+const TRANSPORTS: { id: McpTransport; label: string; hint: string }[] = [
+ { id: "remote", label: "Hosted", hint: "mcp.surfsense.com — nothing to install" },
+ { id: "stdio", label: "Self-host", hint: "run the server against your own backend" },
+];
+
/**
- * Per-agent MCP setup instructions as tabs: pick a client, follow its steps,
- * copy its exact config. Used on the /mcp-server marketing page and in the
- * API playground; `options` fills in real values where the caller has them.
+ * Per-agent MCP setup instructions as tabs: pick a client, then Hosted or
+ * Self-host, and copy its exact config. Used on the /mcp-server marketing page
+ * and in the API playground; `options` fills in real values where the caller
+ * has them.
*/
export function AgentSetupTabs({ options }: { options?: Partial }) {
+ const [transport, setTransport] = useState("remote");
+
const resolved: McpSnippetOptions = {
- baseUrl: options?.baseUrl || "https://api.surfsense.com",
+ remoteUrl: options?.remoteUrl || REMOTE_URL,
apiKey: options?.apiKey || API_KEY_PLACEHOLDER,
+ baseUrl: options?.baseUrl || "https://api.surfsense.com",
serverDir: options?.serverDir || DEFAULT_SERVER_DIR,
};
+ const active = TRANSPORTS.find((t) => t.id === transport) ?? TRANSPORTS[0];
+
return (
-
-
- {MCP_CLIENTS.map((client) => (
-
- {client.label}
-
- ))}
-
- {MCP_CLIENTS.map((client) => {
- const config = client.buildConfig(resolved);
- return (
-
-
- {client.steps.map((step) => (
-