/**
 * HTTP transport for mailpouch (remote / self-host mode).
 *
 * Spec reference: https://modelcontextprotocol.io/specification/2025-11-25
 *
 * Auth is OAuth 2.1 only — there is no shared static bearer. Every caller
 * authenticates as its OWN client, so a token always maps to a specific,
 * gated, revocable agent identity (per-agent grant + audit). Two grant types
 * share the one listener:
 *
 *   1. **authorization_code + PKCE** — interactive agents. RFC 7591 Dynamic
 *      Client Registration + RFC 8414 / 9728 metadata + PKCE S256 + RFC 8707
 *      resource indicators. Consent is automatic; the only human gate is the
 *      per-agent Approve/Deny in the Agents tab (no admin password). The token
 *      is inert until the operator approves the grant.
 *
 *   2. **client_credentials** — headless / unattended agents (cron, CI). The
 *      operator issues a service account out-of-band (`mailpouch agent issue`
 *      or the Settings UI); the agent logs in with its own client_id +
 *      client_secret. The grant is pre-approved at issuance, so no interactive
 *      consent is needed, yet GrantManager still gates every tool call.
 *
 * Every unauthenticated path is rate-limited per IP. The authed /mcp
 * endpoint is rate-limited per token key so a compromised token can't
 * DoS Bridge.
 *
 * Requests without a valid credential get 401 with a `WWW-Authenticate`
 * header per RFC 6750.
 */
import { type IncomingMessage } from "http";
import type { Server as McpServer } from "@modelcontextprotocol/sdk/server/index.js";
import type { AgentGrantStore } from "../agents/grant-store.js";
import type { ServiceAccountStore } from "../agents/service-account-store.js";
export interface HttpTransportOptions {
    /** MCP server instance to wire the transport into (fallback for single-session use). */
    server: McpServer;
    /**
     * Factory that builds a fresh MCP server with all handlers registered. The
     * MCP SDK binds one Server to one transport, so each client session needs its
     * own Server. When provided, a new Server + transport pair is created per
     * session (keyed by Mcp-Session-Id). When omitted, falls back to a single
     * shared `server` (only safe for one session at a time).
     */
    createServer?: () => McpServer;
    /** Bind host. Default 127.0.0.1 (localhost-only). Use 0.0.0.0 for LAN exposure. */
    host?: string;
    /** Port to listen on. */
    port: number;
    /** Path where the MCP endpoint lives. Default /mcp. */
    path?: string;
    /** Optional TLS cert/key paths for HTTPS. If omitted, serves over plain HTTP. */
    tlsCertPath?: string;
    tlsKeyPath?: string;
    /** Enable OAuth 2.1 authorization-server endpoints alongside the static bearer. */
    oauthEnabled?: boolean;
    /** Externally-visible issuer URL. When omitted we derive it from the bind host/port. */
    oauthIssuer?: string;
    /** Requests per second per client for rate limiting (default 20). */
    rateLimitPerSecond?: number;
    /** Burst size (default 40). */
    rateLimitBurst?: number;
    /**
     * Optional grant store to wire into DCR + authed tool calls. When set,
     * each new DCR client gets a pending AgentGrant, and the caller-context
     * dispatched to the MCP handler carries the client_id so the tool
     * dispatcher can consult per-agent permissions. When omitted, the
     * transport behaves as before (bearer-only, no per-agent gating).
     */
    agentGrants?: AgentGrantStore;
    /**
     * Persisted service accounts (client_credentials grant). When set, each is
     * registered into the OAuth client table (for name display) and the token
     * endpoint accepts the client_credentials grant verified against this store.
     * Their matching active AgentGrant is ensured by the caller at startup.
     */
    serviceAccounts?: ServiceAccountStore;
    /**
     * Optional path for persisting issued OAuth access-token hashes so they
     * survive a daemon restart (field finding #7). Only hashes + metadata are
     * written (0600) — never raw bearers. When omitted, tokens are in-memory only.
     */
    oauthTokensPath?: string;
}
export interface HttpTransportHandle {
    /** URL of the MCP endpoint (http[s]://host:port/mcp). */
    url: string;
    /** OAuth issuer URL, present when OAuth is enabled. */
    issuer?: string;
    /** Stop accepting new connections and close existing ones. */
    close: () => Promise<void>;
}
/**
 * Return the caller IP. Trusts `X-Forwarded-For` ONLY when the direct
 * peer is loopback — matches the comment in oauth-handlers.ts and makes
 * the `ipPins` grant condition usable behind a local reverse proxy
 * (Caddy, nginx, Cloudflare Tunnel).
 *
 * XFF is comma-separated "client, proxy1, proxy2, …"; we take the
 * left-most token (the original client). When any parse step fails or
 * the direct peer is not loopback, fall back to the socket address —
 * never fail open to an attacker-controlled header.
 */
export declare function clientIp(req: IncomingMessage): string;
/**
 * Start the HTTP MCP server. Resolves to a handle you can close on shutdown.
 */
export declare function startHttpTransport(opts: HttpTransportOptions): Promise<HttpTransportHandle>;
//# sourceMappingURL=http.d.ts.map