export declare const mcpApprovalsStore: import("../db/store-registry.js").Store; export declare function ensureApprovalTable(): Promise; /** * The app a grant belongs to. Apps can share a database and an origin, and * have actions with the same name, so only the app that asked uses a grant. */ export declare function mcpApprovalAppId(config: { appId?: string; name: string; }): string; /** The identity of one exact call, as a grant binds it. */ export interface McpApprovalCall { appId: string; callerKey: string; actionName: string; argumentsHash: string; } /** What a grant binds: one caller, one action, one exact call, until it expires. */ export interface McpApprovalGrant extends McpApprovalCall { nonce: string; expiresAt: number; } /** * A grant as it is created: the call it binds, who asked for it, and the * arguments the review page renders. The page renders nothing else the caller * sent. The arguments are stored redacted, as the audit log stores them. */ export interface NewMcpApprovalGrant extends McpApprovalGrant { ownerEmail: string; orgId: string | null; /** From `storedApprovalArguments`; null when they could not be stored. */ argumentsJson: string | null; /** The OAuth client whose connection made the call, if it used one. */ oauthClientId: string | undefined; /** The action declares that running this exact call again can't duplicate it. */ retrySafe: boolean; } /** * `pending` until someone answers; every other status is final. A client's * approve answers and uses the grant at once, while a review page approval * waits for the identical call to come back and use it. `denied` is a * person's explicit no, on the page or in the client's form. `declined` is a * client that declined or cancelled its prompt, which may have been the * client itself, so the caller gets a new grant to review on the page. */ export type McpApprovalStatus = "pending" | "approved" | "denied" | "declined"; /** * How the run a used grant allowed went. `failed` wrote nothing; `unknown` * failed after it may have written, which a person must know before they * approve the same call again. */ export type McpApprovalRunStatus = "running" | "completed" | "failed" | "unknown"; export interface McpApprovalRecord extends McpApprovalGrant { ownerEmail: string | null; orgId: string | null; /** * The redacted arguments as JSON while the grant can still be approved or * used; null once it is final or expired, or when none were stored. */ argumentsJson: string | null; oauthClientId: string | null; retrySafe: boolean; status: McpApprovalStatus; /** Who decided on the review page; null when the MCP client answered. */ approverEmail: string | null; approvedAt: number | null; deniedAt: number | null; createdAt: number | null; consumedAt: number | null; runStatus: McpApprovalRunStatus | null; runSettledAt: number | null; } /** The call's arguments as a grant stores them: redacted, and capped. */ export declare function storedApprovalArguments(args: unknown): string | null; export declare function normalizeApprovalEmail(email: string): string; export declare function createMcpApprovalGrant(grant: NewMcpApprovalGrant): Promise; /** * Clears the stored arguments of every grant that can no longer be approved * or used, and deletes grants a day past their expiry. Runs on the recurring * sweep, so it doesn't wait for a new grant; a failure throws for the sweep * to report. */ export declare function pruneMcpApprovalGrants(now?: number): Promise; /** * The client approved the grant it was asked about: approves and uses it in * one step. Refused once the client has answered, the grant is used or * ended, or it expired. */ export declare function consumeMcpApprovalGrant(grant: McpApprovalGrant): Promise; /** * The client answered its prompt without approving it. `opened` is a URL * prompt the person accepted, so the grant waits for the review page; * `declined` and `denied` end it. The client cannot answer a grant twice: * false when it already had, or the grant is used, decided or expired. */ export declare function answerMcpApprovalPrompt(grant: McpApprovalGrant, answer: "opened" | "declined" | "denied"): Promise; /** * Uses a grant a person approved on the review page for this exact call, if * there is one (`nonce`, when given): once, by this caller, before it * expires. */ export declare function consumeReviewedMcpApprovalGrant(call: McpApprovalCall, nonce?: string): Promise; /** Records how the run a used grant allowed ended. */ export declare function recordMcpApprovalRun(nonce: string, status: "completed" | "failed" | "unknown"): Promise; /** * The latest grant this exact call used since `since` whose run may have * done something: it completed, it is still running, or its outcome is * unknown. */ export declare function findRecentMcpApprovalRun(call: McpApprovalCall, since: number): Promise; /** Who reads or decides a grant on the review page, and in which app. */ export interface McpApprovalReader { appId: string; email: string; orgId: string | null; } /** A grant as its owner may see it: same app, same user, same organization. */ export declare function getMcpApprovalForOwner(nonce: string, reader: McpApprovalReader): Promise; /** * Whether the grant is the reader's own in this app, but from another of * their organizations, so the page can tell them to switch. Says nothing * about anyone else's grants. */ export declare function isMcpApprovalInOtherOrganization(nonce: string, reader: McpApprovalReader): Promise; /** * The owner's decision on the review page. Only a pending, unused, unexpired * grant takes one, so a second decision, a replayed request, or a decision * after expiry changes nothing and returns false. Approving moves the expiry * to `approvedUntil`: how long the identical call has to come back and use it. */ export declare function decideMcpApproval(nonce: string, reader: McpApprovalReader, decision: "approve" | "deny", approvedUntil: number): Promise;