MCPcopy Create free account
hub / github.com/cortexkit/magic-context / MagicContextRpcServer

Class MagicContextRpcServer

packages/plugin/src/shared/rpc-server.ts:67–334  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

65 * of idle TUI CPU (#200). Pi never imports this module, so `Bun.serve` is safe.
66 */
67export class MagicContextRpcServer {
68 private server: Server<WsData> | null = null;
69 private port = 0;
70 private handlers = new Map<string, RpcHandler>();
71 private portFilePath: string;
72 private portDir: string;
73 private startedAt = Date.now();
74 /** Every authenticated WS socket, so dispose can close them all. */
75 private sockets = new Set<ServerWebSocket<WsData>>();
76 // Unguessable per-process bearer token, published in the (user-private) port
77 // file and required on every non-health RPC call AND in the WS hello. Defends
78 // side-effecting endpoints (recomp/upgrade/dismiss) and the push channel
79 // against any local process or browser-origin script that merely
80 // discovers/guesses the port.
81 private readonly token = randomBytes(32).toString("hex");
82
83 constructor(storageDir: string, directory: string) {
84 this.portFilePath = rpcPortFilePath(storageDir, directory);
85 this.portDir = rpcPortDir(storageDir, directory);
86 }
87
88 /** Register an RPC method handler. */
89 handle(method: string, handler: RpcHandler): void {
90 this.handlers.set(method, handler);
91 }
92
93 /** Start the server on a random port, write port to disk. */
94 async start(): Promise<number> {
95 const self = this;
96 const server = Bun.serve<WsData>({
97 port: 0,
98 hostname: "127.0.0.1",
99 fetch(req, srv) {
100 return self.handleFetch(req, srv);
101 },
102 websocket: {
103 open(ws) {
104 // Close the socket if it doesn't authenticate promptly. A
105 // never-authenticated socket holds no sink and is harmless,
106 // but we don't want to keep raw connections open forever.
107 ws.data.authTimer = setTimeout(() => {
108 if (!ws.data.authed) ws.close(WS_CLOSE_UNAUTHORIZED, "auth timeout");
109 }, WS_AUTH_TIMEOUT_MS);
110 },
111 message(ws, raw) {
112 self.handleWsMessage(ws, raw);
113 },
114 close(ws) {
115 if (ws.data.authTimer) clearTimeout(ws.data.authTimer);
116 ws.data.unregister?.();
117 self.sockets.delete(ws);
118 },
119 },
120 });
121
122 this.server = server;
123 this.port = server.port ?? 0;
124

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected