UNPKG

@essentialai/cogent-bridge

Version:

Cogent Bridge — cross-agent comms for Claude Code, OpenAI Codex and Slack. Codex users: install with `curl -fsSL https://cogent.tools/install.sh | sh`, then start with `cogent-codex` for real-time peer wake.

123 lines • 5.96 kB
import crypto from "node:crypto"; import { z } from "zod"; import { getConfig } from "../config.js"; import { successResult, errorResult } from "../errors.js"; import { saveCredentials, markJoinedInProcess, markCloudAttemptInProcess } from "../cloud/credential-store.js"; import { logger } from "../logger.js"; /** * Register the cogent_create_session MCP tool. * * Creates a new cloud bridge session on the relay server. * Only available when COGENT_ENDPOINT is configured. * After creation, persists credentials locally and reinitializes * the cloud backend so runtime HttpClient and CloudWsClient use * the new token/sessionId. */ export function registerCreateSessionTool(server) { server.registerTool("cogent_create_session", { title: "Create Cloud Session", description: "Create a new cloud bridge session on the relay server. " + "Returns session ID and secret for other peers to join. " + "Only available when COGENT_ENDPOINT is configured.", inputSchema: { label: z .string() .optional() .describe("Human-readable label for the session"), secret: z .string() .min(8) .optional() .describe("Shared secret for session authentication (min 8 chars). " + "Auto-generated if omitted."), }, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: true, }, }, async ({ label, secret }) => { try { // Record that a cloud create was ATTEMPTED (before any network call), so a // subsequent cogent_register_peer can tell a failed create from "no cloud // attempt at all" and refuse to silently fall back (T0.1, shipped 3.12.5). markCloudAttemptInProcess(); const config = getConfig(); if (!config.COGENT_ENDPOINT) { return errorResult(new Error("COGENT_ENDPOINT not configured. Set it to use cloud mode.")); } // Generate secret if not provided (32 hex chars, well above min 8) const sessionSecret = secret ?? crypto.randomBytes(16).toString("hex"); // POST to create session (unauthenticated endpoint -- no token yet) const resp = await fetch(`${config.COGENT_ENDPOINT}/api/sessions`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ secret: sessionSecret, label }), }); if (!resp.ok) { const body = await resp.text().catch(() => ""); return errorResult(new Error(`Failed to create session: HTTP ${resp.status}${body ? ` - ${body}` : ""}`)); } const data = (await resp.json()); // Persist credentials locally (include label for future resolution) await saveCredentials({ endpoint: config.COGENT_ENDPOINT, sessionId: data.sessionId, token: data.token, label: data.label, savedAt: new Date().toISOString(), }); // Gates the persisted-credentials fallback in register-peer / startup for this process. markJoinedInProcess(); // Reinitialize cloud backend with new credentials. // Uses dynamic import to avoid compile-time dependency on startup.ts // (reinitCloudBackend is added in Plan 05). Cast to Record to avoid // TS2339 since the export doesn't exist yet. try { const startupModule = (await import("../startup.js")); if (typeof startupModule.reinitCloudBackend === "function") { await startupModule.reinitCloudBackend(config.COGENT_ENDPOINT, data.sessionId, data.token); logger.info("Cloud backend reinitialized with new session credentials"); } } catch (err) { // reinitCloudBackend may not exist yet (Plan 05 adds it). // Credentials are persisted, so a restart will pick them up. logger.debug(`Backend reinit not available: ${err}`); } return successResult({ success: true, sessionId: data.sessionId, label: data.label, secret: sessionSecret, token: data.token, createdAt: data.createdAt, config_snippet: { env_vars: `COGENT_ENDPOINT=${config.COGENT_ENDPOINT}\n` + `COGENT_SESSION_ID=${data.label ?? data.sessionId}\n` + `COGENT_SECRET=${sessionSecret}\n` + `COGENT_PLATFORM=${config.COGENT_PLATFORM}`, mcp_config: { "cogent": { command: "npx", args: ["-y", "@essentialai/cogent-bridge"], env: { COGENT_ENDPOINT: config.COGENT_ENDPOINT, COGENT_SESSION_ID: data.label ?? data.sessionId, COGENT_SECRET: sessionSecret, COGENT_PLATFORM: config.COGENT_PLATFORM, }, }, }, }, note: `Session created with label "${data.label ?? data.sessionId}". Share the secret with peers who need to join. Credentials saved locally. Cloud backend updated.`, }); } catch (err) { logger.error("create-session failed", { error: err }); return errorResult(err); } }); } //# sourceMappingURL=create-session.js.map