/** * openlore serve — local HTTP daemon (warm, loopback-only). * * A long-lived process that keeps openlore's caches warm across calls and * exposes the tool surface over plain HTTP so non-MCP clients (e.g. a Pi * extension) can hit it with `fetch` — no JSON-RPC, no subprocess-per-call. * * It reuses the SAME tool dispatch as the stdio MCP server * ({@link dispatchTool}) so the two transports can't drift, and the SAME tool * presets ({@link selectActiveTools}) so a small-model client gets a focused * surface (default: `navigation`). * * Endpoints (all loopback): * GET /health → { ok, version, root, preset, tools, uptimeMs } * POST /tool/:name body { directory?, args } → handler result (JSON) * * Discovery: writes `.openlore/serve.json` { port, pid, host, token?, startedAt } * in the served root so a client can find and reuse a running daemon. * * Security: defaults to 127.0.0.1. Every request is checked against a DNS-rebinding * guard (Host must be a loopback name or the bound host; a cross-site Origin is * rejected) before any dispatch. An optional --token must be presented as the * `x-openlore-token` header and is compared in constant time; binding a non-loopback * host requires a token (the daemon refuses to start otherwise), and a tokenless * loopback bind warns that other local processes can reach the port. * * Freshness (watcher + continuous re-analyze) is layered on separately; this * module is the transport + lifecycle core. */ import { Command } from 'commander'; /** * Resolve the idle-shutdown interval (ms) from the `--idle-timeout` option, in * minutes. Absent or non-numeric → the default; zero/negative → 0 (disabled). */ export declare function idleTimeoutMs(option?: string): number; /** Daemon discovery descriptor written to /.openlore/serve.json. */ interface ServeDescriptor { port: number; pid: number; host: string; token?: string; startedAt: string; version: string; } interface ServeCliOptions { directory?: string; port?: string; host?: string; preset?: string; token?: string; stop?: boolean; /** false (via --no-watch) disables the freshness watcher + re-analyze lane. */ watch?: boolean; /** Minutes of request inactivity before the daemon self-terminates. 0 disables. */ idleTimeout?: string; } /** Live daemon handle. Returned by {@link startServe} so callers (tests) can * address and shut down the running server without signalling the process. */ export interface ServeHandle { port: number; host: string; token?: string; baseUrl: string; close(): Promise; } /** * Read + validate /.openlore/serve.json. The discovery file is an untrusted * on-disk artifact (mcp-security: Untrusted Artifact Deserialization): a hostile repo * could ship a poisoned serve.json. We fail closed unless every field has the expected * type AND the host is a loopback name — otherwise `daemonAlive` would fetch an * arbitrary host (egress / SSRF) and `stopDaemon` could SIGTERM an arbitrary pid. * * Exported for the serve.json validation tests. */ export declare function readDescriptor(root: string): Promise; export declare function startServe(options: ServeCliOptions): Promise; export declare const serveCommand: Command; export {}; //# sourceMappingURL=serve.d.ts.map