import { FederationRegistry, FederationAudit, L6Store, PeerTransport, RemoteL6Client, AgentIdentity, HandoffGovernance } from '@getbourdon/federation'; import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { SkillSource } from '@getbourdon/participants'; import * as node_http from 'node:http'; /** * Bourdon L6 — MCP server (faithful port of `core/l6_server.py`). * * Wraps `@getbourdon/federation`'s `L6Store` in an `@modelcontextprotocol/sdk` * `McpServer` so any MCP-aware agent (Claude Code, Codex, Cursor) can query the * federation natively. Registers the SAME tools + 3 resources as the Python * server, with byte-identical names, arg names, and defaults (the public/team * `access_level` split is reproduced exactly). * * WIRE ENCODING — the single highest-risk port detail: every tool handler * returns `{ content: [{ type: "text", text: JSON.stringify(payload) }] }`, NOT * the SDK's default structured content. The Python `RemoteL6Client` (and * `@getbourdon/client`) recover the payload with `json.loads(item.text)` / * `JSON.parse(text)`. Returning structured content instead makes a Python peer's * `json.loads(item.text)` get `None` and silently breaks mixed-language * federation. Each tool closure builds a plain object; `jsonContent` stringifies * it onto the wire. * * Caller identity arrives via the AsyncLocalStorage binding (`getCaller()` from * `@getbourdon/federation`): the HTTP auth middleware binds the resolved * identity for the request subtree; stdio has no binding and resolves to * OPERATOR (trusted) — exactly v0.8.0 behavior. Quarantined callers get an * allowlisted read surface (granted namespaces) and STAGED writes; every call is * audited, allow and deny alike. */ interface CreateL6ServerOptions { name?: string; registry?: FederationRegistry; audit?: FederationAudit; /** * Explicit canonical HTTPS MCP resource for caller descriptions (Python's * `caller_audience`). Must match the enrolled library identity. Left unset, * `describe_caller` reports `not_configured` rather than guessing. */ callerAudience?: string | null; /** * `agentId -> SkillSource[] | null`: where an agent's skill reader looks, * used by `propose_skill` to find the folder an advertised skill was read * from. Defaults to the built-in readers' directories * (`skillSourcesForAgent` in `@getbourdon/participants`). */ skillSources?: (agentId: string) => readonly SkillSource[] | null; } /** * Sent in the MCP `initialize` response, byte-identical to the oracle's * `SERVER_INSTRUCTIONS` (pinned in conformance `mcp_server_meta.json`). Hosts * that surface server instructions to the model get a standing reason to call * `compile_turn`, and to reach for the shared skills on a how-to task. */ declare const SERVER_INSTRUCTIONS: string; declare function createL6Server(store: L6Store, options?: CreateL6ServerOptions): McpServer; /** * Source-attributed agent export — faithful port of `core/agents_export.py`. * * The single place that turns a directory of `*.l5.yaml` manifests into the * stable, redacted `bourdon.agents/v1` JSON shape the desktop tray consumes. * The `export_agents` MCP tool calls `exportLocalAgents` here (NOT * `L6Store.exportAgents`, which serves the different federated-merge shape). * * Redaction reuses the `@getbourdon/redaction` SSOT — `_safe_native_memory_text` * in Python is a thin wrapper over `redact_text(value, limit=180)`, so the tray * never sees a raw credential regardless of session visibility. `source` / * `source_kind` are stamped by the caller (this machine), never read from the * agent's self-reported manifest. * * EGRESS visibility gate (3-Star audit P0-1): the peer-facing export path passes * `access_level="team"`/`"public"` so PRIVATE session content never crosses the * federation wire. The default `"private"` admits every well-formed session for * the operator's own local tray view. Session visibility is resolved by the * shared `@getbourdon/l5` visibility policy -- the same one every other egress * surface applies -- and an unknown access level throws rather than widening. */ declare const AGENTS_SCHEMA = "bourdon.agents/v1"; declare const MAX_RECENT_SESSIONS = 10; type Dict$1 = Record; /** * Resolve this machine's label for source attribution. Honors * `BOURDON_LOCAL_NAME` (a deployment can pin a stable, friendly label), else * `os.hostname()`. Computed at call time so tests can override either source. */ declare function resolveLocalName(): string; /** * Build one redacted, source-attributed summary from a parsed L5 manifest. The * canonical per-agent tray shape plus the two source-attribution fields. */ declare function summarizeAgentManifest(manifest: Dict$1, opts: { source: string; sourceKind?: string; accessLevel?: string; }): Dict$1; /** Partial-failure entry so the tray can represent a broken manifest. */ declare function errorAgentEntry(agentId: string, message: string, opts: { source: string; sourceKind?: string; }): Dict$1; /** * Summarize every local `*.l5.yaml` manifest into the tray envelope. Agents are * sorted by live-now then `last_updated` descending; per-manifest parse failures * are represented inline (`parse_error`) rather than raised, so one broken file * never sinks the whole export. */ declare function exportLocalAgents(agentsDir: string, localName: string, accessLevel?: string): Dict$1; /** * Recognition / context helpers for the L6 MCP tools — faithful port of the * module-level functions in `core/l6_server.py` * (`prepare_recognition_context_from_store`, `_recognition_prompt_context`, * `get_deeper_context_for_prompt`, `compile_codex_turn_from_store`). * * Thin glue between `@getbourdon/federation` (L6Store) and * `@getbourdon/recognition` (recognitionFirst). No business logic of its own. */ type Dict = Record; /** * The turn-start fragment an agent prepends to its own prompt. * * The recognition string already says what each named anchor is and how current * that knowledge is, so it is quoted WHOLE (redacted line by line, bounded) * rather than restated as a "Matched entities:" list. The provenance line * underneath says which agents know each matched entity; that is the part * recognition leaves out on purpose. */ declare function recognitionPromptContext(result: { recognition: string; matchedEntities: Dict[]; }): string; /** * Immediate recognition + a bounded prompt-context fragment from the store. The * recognition string is computed synchronously; `recognition_latency_us` is the * measured micro-latency (rounded to 1 dp, like Python). `hydration_scheduled` * mirrors Python's `hydration is not None` (true iff there were matches). */ declare function prepareRecognitionContextFromStore(store: L6Store, prompt: string, accessLevel?: string, includePrivate?: boolean, hydrate?: boolean): Promise; /** * Deeper context for `prompt`, assembled locally and free — faithful port of * `get_deeper_context_for_prompt`. The local store is the source; an enabled * L2 backend still contributes when a deployment has one, appended rather * than depended on — retrieval that ships disabled must not be the only door. */ declare function getDeeperContextForPrompt(store: L6Store, prompt: string, accessLevel?: string, includePrivate?: boolean): Promise; /** * The deferred stub the `mcp_snapshots` conformance fixture pins for * `compile_codex_turn`. Kept for back-compat: the generator special-cases this * tool's snapshot because its live output is environment-bound (resolves the live * cwd, git repo name + remote, repo-identity scoring), so it is NOT a portable * cross-impl parity surface. The real tool now returns a full brief at runtime * (matching the live Python server), so the snapshot test asserts structurally * rather than byte-equal to this stub. */ declare const CODEX_TURN_DEFERRED: { readonly _status: "deferred"; readonly schema_version: "codex-turn-brief/v1"; readonly reason: string; }; /** * Return a Codex turn-scoped recognition brief using this server's store — * delegates to the P7 `@getbourdon/inference` turn compiler (faithful port of * `compile_codex_turn_from_store` in `core/l6_server.py`). The live Python server * returns the same full brief; only the conformance SNAPSHOT is the deferred stub. */ declare function compileCodexTurnFromStore(store: L6Store, prompt: string, opts?: { cwd?: string | null; accessLevel?: string; maxItems?: number; maxChars?: number; }): Dict; /** * stdio transport — the MCP-host default and `bourdon serve --transport stdio`. * * `StdioServerTransport` carries no auth: stdio has no HTTP request, so the * caller resolves to OPERATOR (trusted) via the unbound AsyncLocalStorage — * exactly v0.8.0 behavior. `server.connect(transport)` blocks the process until * the connecting MCP client disconnects. */ /** Connect `server` to a stdio transport. Resolves once connected; the process * stays alive until the client disconnects. */ declare function runStdio(server: McpServer): Promise; declare const DEFAULT_PEERS_CONFIG: string; declare class PeerAuthorityError extends Error { constructor(message: string); } interface PeerAuthorityOptions { federate: boolean; noPeers: boolean; peersConfig?: string; peerUrls: readonly string[]; clientName: string; clientVersion: string; defaultPeersConfig?: string; } declare function resolvePeerClients(options: PeerAuthorityOptions, transport?: PeerTransport): RemoteL6Client[]; declare const DEFAULT_PORT = 7500; declare const DEFAULT_HOST = "127.0.0.1"; /** * The legacy shared peer token, with empty/whitespace normalized to null. A * set-but-empty `BOURDON_PEER_TOKEN_SERVER` (a routine .env slip) is treated as * "no token" everywhere — both the startup gate and per-request auth (P1-1). */ declare function normalizedLegacyToken(): string | null; /** Whether a bind host is loopback-only. */ declare function isLoopbackHost(host: string): boolean; type AuthResult = { kind: "unconfigured"; } | { kind: "unauthorized"; message: string; } | { kind: "ok"; identity: AgentIdentity; }; /** * Resolve an `Authorization` header to an identity, reproducing the * `_BearerAuth.dispatch` decision exactly. */ declare function authenticateBearer(registry: FederationRegistry, legacy: string | null, authHeader: string | null | undefined): AuthResult; /** Error thrown when a non-loopback bind is refused. The CLI catches it and * exits non-zero (mirrors Python's `raise SystemExit`). */ declare class BindRefusedError extends Error { constructor(message: string); } interface RunHttpServerOptions { port?: number; host?: string; allowUnauthenticated?: boolean; registry?: FederationRegistry; governance?: HandoffGovernance; } /** Start the same authenticated request handler exposed for in-process integration. */ declare function runHttpServer(createServer: () => McpServer, options?: RunHttpServerOptions): node_http.Server; /** * @getbourdon/mcp-server — the Bourdon L6 MCP server facade (BUSL-1.1). * * The TypeScript mirror of `core/l6_server.py` on `@modelcontextprotocol/sdk`, * WIRE-COMPATIBLE with the Python server BOTH directions so mixed-language * federation works: every tool returns JSON-in-TextContent * (`text = JSON.stringify(payload)`) — NOT the SDK's default structured content * — so a Python `RemoteL6Client`'s `json.loads(item.text)` recovers the payload. * * The 12 tools + 3 resources are thin delegates to `@getbourdon/federation` * (L6Store + trust) and `@getbourdon/recognition`. The public/team `access_level` * default split is reproduced exactly. Python (`pip install bourdon`) is the * oracle; this package asserts against `@getbourdon/conformance` `mcp_snapshots`. */ /** * Convenience factory: build an `McpServer` over `store` with the given trust * `registry` + `audit`. Equivalent to `createL6Server(store, { registry, audit })`. */ declare function createServer(store: L6Store, registry?: FederationRegistry, opts?: Omit & { audit?: FederationAudit; }): McpServer; export { AGENTS_SCHEMA, type AuthResult, BindRefusedError, CODEX_TURN_DEFERRED, type CreateL6ServerOptions, DEFAULT_HOST, DEFAULT_PEERS_CONFIG, DEFAULT_PORT, MAX_RECENT_SESSIONS, PeerAuthorityError, type PeerAuthorityOptions, type RunHttpServerOptions, SERVER_INSTRUCTIONS, authenticateBearer, compileCodexTurnFromStore, createL6Server, createServer, errorAgentEntry, exportLocalAgents, getDeeperContextForPrompt, isLoopbackHost, normalizedLegacyToken, prepareRecognitionContextFromStore, recognitionPromptContext, resolveLocalName, resolvePeerClients, runHttpServer, runStdio, summarizeAgentManifest };