export const OpenWorkConnectInstaller = () => { const MCP_SERVER_URL = "https://api.openworklabs.com/mcp/agent"; const CODEX_CONNECTIONS_DEEPLINK = "codex://settings/connections"; const CHATGPT_SETTINGS_URL = "https://chatgpt.com/#settings/Connectors"; const CODEX_LOGIN_COMMAND = "codex mcp login openwork"; const CODEX_RECONNECT_COMMAND = `codex mcp logout openwork codex mcp login openwork`; const OPENCODE_AUTH_COMMAND = "opencode mcp auth openwork"; const OPENCODE_RECONNECT_COMMAND = `opencode mcp logout openwork opencode mcp auth openwork`; const installs = [ { id: "cursor", label: "Cursor", eyebrow: "Cursor Desktop and Web/Agents", helper: "Setup-only for Cursor Desktop and Cursor Web/Agents. Cursor Desktop's OAuth callback cursor://anysphere.cursor-mcp/oauth/callback is accepted with PKCE S256 enforced.", supportStatus: "Setup only", supportExplanation: "Setup guide only: paste the server URL into Cursor and start OAuth. Cursor Desktop's cursor://anysphere.cursor-mcp/oauth/callback callback is accepted through an exact allowlist with PKCE S256 enforced. Native proof is not complete.", copyText: MCP_SERVER_URL, }, { id: "codex", label: "Codex", eyebrow: "Codex desktop, CLI, and IDE", helper: "Add OpenWork once, then sign in with Codex's MCP login command.", supportStatus: "Setup only", supportExplanation: "Setup guide only: add OpenWork, run codex mcp login openwork, and reconnect with logout then login. Native proof must be rerun on this exact branch.", copyText: `codex mcp add openwork --url ${MCP_SERVER_URL}`, authText: CODEX_LOGIN_COMMAND, reconnectText: CODEX_RECONNECT_COMMAND, }, { id: "chatgpt-desktop", label: "ChatGPT Desktop", eyebrow: "Guided desktop setup", helper: "Open ChatGPT Settings > MCP servers, paste this URL, then start OAuth from ChatGPT's connection prompt.", supportStatus: "Setup only", supportExplanation: "Setup guide only: paste the URL in ChatGPT Settings > MCP servers and start OAuth there. Native proof is not complete.", copyText: MCP_SERVER_URL, }, { id: "claude-code", label: "Claude Code", eyebrow: "One terminal command", helper: "Add the remote HTTP server, then use /mcp in Claude Code and follow the client auth flow.", supportStatus: "Setup only", supportExplanation: "Setup guide only: add the server, then use /mcp in Claude Code to run the client auth flow. Native proof is not complete.", copyText: `claude mcp add --transport http openwork ${MCP_SERVER_URL}`, }, { id: "opencode", label: "OpenCode", eyebrow: "opencode.json MCP config", helper: "Add this remote MCP server entry to your OpenCode config, then authenticate.", supportStatus: "Verified", supportExplanation: "Verified with OpenCode native remote MCP OAuth flow.", copyText: `{ "mcp": { "openwork": { "type": "remote", "enabled": true, "url": "${MCP_SERVER_URL}", "oauth": {} } } }`, authText: OPENCODE_AUTH_COMMAND, reconnectText: OPENCODE_RECONNECT_COMMAND, }, { id: "vs-code", label: "VS Code", eyebrow: "VS Code MCP command", helper: "Run this from a shell with the VS Code CLI on your path, then start OAuth from VS Code's MCP server prompt.", supportStatus: "Setup only", supportExplanation: "Setup guide only: add the server with the VS Code CLI, then start OAuth from VS Code's MCP server prompt. Native proof is not complete.", copyText: `code --add-mcp '{"name":"openwork","type":"http","url":"${MCP_SERVER_URL}"}'`, }, { id: "any-client", label: "Any client", eyebrow: "Bring your own MCP client", helper: "Paste this URL only into clients that support remote Streamable HTTP MCP servers and OAuth.", supportStatus: "Setup only", supportExplanation: "Setup guide only: use clients that support remote Streamable HTTP MCP servers and OAuth. Native proof depends on the client.", copyText: MCP_SERVER_URL, }, ]; const clientFromHash = () => { if (typeof window === "undefined") return "cursor"; const requested = window.location.hash.slice(1).replace("connect-mcp-install-", ""); return installs.some((install) => install.id === requested) ? requested : "cursor"; }; const copyText = async (value) => { try { await navigator.clipboard.writeText(value); return true; } catch { const textarea = document.createElement("textarea"); textarea.value = value; textarea.setAttribute("readonly", ""); textarea.style.cssText = "position:absolute;left:-9999px;top:-9999px"; document.body.appendChild(textarea); textarea.select(); const didCopy = document.execCommand("copy"); textarea.remove(); return didCopy; } }; const [activeClient, setActiveClient] = useState(clientFromHash); const [copied, setCopied] = useState(""); const activeInstall = installs.find((install) => install.id === activeClient) || installs[0]; useEffect(() => { const selectHashClient = () => setActiveClient(clientFromHash()); window.addEventListener("hashchange", selectHashClient); selectHashClient(); return () => window.removeEventListener("hashchange", selectHashClient); }, []); const copy = async (id, value) => { const didCopy = await copyText(value); setCopied(didCopy ? id : "error"); window.setTimeout(() => setCopied(""), 2500); }; return (
{activeInstall.eyebrow}
{activeInstall.helper}
{activeInstall.copyText}
{activeInstall.id === "any-client" ? (
Use this URL only with MCP clients that support remote Streamable HTTP servers with OAuth.
) : null} {activeInstall.authText ? (Authenticate
{activeInstall.authText}
Reconnect or switch org
{activeInstall.reconnectText}
Works with your OpenWork account — create one free.
{MCP_SERVER_URL}