/** * Core types for the app-agnostic MCP layer. * * The design in one sentence: generate one MCP tool per OpenAPI operation, and * dispatch each tool call by proxying to the real HTTP endpoint carrying the * caller's bearer token — so an agent gets exactly the user's permissions and * authorization stays entirely in the endpoints (never re-implemented here). * * This package is deliberately free of any app/domain specifics and of the MCP * transport SDK: it turns a spec into tools and a tool call into an HTTP request. * The consuming app supplies the OpenAPI document, the base URL, and an * {@link AuthResolver}; it binds {@link ToolRegistry} to the MCP transport. */ /** A JSON Schema object (draft 2020-12). We treat schemas opaquely and forward them. */ type JsonSchema = Record; /** * MCP tool-behavior annotations used by clients for review and confirmation. * * Every value is required intentionally. ChatGPT App review treats a missing * hint as a blocker, and an implicit protocol default is not enough evidence * that a tool's behavior was audited. The Anthropic connector directory * additionally requires a human-readable `title` on every tool, and derives * auto-permissions from `readOnlyHint`/`destructiveHint`. */ interface ToolAnnotations { /** Human-readable tool label (required by the Anthropic connector review). */ title: string; readOnlyHint: boolean; openWorldHint: boolean; destructiveHint: boolean; } /** Where an operation parameter is carried in the HTTP request. */ type ParameterLocation = "path" | "query" | "header"; /** One OpenAPI operation parameter, retained so the dispatcher can route args. */ interface ToolParameter { name: string; in: ParameterLocation; required: boolean; schema: JsonSchema; } /** * A single generated MCP tool: an agent-facing input schema plus everything the * dispatcher needs to reconstruct the HTTP call. This is the unit that is both * served to agents and committed to the drift manifest. */ interface GeneratedTool { /** Stable tool id: the operationId, or a `method_path` slug when absent. */ name: string; description: string; /** Uppercase HTTP method, e.g. "GET", "POST". */ method: string; /** OpenAPI path template, e.g. "/products/{id}". */ path: string; /** Agent-facing input schema (params + flattened request-body properties). */ inputSchema: JsonSchema; /** Documented success-response schema, when the spec provides one. */ outputSchema?: JsonSchema; /** Explicit, behavior-audited MCP review hints. */ annotations: ToolAnnotations; /** * Dotted response paths stripped before the result reaches the agent. * * `outputSchema` is advertisement only — the dispatcher forwards the upstream * body verbatim — so narrowing a schema alone would misdescribe what is * actually sent. Redaction is what removes the value; the narrowed schema * just keeps the advertisement honest. A segment that lands on an array is * applied to every element. */ redactResponse?: readonly string[]; /** Path/query/header parameters, in declaration order. */ parameters: ToolParameter[]; /** Top-level property names sourced from the request body (routed to the body). */ bodyProps: string[]; /** True when the request body is not an object (sent verbatim as the payload). */ bodyIsWhole: boolean; /** True for POST/PUT/PATCH/DELETE — a write. Consumers may gate these. */ mutating: boolean; /** OpenAPI security requirement names referenced by the operation, if any. */ security: string[]; } /** The committed source-of-truth artifact the drift gate (`mcp:check`) diffs. */ interface ToolManifest { /** Bumped on any intentional shape change (mirrors the golden-catalog convention). */ version: number; /** Human label for the spec the tools were generated from. */ source: string; tools: GeneratedTool[]; } /** Options controlling tool generation from an OpenAPI document. */ interface GenerateOptions { /** Only include operations whose method is in this set (default: all). */ includeMethods?: readonly string[]; /** Drop operations tagged with any of these (e.g. "internal"). */ excludeTags?: readonly string[]; /** Predicate to include/exclude an operation by (method, path). */ filter?: (method: string, path: string) => boolean; } /** * The caller's resolved authorization for a single request. The dispatcher only * ever forwards `bearer` upstream; identity/permission checks happen at the * endpoint. `subject`/`scopes` are surfaced for logging and tool-visibility * decisions, not for authorization. */ interface RequestAuth { /** The bearer token to forward to the upstream endpoint (verbatim). */ bearer: string; /** Token subject (for logging only). */ subject?: string; /** Granted scopes (for optional tool visibility filtering). */ scopes?: readonly string[]; } /** * App-supplied hook that turns an incoming request into {@link RequestAuth}, or * `null` when unauthenticated. For the OAuth resource-server mode this validates * the access token (signature/audience/scope) and returns the token to forward. */ type AuthResolver = (request: Request) => Promise; /** Configuration for a proxying dispatch. */ interface DispatchConfig { /** Origin the tools are proxied to, e.g. "https://app.example.com". */ baseUrl: string; /** The caller's bearer, forwarded as `Authorization: Bearer `. */ bearer: string; /** Injectable fetch (defaults to global fetch) — eases testing. */ fetchImpl?: typeof fetch; } /** The upstream response, normalized for the MCP layer. */ interface DispatchResult { status: number; ok: boolean; /** Parsed JSON body when the response was JSON, else the raw text. */ body: unknown; } /** * Minimal structural view of the OpenAPI 3.x document we consume. We intentionally * model only the subset the generator reads; unknown fields are ignored and any * `$ref` in a leaf schema is forwarded opaquely (the document is expected to be * dereferenced by the loader for anything we need to introspect — request-body * object properties in particular). */ interface OpenApiOperation { operationId?: string; summary?: string; description?: string; tags?: string[]; /** Paladira's required projection of MCP tool annotations into OpenAPI. */ "x-mcp-tool-annotations"?: ToolAnnotations; /** Dotted response paths stripped from the result before the agent sees it. */ "x-mcp-redact-response"?: readonly string[]; parameters?: OpenApiParameter[]; requestBody?: OpenApiRequestBody; responses?: Record; security?: Array>; } interface OpenApiParameter { name: string; in: string; required?: boolean; schema?: JsonSchema; } interface OpenApiRequestBody { required?: boolean; content?: Record; } interface OpenApiResponse { content?: Record; } interface OpenApiDocument { paths?: Record>; security?: Array>; } /** * Generate one {@link GeneratedTool} per OpenAPI operation. Deterministic: the * same document always yields the same tools in path/method declaration order, * which is what makes the drift gate (`mcp:check`) a stable diff. */ declare function generateTools(doc: OpenApiDocument, options?: GenerateOptions): GeneratedTool[]; export { type AuthResolver as A, type DispatchConfig as D, type GeneratedTool as G, type JsonSchema as J, type OpenApiDocument as O, type ParameterLocation as P, type RequestAuth as R, type ToolManifest as T, type ToolAnnotations as a, type DispatchResult as b, type GenerateOptions as c, type OpenApiOperation as d, type OpenApiParameter as e, type OpenApiRequestBody as f, type OpenApiResponse as g, type ToolParameter as h, generateTools as i };