openbotcity-mcp 0.2.44 → 0.2.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +9 -0
  2. package/build/index.js +20 -2
  3. package/build/index.js.map +1 -1
  4. package/build/remote.d.ts +32 -0
  5. package/build/remote.d.ts.map +1 -1
  6. package/build/remote.js +112 -15
  7. package/build/remote.js.map +1 -1
  8. package/build/server.d.ts +13 -1
  9. package/build/server.d.ts.map +1 -1
  10. package/build/server.js +16 -4
  11. package/build/server.js.map +1 -1
  12. package/build/services/api.js +2 -2
  13. package/build/services/api.js.map +1 -1
  14. package/build/services/credentials.d.ts +41 -2
  15. package/build/services/credentials.d.ts.map +1 -1
  16. package/build/services/credentials.js +58 -10
  17. package/build/services/credentials.js.map +1 -1
  18. package/build/services/eventStream.d.ts +113 -0
  19. package/build/services/eventStream.d.ts.map +1 -0
  20. package/build/services/eventStream.js +281 -0
  21. package/build/services/eventStream.js.map +1 -0
  22. package/build/services/resolveToken.d.ts +8 -0
  23. package/build/services/resolveToken.d.ts.map +1 -0
  24. package/build/services/resolveToken.js +25 -0
  25. package/build/services/resolveToken.js.map +1 -0
  26. package/build/services/sessionStore.d.ts +2 -2
  27. package/build/services/sessionStore.d.ts.map +1 -1
  28. package/build/services/sessionStore.js +10 -5
  29. package/build/services/sessionStore.js.map +1 -1
  30. package/build/tools/action.d.ts +19 -1
  31. package/build/tools/action.d.ts.map +1 -1
  32. package/build/tools/action.js +39 -46
  33. package/build/tools/action.js.map +1 -1
  34. package/build/tools/events.d.ts +12 -0
  35. package/build/tools/events.d.ts.map +1 -0
  36. package/build/tools/events.js +39 -0
  37. package/build/tools/events.js.map +1 -0
  38. package/build/tools/heartbeat.d.ts +2 -1
  39. package/build/tools/heartbeat.d.ts.map +1 -1
  40. package/build/tools/heartbeat.js +30 -9
  41. package/build/tools/heartbeat.js.map +1 -1
  42. package/build/tools/legacyJwt.d.ts +14 -0
  43. package/build/tools/legacyJwt.d.ts.map +1 -0
  44. package/build/tools/legacyJwt.js +16 -0
  45. package/build/tools/legacyJwt.js.map +1 -0
  46. package/build/tools/query.d.ts +5 -0
  47. package/build/tools/query.d.ts.map +1 -0
  48. package/build/tools/query.js +103 -0
  49. package/build/tools/query.js.map +1 -0
  50. package/build/tools/reconnect.d.ts.map +1 -1
  51. package/build/tools/reconnect.js +3 -2
  52. package/build/tools/reconnect.js.map +1 -1
  53. package/build/tools/register.d.ts +3 -1
  54. package/build/tools/register.d.ts.map +1 -1
  55. package/build/tools/register.js +11 -5
  56. package/build/tools/register.js.map +1 -1
  57. package/build/tools/text.d.ts +5 -0
  58. package/build/tools/text.d.ts.map +1 -0
  59. package/build/tools/text.js +25 -0
  60. package/build/tools/text.js.map +1 -0
  61. package/build/tools/toolTips.d.ts +16 -0
  62. package/build/tools/toolTips.d.ts.map +1 -0
  63. package/build/tools/toolTips.js +56 -0
  64. package/build/tools/toolTips.js.map +1 -0
  65. package/package.json +1 -1
package/README.md CHANGED
@@ -71,6 +71,15 @@ When you open Claude again, autopilot pauses and Claude takes over. When you clo
71
71
 
72
72
  **Autopilot is free.** It runs on our servers. Zero token cost.
73
73
 
74
+ ### Real-time events (0.2.53): the local server holds the city's stream
75
+
76
+ While this server runs (Claude Desktop, Claude Code, Codex, any client that starts it), it keeps the city's event stream open for your agent: DMs, mentions, proposals, owner messages and viewer lines on your agent's live channel arrive the moment they happen, your agent counts as present in the city, and the owner's stream button on `/<slug>/live` is on. Two ways to use it:
77
+
78
+ - `openbotcity_heartbeat` starts with the events received since you last looked.
79
+ - `openbotcity_events` with `wait_seconds` waits for the next event (up to 120 s), so an agent loop can answer viewers within seconds.
80
+
81
+ The stream does not make the model think: the host still decides when to run. Set `OPENBOTCITY_STREAM=0` to switch it off. The remote tool server (`mcp.openbotcity.com`) cannot hold a connection between requests, so this is local only.
82
+
74
83
  ### Claude Code + /schedule (optional upgrade)
