/** * `vana mcp requests | approve | deny`: answer the scope requests MCP agents * leave on this account's Personal Server. * * A connected agent (Claude, Claude Code, Cursor) that needs data it cannot * read calls the server's `request_scope_access` tool. The server records the * request on the connection and, when it has a public https origin, hands the * agent a Vana Web link (`/mcp/requests/?ps_origin=`), where * the owner answers from any device. These commands are the same answer from * the terminal, through the owner-only API with the PS session token the CLI * already holds, and the only one for a server without a public URL: * * GET /v1/mcp/connections * POST /v1/mcp/connections/:id/scope-request/approve { scopes } * POST /v1/mcp/connections/:id/scope-request/deny * * The answer endpoints arrived in personal-server-ts 1.30.0; an older server * lists the requests but cannot take the answer. */ import { type AppCommandOptions } from "./app/outcome.js"; import { CliExitCode } from "../core/exit-codes.js"; /** One agent's pending request, as `vana mcp requests` lists it. */ export interface PendingScopeRequest { connectionId: string; displayName: string; scopes: string[]; reason: string | null; requestedAt: string | null; grantedScopes: string[]; /** The Vana Web page to answer it on, when the server has a public origin. */ approvalUrl: string | null; } /** The running server these commands talk to. */ export interface McpOwnerServer { url: string; /** The owner's PS session token; null when the CLI holds none for it. */ token: string | null; /** * The server's public https origin (its tunnel URL), which Vana Web calls * back; null for a `--local` server or before the tunnel is up. */ publicOrigin: string | null; /** Vana Web for the server's network (app.vana.org, app-dev on moksha). */ webOrigin: string | null; } /** Why there is no server to talk to. */ export interface McpOwnerServerProblem { code: "server_unavailable"; message: string; remedy?: string; } export interface McpRequestsDeps { resolveServer(): Promise; fetch?: typeof fetch; now?: () => number; } export declare const SERVER_TOO_OLD_MESSAGE = "Your Personal Server is too old to answer access requests. Update vana, then run `vana server stop && vana server start`."; /** * The Vana Web page for one connection's request, built the way the server's * `vanaWebMcpScopeRequestApprovalUrl` hook builds the link it hands the agent: * `/mcp/requests/?ps_origin=`. Null unless the server * has a public https origin, since a page on the web cannot reach any other. */ export declare function approvalUrlFor(server: Pick, connectionId: string): string | null; interface ConnectionView { id?: unknown; displayName?: unknown; status?: unknown; grants?: unknown; grantedScopes?: unknown; scopeAccessRequest?: { scopes?: unknown; reason?: unknown; requestedAt?: unknown; } | null; } /** The pending request on one connection view, or null. */ export declare function pendingRequestOf(view: ConnectionView, server: Pick | null): PendingScopeRequest | null; /** A failed owner API call, in the words and codes the commands use. */ export declare class McpOwnerApiError extends Error { code: string; remedy?: string | undefined; constructor(code: string, message: string, remedy?: string | undefined); } interface ListedConnections { views: ConnectionView[]; /** Whether the server has the scope-request answer endpoints. */ supportsAnswers: boolean; } /** Every MCP connection on the server, owner view. */ export declare function listConnections(server: McpOwnerServer, fetchImpl?: typeof fetch, timeoutMs?: number): Promise; /** Every pending request on the server, oldest first. */ export declare function listPendingScopeRequests(server: McpOwnerServer, fetchImpl?: typeof fetch, timeoutMs?: number): Promise<{ requests: PendingScopeRequest[]; supportsAnswers: boolean; }>; /** The server's scope-request error, mapped onto the CLI's codes. */ export declare function scopeRequestError(status: number, body: unknown, connectionId: string): McpOwnerApiError; export interface ScopeRequestAnswer { connectionId: string; displayName: string; decision: "approved" | "denied"; approvedScopes: string[]; deniedScopes: string[]; grantedScopes: string[]; grantId: string | null; } /** * Approve (part of) or decline the pending request on one connection. With no * `scopes`, approve approves everything the agent asked for. */ export declare function answerScopeRequest(server: McpOwnerServer, input: { connectionId: string; decision: "approve" | "deny"; scopes?: string[]; }, fetchImpl?: typeof fetch): Promise; /** "5 minutes ago", for a request's age. */ export declare function formatAge(iso: string | null, now: number): string; /** * The one `vana status` line for waiting requests, or null: * "1 access request waiting: Claude wants youtube.history. Run `vana mcp requests`." */ export declare function pendingRequestsStatusLine(requests: PendingScopeRequest[]): string | null; interface Output { stdout(text: string): void; } /** `vana mcp requests` */ export declare function runMcpRequests(options: AppCommandOptions, deps: McpRequestsDeps, out?: Output): Promise; /** `vana mcp approve [--scopes a,b]` and `vana mcp deny ` */ export declare function runMcpAnswer(options: AppCommandOptions, input: { connectionId: string; decision: "approve" | "deny"; scopes?: string; }, deps: McpRequestsDeps): Promise; export {}; //# sourceMappingURL=mcp-requests.d.ts.map