import { JSONObject, StandardSchemaV1 } from '@modelcontextprotocol/client';
export type { JSONObject, JSONValue } from '@modelcontextprotocol/client';
/**
 * Delivery modes an event type may advertise.
 *
 * @experimental
 */
export type MCPEventDeliveryMode = 'poll' | 'push' | 'webhook';
/**
 * One event type from `events/list`.
 *
 * @experimental
 *
 * @example
 * ```ts
 * const events = await client.experimental_events.list()
 * const incident = events.find((event) => event.name === 'incident.created')
 * ```
 */
export interface MCPEventDefinition {
    name: string;
    description?: string;
    delivery: Array<MCPEventDeliveryMode>;
    inputSchema: unknown;
    payloadSchema: unknown;
    _meta?: JSONObject;
}
/**
 * Server-reported webhook delivery health on subscribe/refresh.
 *
 * @experimental
 */
export interface MCPEventDeliveryStatus {
    active?: boolean;
    lastDeliveryAt?: string;
    lastError?: string | null;
    failedSince?: string;
    throttled?: boolean;
    retryAfterMs?: number;
}
/**
 * Result of `events/subscribe` after the client stores a local key.
 *
 * @experimental
 */
export interface MCPEventSubscribeResult {
    key: string;
    id: string;
    refreshBefore: string | null;
    cursor: string | null;
    truncated: boolean;
    deliveryStatus?: MCPEventDeliveryStatus;
}
/**
 * One delivered event occurrence.
 *
 * @experimental
 */
export interface MCPEventOccurrence {
    eventId: string;
    name: string;
    timestamp: string;
    data: JSONObject;
    cursor?: string | null;
}
/**
 * Stored subscription. Must stay server-side: it holds the HMAC secret.
 *
 * @experimental
 */
export interface MCPEventSubscription {
    key: string;
    id?: string;
    name: string;
    arguments: JSONObject;
    definition: MCPEventDefinition;
    delivery: {
        mode: 'webhook';
        url: string;
        secret: string;
    };
    refreshBefore?: string | null;
    cursor: string | null;
    truncated: boolean;
    ttlMs?: number | null;
    maxAgeMs?: number;
    status: 'pending' | 'active';
}
/**
 * Handler-safe view of a subscription. No secret.
 *
 * @experimental
 */
export interface MCPEventSubscriptionInfo {
    key: string;
    id: string;
    name: string;
    arguments: JSONObject;
    delivery: {
        mode: 'webhook';
        url: string;
    };
    refreshBefore: string | null;
}
/**
 * Client store for webhook subscriptions.
 *
 * `update` must merge only the supplied fields.
 * `list` is optional so a cron job can refresh every subscription.
 *
 * @experimental
 *
 * @example
 * ```ts
 * import { inMemoryMCPEventStore } from '@tanstack/ai-mcp/events'
 *
 * const store = inMemoryMCPEventStore()
 * const mcp = await createMCPClient({
 *   transport: { type: 'http', url: 'https://mcp.example.com/mcp' },
 *   experimental_events: { store },
 * })
 * ```
 */
export interface MCPEventStore {
    get: (key: string) => Promise<MCPEventSubscription | undefined>;
    getById: (id: string) => Promise<MCPEventSubscription | undefined>;
    set: (subscription: MCPEventSubscription) => Promise<void>;
    update: (key: string, patch: Partial<Omit<MCPEventSubscription, 'key'>>) => Promise<void>;
    delete: (key: string) => Promise<void>;
    list?: () => AsyncIterable<MCPEventSubscription>;
}
/**
 * Direct mode: the client talks to the MCP server and this store.
 *
 * @experimental
 */