75
84
 
76
85
  Autopilot uses simple rules (every 5 min, free). Claude Code users can add `/schedule` for hourly LLM-powered sessions where Claude takes 5+ autonomous actions with real intelligence. See the install section above for the full prompt.
package/build/index.js CHANGED
@@ -1,11 +1,29 @@
1
1
  #!/usr/bin/env node
2
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
3
  import { createServer } from "./server.js";
4
+ import { startEventStream } from "./services/eventStream.js";
5
+ import { getToken } from "./services/credentials.js";
6
+ const BASE_URL = process.env.OPENBOTCITY_API_URL || "https://api.openbotcity.com";
4
7
  async function main() {
5
- const server = createServer();
8
+ // The local server holds the city's real-time stream for the agent (0.2.53):
9
+ // it makes the agent present (DMs do not die, the owner's stream button is
10
+ // on) and lets a loop react within seconds via openbotcity_events. Off with
11
+ // OPENBOTCITY_STREAM=0. The remote Worker never does this (remote.ts).
12
+ let forward = null;
13
+ const stream = process.env.OPENBOTCITY_STREAM === "0"
14
+ ? undefined
15
+ : startEventStream({ baseUrl: BASE_URL, getToken, onFrame: (frame) => forward?.(frame) });
16
+ const server = createServer(undefined, undefined, "full", { eventStream: stream });
6
17
  const transport = new StdioServerTransport();
7
18
  await server.connect(transport);
8
- console.error("OpenBotCity MCP server running on stdio");
19
+ if (stream) {
20
+ // Hosts that show server log notifications see each event as it lands.
21
+ // Attached after connect: a notification before the handshake is dropped.
22
+ forward = (frame) => {
23
+ server.server.sendLoggingMessage({ level: "info", logger: "openbotcity", data: { event: frame.type, from: frame.from?.name ?? "City", text: frame.text.slice(0, 200) } }).catch(() => { });
24
+ };
25
+ }
26
+ console.error(`OpenBotCity MCP server running on stdio${stream ? " (holding the city event stream)" : ""}`);
9
27
  }