export interface DirectMCPEventsOptions {
    store: MCPEventStore;
    adapter?: never;
    /**
     * Called on each `subscribe()` call, not on `refresh()`. Throw to reject.
     * The SDK does not validate against `inputSchema`.
     *
     * @example
     * ```ts
     * experimental_events: {
     *   store,
     *   validateArguments: ({ arguments: args }) => {
     *     if (typeof args.repo !== 'string') throw new Error('repo required')
     *   },
     * }
     * ```
     */
    validateArguments?: (args: {
        definition: MCPEventDefinition;
        arguments: JSONObject;
    }) => void | PromiseLike<void>;
}
/**
 * Transport context passed to a managed events adapter.
 *
 * @experimental
 */
export type MCPEventAdapterTransport = {
    type: 'http';
    url: string;
} | {
    type: 'sse';
    url: string;
} | {
    type: 'custom';
};
/**
 * Status values used by managed adapters such as Vercel Connect.
 *
 * @experimental
 */
export type ManagedMCPSubscriptionStatus = 'pending' | 'active' | 'needs_auth' | 'stopped' | 'expired' | 'failed';
/**
 * One managed subscription record.
 *
 * @experimental
 */
export interface ManagedMCPSubscription {
    id: string;
    name: string;
    arguments: JSONObject;
    status: ManagedMCPSubscriptionStatus;
    expiresAt: string | null;
    idempotencyKey?: string;
    context?: JSONObject;
}
/**
 * Input for a managed adapter `subscribe` call.
 *
 * @experimental
 */
export interface ManagedMCPSubscribeInput {
    name: string;
    arguments: JSONObject;
    context?: JSONObject;
    idempotencyKey: string;
    ttlMs: number | null;
    options?: {
        signal?: AbortSignal;
        timeout?: number;
    };
}
/**
 * Operations returned by `adapter.createAdapter`.
 *
 * @experimental
 */
export interface MCPEventOperations {
    subscribe: (input: ManagedMCPSubscribeInput) => Promise<ManagedMCPSubscription>;
    getSubscription: (id: string) => Promise<ManagedMCPSubscription | undefined>;
    listSubscriptions: () => Promise<Array<ManagedMCPSubscription>>;
    unsubscribe: (id: string) => Promise<void>;
}
/**
 * Hosted-backend adapter. `createAdapter` is synchronous and called once.
 *
 * @experimental
 *
 * @example
 * ```ts
 * const mcp = await createMCPClient({
 *   transport: { type: 'http', url: 'https://mcp.example.com/mcp' },
 *   experimental_events: { adapter },
 * })
 * await mcp.experimental_events.subscribe({
 *   name: 'incident.created',
 *   arguments: { repo: 'acme/app' },
 *   idempotencyKey: 'incident:acme/app',
 *   ttlMs: 3_600_000,
 * })
 * ```
 */
export interface MCPEventAdapter {
    createAdapter: (context: {
        transport: MCPEventAdapterTransport;
    }) => MCPEventOperations;
}
/**
 * Managed mode: subscribe goes through the adapter. `list` still uses MCP.
 *
 * @experimental
 */
export interface ManagedMCPEventsOptions {
    adapter: MCPEventAdapter;
    store?: never;
    validateArguments?: never;
}
/**
 * `createMCPClient({ experimental_events })` option.
 * Omit it for discovery-only (`list()`).
 *
 * @experimental
 */
export type MCPEventsOptions = DirectMCPEventsOptions | ManagedMCPEventsOptions;
/**
 * Lookup key for refresh and unsubscribe in direct mode.
 *
 * @experimental
 */
export type MCPEventSubscriptionRef = ({
    key: string;
    id?: never;
} | {
    id: string;
    key?: never;
}) & {
    signal?: AbortSignal;
};
/**
 * Options for a direct-mode subscribe call.
 *
 * @experimental
 *
 * @example
 * ```ts
 * const sub = await client.experimental_events.subscribe({
 *   name: 'incident.created',
 *   arguments: { repo: 'acme/app' },
 *   delivery: {
 *     mode: 'webhook',
 *     url: 'https://app.example.com/api/mcp-events',
 *   },
 * })
 * ```
 */