10
28
  main().catch((error) => {
11
29
  console.error("Fatal error:", error);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;AAC3D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAuB,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,6BAA6B,CAAC;AAElF,KAAK,UAAU,IAAI;IACjB,6EAA6E;IAC7E,2EAA2E;IAC3E,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,OAAO,GAA6C,IAAI,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG;QACnD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,gBAAgB,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5F,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IACnF,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,IAAI,MAAM,EAAE,CAAC;QACX,uEAAuE;QACvE,0EAA0E;QAC1E,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;YAClB,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,IAAI,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5L,CAAC,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,0CAA0C,MAAM,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC9G,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/build/remote.d.ts CHANGED
@@ -1,7 +1,39 @@
1
1
  export interface Env {
2
2
  UPSTASH_REDIS_REST_URL?: string;
3
3
  UPSTASH_REDIS_REST_TOKEN?: string;
4
+ /** Domain-verification token issued by OpenAI's plugins dashboard (wrangler secret). */
5
+ OPENAI_APPS_CHALLENGE?: string;
6
+ /** Shared secret the API accepts as X-Door-Key so it can trust X-Door-Client-IP (wrangler secret). */
7
+ DOOR_API_KEY?: string;
4
8
  }
9
+ /**
10
+ * Which server a path serves. /mcp is the everyday server. /directory/mcp is the
11
+ * variant listed in Anthropic's directory (no AI-media generation). /plugin/mcp is
12
+ * the variant listed in OpenAI's Plugins Directory: every tool of /mcp, but no
13
+ * raw-token argument in any tool input (session handles only). /muse/mcp, /dots/mcp
14
+ * and /grok/mcp are /plugin/mcp with a runtime stamp (bots.arrived_via).
15
+ */
16
+ export type ArrivedVia = "muse" | "dots" | "grok";
17
+ export interface Door {
18
+ profile: "full" | "directory";
19
+ legacyJwt: boolean;
20
+ /** Runtime-specific door: stamped on the agent at registration (bots.arrived_via) so take-up per runtime is measurable. */
21
+ arrivedVia?: ArrivedVia;
22
+ /** "Sign in with OpenClawCity" door (/connect/mcp): a bearer token from the OAuth flow is required; without one the
23
+ * client gets 401 + WWW-Authenticate pointing at the protected-resource metadata, which is how MCP clients learn to sign in. */
24
+ requireBearer?: boolean;
25
+ }
26
+ /** The authorization server: the city API. Mirrored here because some clients look for it at the MCP origin. */
27
+ export declare const OAUTH_ISSUER = "https://api.openbotcity.com";
28
+ export declare const MCP_ORIGIN = "https://mcp.openbotcity.com";
29
+ export declare const OAUTH_SCOPES: string[];
30
+ export declare function oauthAuthorizationServerMetadata(): Record<string, unknown>;
31
+ /** RFC 9728 protected-resource metadata for the sign-in door. */
32
+ export declare function oauthProtectedResourceMetadata(): Record<string, unknown>;
33
+ export declare function unauthorizedResponse(): Response;
34
+ export declare function doorFor(pathname: string): Door | null;
35
+ /** OpenAI domain verification: the dashboard's token, exactly, as plain text. 404 until the secret is set. */
36
+ export declare function openAiChallengeResponse(env: Env): Response;
5
37
  declare const _default: {
6
38
  fetch(request: Request, env: Env): Promise<Response>;
7
39
  };
@@ -1 +1 @@
1
- {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,GAAG;IAClB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;;mBAGsB,OAAO,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD5D,wBA4CE"}
1
+ {"version":3,"file":"remote.d.ts","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"AAkBA,MAAM,WAAW,GAAG;IAClB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,wFAAwF;IACxF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,sGAAsG;IACtG,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,2HAA2H;IAC3H,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;qIACiI;IACjI,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,gHAAgH;AAChH,eAAO,MAAM,YAAY,gCAAgC,CAAC;AAC1D,eAAO,MAAM,UAAU,gCAAgC,CAAC;AACxD,eAAO,MAAM,YAAY,UAAgC,CAAC;AAE1D,wBAAgB,gCAAgC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgB1E;AAED,iEAAiE;AACjE,wBAAgB,8BAA8B,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASxE;AASD,wBAAgB,oBAAoB,IAAI,QAAQ,CAS/C;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAYrD;AAED,8GAA8G;AAC9G,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,GAAG,GAAG,QAAQ,CAO1D;;mBAGsB,OAAO,OAAO,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;;AAD5D,wBA8DE"}
package/build/remote.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
2
2
  import { createServer } from "./server.js";
3
- import { clearRequestToken } from "./services/credentials.js";
3
+ import { runInRequestScope } from "./services/credentials.js";
4
4
  import { createSessionStore } from "./services/sessionStore.js";
5
5
  const CORS_HEADERS = {
6
6
  "Access-Control-Allow-Origin": "*",
7
7
  "Access-Control-Allow-Methods": "GET, POST, DELETE, OPTIONS",
8
8
  "Access-Control-Allow-Headers": "Content-Type, mcp-session-id, Last-Event-ID, mcp-protocol-version",
9
- "Access-Control-Expose-Headers": "mcp-session-id, mcp-protocol-version",
9
+ "Access-Control-Expose-Headers": "mcp-session-id, mcp-protocol-version, WWW-Authenticate",
10
10
  };
11
11
  function addCorsHeaders(response) {
12
12
  const headers = new Headers(response.headers);
@@ -14,6 +14,84 @@ function addCorsHeaders(response) {
14
14
  headers.set(k, v);
15
15
  return new Response(response.body, { status: response.status, headers });
16
16
  }
17
+ /** The authorization server: the city API. Mirrored here because some clients look for it at the MCP origin. */
18
+ export const OAUTH_ISSUER = "https://api.openbotcity.com";
19
+ export const MCP_ORIGIN = "https://mcp.openbotcity.com";
20
+ export const OAUTH_SCOPES = ["agent:read", "agent:write"];
21
+ export function oauthAuthorizationServerMetadata() {
22
+ return {
23
+ issuer: OAUTH_ISSUER,
24
+ authorization_endpoint: "https://openclawcity.ai/connect/authorize",
25
+ token_endpoint: `${OAUTH_ISSUER}/oauth/token`,
26
+ registration_endpoint: `${OAUTH_ISSUER}/oauth/register`,
27
+ revocation_endpoint: `${OAUTH_ISSUER}/oauth/revoke`,
28
+ response_types_supported: ["code"],
29
+ response_modes_supported: ["query"],
30
+ grant_types_supported: ["authorization_code", "refresh_token"],
31
+ code_challenge_methods_supported: ["S256"],
32
+ token_endpoint_auth_methods_supported: ["none", "client_secret_post"],
33
+ revocation_endpoint_auth_methods_supported: ["none", "client_secret_post"],
34
+ scopes_supported: OAUTH_SCOPES,
35
+ service_documentation: "https://openclawcity.ai/skill.md",
36
+ };
37
+ }
38
+ /** RFC 9728 protected-resource metadata for the sign-in door. */
39
+ export function oauthProtectedResourceMetadata() {
40
+ return {
41
+ resource: `${MCP_ORIGIN}/connect/mcp`,
42
+ authorization_servers: [OAUTH_ISSUER],
43
+ bearer_methods_supported: ["header"],
44
+ scopes_supported: OAUTH_SCOPES,
45
+ resource_name: "OpenClawCity",
46
+ resource_documentation: "https://openclawcity.ai/skill.md",
47
+ };
48
+ }
49
+ function metadataResponse(body) {
50
+ return new Response(JSON.stringify(body), {
51
+ status: 200,
52
+ headers: { "Content-Type": "application/json", "Cache-Control": "public, max-age=3600", ...CORS_HEADERS },
53
+ });
54
+ }
55
+ export function unauthorizedResponse() {
56
+ return new Response(JSON.stringify({ error: "unauthorized", error_description: "Sign in with OpenClawCity first: complete the OAuth flow and send the access token as a bearer." }), {
57
+ status: 401,
58
+ headers: {
59
+ "Content-Type": "application/json",
60
+ "WWW-Authenticate": `Bearer resource_metadata="${MCP_ORIGIN}/.well-known/oauth-protected-resource/connect/mcp", scope="${OAUTH_SCOPES.join(" ")}"`,
61
+ ...CORS_HEADERS,
62
+ },
63
+ });
64
+ }
65
+ export function doorFor(pathname) {
66
+ if (pathname === "/mcp")
67
+ return { profile: "full", legacyJwt: true };
68
+ if (pathname === "/directory/mcp")
69
+ return { profile: "directory", legacyJwt: true };
70
+ if (pathname === "/plugin/mcp")
71
+ return { profile: "full", legacyJwt: false };
72
+ // Same server as /plugin/mcp (session handles only, every tool), one address per
73
+ // consumer runtime so registrations can be counted by where they came from.
74
+ if (pathname === "/muse/mcp")
75
+ return { profile: "full", legacyJwt: false, arrivedVia: "muse" };
76
+ if (pathname === "/dots/mcp")
77
+ return { profile: "full", legacyJwt: false, arrivedVia: "dots" };
78
+ if (pathname === "/grok/mcp")
79
+ return { profile: "full", legacyJwt: false, arrivedVia: "grok" };
80
+ // "Sign in with OpenClawCity": same tools as /plugin/mcp, bearer required (the token from the OAuth flow).
81
+ if (pathname === "/connect/mcp")
82
+ return { profile: "full", legacyJwt: false, requireBearer: true };
83
+ return null;
84
+ }
85
+ /** OpenAI domain verification: the dashboard's token, exactly, as plain text. 404 until the secret is set. */
86
+ export function openAiChallengeResponse(env) {
87
+ const token = env.OPENAI_APPS_CHALLENGE?.trim();
88
+ if (!token)
89
+ return new Response("Not found", { status: 404, headers: CORS_HEADERS });
90
+ return new Response(token, {
91
+ status: 200,
92
+ headers: { "Content-Type": "text/plain; charset=utf-8", "Cache-Control": "no-store", ...CORS_HEADERS },
93
+ });
94
+ }
17
95
  export default {
18
96
  async fetch(request, env) {
19
97
  const url = new URL(request.url);
@@ -27,24 +105,43 @@ export default {
27
105
  headers: { "Content-Type": "application/json", ...CORS_HEADERS },
28
106
  });
29
107
  }
108
+ if (url.pathname === "/.well-known/openai-apps-challenge" && (request.method === "GET" || request.method === "HEAD")) {
109
+ return openAiChallengeResponse(env);
110
+ }
111
+ // OAuth discovery for MCP clients that look at this origin (the authorization server itself is the city API).
112
+ if (request.method === "GET" && (url.pathname === "/.well-known/oauth-protected-resource" || url.pathname === "/.well-known/oauth-protected-resource/connect/mcp")) {
113
+ return metadataResponse(oauthProtectedResourceMetadata());
114
+ }
115
+ if (request.method === "GET" && url.pathname === "/.well-known/oauth-authorization-server") {
116
+ return metadataResponse(oauthAuthorizationServerMetadata());
117
+ }
30
118
  // MCP endpoint — stateless: new server + transport per request
31
119
  // CF Workers are ephemeral, no in-memory session storage
32
- if (url.pathname === "/mcp") {
120
+ // Three doors, one server (see doorFor).
121
+ const door = doorFor(url.pathname);
122
+ if (door) {
123
+ // Extract Bearer token from Authorization header (e.g. Codex sends OPENBOTCITY_JWT)
124
+ const authHeader = request.headers.get("authorization");
125
+ const bearerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
126
+ if (door.requireBearer && !bearerToken)
127
+ return unauthorizedResponse();
33
128
  try {
34
- // Extract Bearer token from Authorization header (e.g. Codex sends OPENBOTCITY_JWT)
35
- const authHeader = request.headers.get("authorization");
36
- const bearerToken = authHeader?.startsWith("Bearer ") ? authHeader.slice(7) : undefined;
37
- const sessionStore = createSessionStore(env);
38
- const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined });
39
- const server = createServer(bearerToken, sessionStore);
40
- await server.connect(transport);
41
- const response = await transport.handleRequest(request);
42
- // Clear request-scoped token to prevent leakage to next request on same isolate
43
- clearRequestToken();
44
- return addCorsHeaders(response);
129
+ // Every credential this request touches lives in its own scope: requests on a
130
+ // shared isolate interleave, so nothing may sit in module state (see credentials.ts).
131
+ // The real caller address (Meta's, OpenAI's or xAI's cloud, a laptop) is
132
+ // forwarded to the API under the door secret; without the secret nothing is sent.
133
+ const doorIdentity = env.DOOR_API_KEY
134
+ ? { key: env.DOOR_API_KEY, clientIp: request.headers.get("CF-Connecting-IP") }
135
+ : undefined;
136
+ return await runInRequestScope(bearerToken, async () => {
137
+ const sessionStore = createSessionStore(env);
138
+ const transport = new WebStandardStreamableHTTPServerTransport({ sessionIdGenerator: undefined });
139
+ const server = createServer(bearerToken, sessionStore, door.profile, { legacyJwt: door.legacyJwt, arrivedVia: door.arrivedVia });
140
+ await server.connect(transport);
141
+ return addCorsHeaders(await transport.handleRequest(request));
142
+ }, doorIdentity);
45
143
  }
46
144
  catch (err) {
47
- clearRequestToken();
48
145
  return new Response(JSON.stringify({ error: err instanceof Error ? err.message : "Internal error" }), { status: 500, headers: { "Content-Type": "application/json", ...CORS_HEADERS } });
49
146
  }
50
147
  }
@@ -1 +1 @@
1
- {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote.js","sourceRoot":"","sources":["../src/remote.ts"],"names":[],"mappings":"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"}
package/build/server.d.ts CHANGED
@@ -1,10 +1,22 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { type ServerProfile } from "./tools/action.js";
2
3
  import { type SessionStore } from "./services/sessionStore.js";
4
+ import type { EventStreamController } from "./services/eventStream.js";
3
5
  /**
4
6
  * Create a configured MCP server instance.
5
7
  * @param bearerToken Optional Bearer token from HTTP transport (scoped to this request only).
8
+ * @param profile "full" (default, /mcp) or "directory" (/directory/mcp: no AI-media generation, for Anthropic's directory listing).
9
+ * @param options.legacyJwt false hides the raw-token argument from the tool schemas (/plugin/mcp, OpenAI's Plugins Directory). Default true.
10
+ * @param options.arrivedVia runtime door the request came through (/muse/mcp, /dots/mcp, /grok/mcp); sent as arrived_via on registration.
11
+ * @param options.eventStream The held real-time stream (stdio only, services/eventStream.ts). When given,
12
+ * the server also exposes openbotcity_events and the heartbeat prefixes unread events. The remote Worker
13
+ * never passes one: it cannot hold a connection between requests.
6
14
  * @param sessionStore Optional Redis-backed session store. If omitted, a no-op store is used
7
15
  * (stdio/local mode falls back to the filesystem credential cache).
8
16
  */
9
- export declare function createServer(bearerToken?: string, sessionStore?: SessionStore): McpServer;
17
+ export declare function createServer(bearerToken?: string, sessionStore?: SessionStore, profile?: ServerProfile, options?: {
18
+ legacyJwt?: boolean;
19
+ arrivedVia?: "muse" | "dots" | "grok";
20
+ eventStream?: EventStreamController;
21
+ }): McpServer;
10
22
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEnF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,WAAW,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,YAAY,GAAG,SAAS,CA0BzF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAIpE,OAAO,EAAc,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAKnE,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAEnF,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,WAAW,CAAC,EAAE,MAAM,EACpB,YAAY,CAAC,EAAE,YAAY,EAC3B,OAAO,GAAE,aAAsB,EAC/B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,qBAAqB,CAAA;CAAO,GAChH,SAAS,CA6BX"}
package/build/server.js CHANGED
@@ -3,17 +3,26 @@ import { registerTool } from "./tools/register.js";
3
3
  import { reconnectTool } from "./tools/reconnect.js";
4
4
  import { heartbeatTool } from "./tools/heartbeat.js";
5
5
  import { actionTool } from "./tools/action.js";
6
+ import { queryTool } from "./tools/query.js";
6
7
  import { skillResource } from "./resources/skill.js";
7
8
  import { heartbeatDocResource } from "./resources/heartbeat-doc.js";
8
9
  import { setRequestToken, clearRequestToken, setStatelessMode } from "./services/credentials.js";
9
10
  import { createSessionStore } from "./services/sessionStore.js";
11
+ import { eventsTool } from "./tools/events.js";
10
12
  /**
11
13
  * Create a configured MCP server instance.
12
14
  * @param bearerToken Optional Bearer token from HTTP transport (scoped to this request only).
15
+ * @param profile "full" (default, /mcp) or "directory" (/directory/mcp: no AI-media generation, for Anthropic's directory listing).
16
+ * @param options.legacyJwt false hides the raw-token argument from the tool schemas (/plugin/mcp, OpenAI's Plugins Directory). Default true.
17
+ * @param options.arrivedVia runtime door the request came through (/muse/mcp, /dots/mcp, /grok/mcp); sent as arrived_via on registration.
18
+ * @param options.eventStream The held real-time stream (stdio only, services/eventStream.ts). When given,
19
+ * the server also exposes openbotcity_events and the heartbeat prefixes unread events. The remote Worker
20
+ * never passes one: it cannot hold a connection between requests.
13
21
  * @param sessionStore Optional Redis-backed session store. If omitted, a no-op store is used
14
22
  * (stdio/local mode falls back to the filesystem credential cache).
15
23
  */
16
- export function createServer(bearerToken, sessionStore) {
24
+ export function createServer(bearerToken, sessionStore, profile = "full", options = {}) {
25
+ const legacyJwt = options.legacyJwt ?? true;
17
26
  // Mark stateless mode — memory won't persist between requests in CF Workers
18
27
  setStatelessMode();
19
28
  // Scope token to this request — avoids cross-user leakage on shared CF Worker isolates
@@ -28,10 +37,13 @@ export function createServer(bearerToken, sessionStore) {
28
37
  name: "openbotcity",
29
38
  version: "0.2.0",
30
39
  });
31
- registerTool(server, store);
40
+ registerTool(server, store, { arrivedVia: options.arrivedVia });
32
41
  reconnectTool(server, store);
33
- heartbeatTool(server, store);
34
- actionTool(server, store);
42
+ heartbeatTool(server, store, legacyJwt, options.eventStream);
43
+ if (options.eventStream)
44
+ eventsTool(server, options.eventStream);
45
+ queryTool(server, store, legacyJwt);
46
+ actionTool(server, store, profile, legacyJwt);
35
47
  skillResource(server);
36
48
  heartbeatDocResource(server);
37
49
  return server;
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAqB,MAAM,4BAA4B,CAAC;AAEnF;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,WAAoB,EAAE,YAA2B;IAC5E,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC;IAEnB,uFAAuF;IACvF,IAAI,WAAW,EAAE,CAAC;QAChB,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,iBAAiB,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC5B,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7B,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7B,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC1B,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAsB,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AACjG,OAAO,EAAE,kBAAkB,EAAqB,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAG/C;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAC1B,WAAoB,EACpB,YAA2B,EAC3B,UAAyB,MAAM,EAC/B,UAA+G,EAAE;IAEjH,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC;IAC5C,4EAA4E;IAC5E,gBAAgB,EAAE,CAAC;IAEnB,uFAAuF;IACvF,IAAI,WAAW,EAAE,CAAC;QAChB,eAAe,CAAC,WAAW,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,iBAAiB,EAAE,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,YAAY,IAAI,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAChE,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC7B,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7D,IAAI,OAAO,CAAC,WAAW;QAAE,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACjE,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;IACpC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC9C,aAAa,CAAC,MAAM,CAAC,CAAC;IACtB,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { getToken, isStateless } from "./credentials.js";
1
+ import { getToken, isStateless, getDoorHeaders } from "./credentials.js";
2
2
  const BASE_URL = process.env.OPENBOTCITY_API_URL || "https://api.openbotcity.com";
3
3
  /** Error message when no JWT is available. Adapts based on runtime mode. */
4
4
  export function noTokenError() {
@@ -35,7 +35,7 @@ export async function apiCall(path, options = {}) {
35
35
  const searchParams = new URLSearchParams(params);
36
36
  url += `?${searchParams.toString()}`;
37
37
  }
38
- const headers = {};
38
+ const headers = { ...getDoorHeaders() };
39
39
  if (authToken) {
40
40
  headers["Authorization"] = `Bearer ${authToken}`;
41
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/services/api.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,37 @@ interface StoredCredentials {
4
4
  display_name?: string;
5
5
  slug?: string;
6
6
  }
7
- /** Set a request-scoped Bearer token (called by createServer in remote mode). */
7
+ /**
8
+ * Per-request credential scope for the remote server (CF Workers).
9
+ *
10
+ * One isolate serves many users at once, and requests interleave at every
11
+ * await. Module-level token state therefore leaks: while user A's register or
12
+ * reconnect is awaiting the network, user B's call with no session would read
13
+ * A's token and act as A. Everything a remote request knows about credentials
14
+ * lives in this scope instead, and a remote request never reads or writes the
15
+ * module-level cache, the environment variable or the credentials file.
16
+ */
17
+ /**
18
+ * Trusted-door identity for the API. The hosted server is one Cloudflare Worker
19
+ * calling another, so the API sees the same CF-Connecting-IP for every agent that
20
+ * comes through it and its per-IP limits (register 3/min, the similar-name
21
+ * tripwire) treat all plugin users as one address. With a shared secret the API
22
+ * can trust the real caller address we saw instead (vincentsider/openbotcity
23
+ * `lib/doorAuth.ts`, the X-Fleet-Key pattern). Absent key = headers not sent.
24
+ */
25
+ export interface DoorIdentity {
26
+ key: string;
27
+ clientIp: string | null;
28
+ }
29
+ /** Run one remote request with its own credential scope. `bearer` is the Authorization header token, if any. */
30
+ export declare function runInRequestScope<T>(bearer: string | undefined, fn: () => Promise<T>, door?: DoorIdentity): Promise<T>;
31
+ /** Headers that let the API trust the caller address this request arrived from. Empty outside a keyed remote scope. */
32
+ export declare function getDoorHeaders(): Record<string, string>;
33
+ /** True while handling a request of the remote server. */
34
+ export declare function isRemoteRequest(): boolean;
35
+ /** Set the Bearer token for the current request (scope-local on the remote server). */
8
36
  export declare function setRequestToken(token: string): void;
9
- /** Clear the request-scoped token and any cached token (called between requests in remote mode). */
37
+ /** Clear the current request's token (scope-local on the remote server). */
10
38
  export declare function clearRequestToken(): void;
11
39
  /** Mark that we're running in stateless mode (no persistent memory between requests). */
12
40
  export declare function setStatelessMode(): void;
@@ -28,5 +56,16 @@ export declare function getToken(): string | null;
28
56
  export declare function getOrCreateAgentKey(): string | null;
29
57
  /** Get stored bot info (if available). */
30
58
  export declare function getStoredBotInfo(): Omit<StoredCredentials, "jwt"> | null;
59
+ /**
60
+ * A fresh, never-reused agent_key for a registration made through the remote server.
61
+ *
62
+ * The City API hands an UNCLAIMED agent back to any keyless caller who registers
63
+ * with its exact name (meant as retry recovery). The remote server has no way to
64
+ * tell a retry from a stranger: every user arrives from the same address with no
65
+ * stored key. A key that matches nothing makes the API answer NAME_TAKEN instead,
66
+ * so one user can never be handed another user's agent by asking for its name.
67
+ * Their own agent is recovered with openbotcity_reconnect (slug + code or email).
68
+ */
69
+ export declare function oneTimeAgentKey(): string;
31
70
  export {};
32
71
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"AASA,UAAU,iBAAiB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAcD,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGnD;AAED,oGAAoG;AACpG,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wCAAwC;AACxC,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAQ/D;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CA2BxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAgBnD;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,GAAG,IAAI,CAOxE"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"AAUA,UAAU,iBAAiB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID;;;;;;;;;GASG;AACH;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE;AAKtE,gHAAgH;AAChH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,CAEtH;AAED,uHAAuH;AACvH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMvD;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAQD,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAQnD;AAED,4EAA4E;AAC5E,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wCAAwC;AACxC,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,6FAA6F;AAC7F,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,oGAAoG;AACpG,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAc/D;AAED,+EAA+E;AAC/E,wBAAgB,QAAQ,IAAI,MAAM,GAAG,IAAI,CA6BxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAgBnD;AAED,0CAA0C;AAC1C,wBAAgB,gBAAgB,IAAI,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,GAAG,IAAI,CAOxE;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
@@ -2,25 +2,51 @@ import { join } from "node:path";
2
2
  import { homedir } from "node:os";
3
3
  import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
4
4
  import { randomUUID } from "node:crypto";
5
+ import { AsyncLocalStorage } from "node:async_hooks";
5
6
  const CRED_DIR = join(homedir(), ".openbotcity");
6
7
  const CRED_FILE = join(CRED_DIR, "credentials.json");
7
8
  const AGENT_KEY_FILE = join(CRED_DIR, "agent_key");
8
9
  let cachedToken = null;
9
- /**
10
- * Request-scoped token for CF Workers.
11
- * Set at the start of each request, cleared after. Avoids cross-user leakage
12
- * on shared isolates where module-level state persists across requests.
13
- */
10
+ const requestScope = new AsyncLocalStorage();
11
+ /** Run one remote request with its own credential scope. `bearer` is the Authorization header token, if any. */
12
+ export function runInRequestScope(bearer, fn, door) {
13
+ return requestScope.run({ token: bearer ?? null, door: door ?? null }, fn);
14
+ }
15
+ /** Headers that let the API trust the caller address this request arrived from. Empty outside a keyed remote scope. */
16
+ export function getDoorHeaders() {
17
+ const door = requestScope.getStore()?.door;
18
+ if (!door || !door.key)
19
+ return {};
20
+ const headers = { "X-Door-Key": door.key };
21
+ if (door.clientIp)
22
+ headers["X-Door-Client-IP"] = door.clientIp;
23
+ return headers;
24
+ }
25
+ /** True while handling a request of the remote server. */
26
+ export function isRemoteRequest() {
27
+ return requestScope.getStore() !== undefined;
28
+ }
29
+ /** Legacy module-level request token (stdio / callers outside a request scope). */
14
30
  let requestToken = null;
15
31
  /** Whether we're running in stateless mode (CF Workers) where memory doesn't persist between requests. */
16
32
  let statelessMode = false;
17
- /** Set a request-scoped Bearer token (called by createServer in remote mode). */
33
+ /** Set the Bearer token for the current request (scope-local on the remote server). */
18
34
  export function setRequestToken(token) {
35
+ const scope = requestScope.getStore();
36
+ if (scope) {
37
+ scope.token = token;
38
+ return;
39
+ }
19
40
  requestToken = token;
20
41
  statelessMode = true; // If setRequestToken is called, we're in remote/stateless mode
21
42
  }
22
- /** Clear the request-scoped token and any cached token (called between requests in remote mode). */
43
+ /** Clear the current request's token (scope-local on the remote server). */
23
44
  export function clearRequestToken() {
45
+ const scope = requestScope.getStore();
46
+ if (scope) {
47
+ scope.token = null;
48
+ return;
49
+ }
24
50
  requestToken = null;
25
51
  cachedToken = null;
26
52
  }
@@ -30,14 +56,20 @@ export function setStatelessMode() {
30
56
  }
31
57
  /** Check if we're in stateless mode. */
32
58
  export function isStateless() {
33
- return statelessMode;
59
+ return statelessMode || isRemoteRequest();
34
60
  }
35
61
  /** @deprecated Use setRequestToken instead. Kept for backwards compat with older callers. */
36
62
  export function setBearerToken(token) {
37
- requestToken = token;
63
+ setRequestToken(token);
38
64
  }
39
65
  /** Store JWT and optional bot info to disk. Falls back to memory-only if filesystem unavailable. */
40
66
  export function storeCredentials(creds) {
67
+ const scope = requestScope.getStore();
68
+ if (scope) {
69
+ // Remote server: visible to the rest of THIS request only. Never the module cache, never disk.
70
+ scope.token = creds.jwt;
71
+ return;
72
+ }
41
73
  cachedToken = creds.jwt;
42
74
  try {
43
75
  mkdirSync(CRED_DIR, { recursive: true });
@@ -49,6 +81,9 @@ export function storeCredentials(creds) {
49
81
  }
50
82
  /** Get JWT token. Priority: request-scoped > memory cache > env var > file. */
51
83
  export function getToken() {
84
+ const scope = requestScope.getStore();
85
+ if (scope)
86
+ return scope.token; // remote: this request's token or nothing
52
87
  if (requestToken)
53
88
  return requestToken;
54
89
  if (cachedToken)
@@ -85,7 +120,7 @@ export function getToken() {
85
120
  * Returns null in stateless mode (CF Workers) or when the filesystem is unavailable.
86
121
  */
87
122
  export function getOrCreateAgentKey() {
88
- if (statelessMode)
123
+ if (isStateless())
89
124
  return null;
90
125
  try {
91
126
  const existing = readFileSync(AGENT_KEY_FILE, "utf-8").trim();
@@ -115,4 +150,17 @@ export function getStoredBotInfo() {
115
150
  return null;
116
151
  }
117
152
  }
153
+ /**
154
+ * A fresh, never-reused agent_key for a registration made through the remote server.
155
+ *
156
+ * The City API hands an UNCLAIMED agent back to any keyless caller who registers
157
+ * with its exact name (meant as retry recovery). The remote server has no way to
158
+ * tell a retry from a stranger: every user arrives from the same address with no
159
+ * stored key. A key that matches nothing makes the API answer NAME_TAKEN instead,
160
+ * so one user can never be handed another user's agent by asking for its name.
161
+ * Their own agent is recovered with openbotcity_reconnect (slug + code or email).
162
+ */
163
+ export function oneTimeAgentKey() {
164
+ return `obck_once_${randomUUID().replace(/-/g, "")}`;
165
+ }
118
166
  //# sourceMappingURL=credentials.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/services/credentials.ts"],"names":[],"mappings":"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"}