export interface SubscribeMCPEventOptions {
    name: string;
    arguments?: JSONObject;
    delivery: {
        mode: 'webhook';
        url: string;
        secret?: string;
        allowInsecureLocalhost?: boolean;
    };
    cursor?: string | null;
    ttlMs?: number | null;
    maxAgeMs?: number;
    signal?: AbortSignal;
}
/**
 * Direct and discovery events API on `client.experimental_events`.
 *
 * @experimental
 */
export interface MCPEvents {
    list: (options?: {
        signal?: AbortSignal;
    }) => Promise<Array<MCPEventDefinition>>;
    subscribe: (options: SubscribeMCPEventOptions) => Promise<MCPEventSubscribeResult>;
    refresh: (options: MCPEventSubscriptionRef) => Promise<MCPEventSubscribeResult>;
    unsubscribe: (options: MCPEventSubscriptionRef) => Promise<void>;
}
/**
 * Managed events API: MCP `list()` plus adapter operations. No `refresh`.
 *
 * @experimental
 */
export interface ManagedMCPEvents extends MCPEventOperations {
    list: (options?: {
        signal?: AbortSignal;
    }) => Promise<Array<MCPEventDefinition>>;
}
/**
 * What `client.ts` hands to the `events/*` modules. Internal.
 */
export interface MCPEventsContext {
    /** Sends one `events/*` request. The SDK validates the result with `schema`. */
    request: <T>(method: 'events/list' | 'events/subscribe' | 'events/unsubscribe', params: Record<string, unknown>, schema: StandardSchemaV1<unknown, T>, signal?: AbortSignal) => Promise<T>;
    assertOpen: () => void;
    readonly supportsEvents: boolean;
    readonly transport: MCPEventAdapterTransport;
}
/**
 * Receiver options for `createMCPEventWebhook`.
 *
 * @experimental
 *
 * @example
 * ```ts
 * import { createMCPEventWebhook } from '@tanstack/ai-mcp/events'
 *
 * const webhook = createMCPEventWebhook({
 *   store,
 *   onEvent: async ({ event }) => {
 *     await queue.send({ eventId: event.eventId, data: event.data })
 *   },
 * })
 * ```
 */
export interface MCPEventWebhookOptions {
    store: MCPEventStore;
    onEvent: (args: {
        subscription: MCPEventSubscriptionInfo;
        event: MCPEventOccurrence;
        messageId: string;
    }) => Promise<void> | void;
    onGap?: (args: {
        subscription: MCPEventSubscriptionInfo;
        messageId: string;
        gap: {
            cursor: string;
            truncated: true;
        };
    }) => Promise<void> | void;
    onTerminated?: (args: {
        subscription: MCPEventSubscriptionInfo;
        messageId: string;
        termination: {
            code: number;
            message: string;
            data?: unknown;
        };
    }) => Promise<void> | void;
    /**
     * Throw to reject the event with HTTP 400.
     */
    validatePayload?: (args: {
        definition: MCPEventDefinition;
        data: JSONObject;
    }) => void | PromiseLike<void>;
    /**
     * Called on failed checks. Never receives secrets.
     */
    onError?: (error: MCPEventWebhookError) => void;
    toleranceSeconds?: number;
    maxBodyBytes?: number;
    now?: () => number;
}
/**
 * Receiver error passed to `onError`. Messages never include the secret.
 *
 * @experimental
 */
export declare class MCPEventWebhookError extends Error {
    readonly stage: 'headers' | 'routing' | 'signature' | 'timestamp' | 'body' | 'envelope' | 'payload' | 'handler' | 'store';
    readonly subscriptionKey?: string;
    constructor(stage: MCPEventWebhookError['stage'], message: string, options?: {
        subscriptionKey?: string;
        cause?: unknown;
    });
}
export type MCPEventWebhookStage = MCPEventWebhookError['stage'];
