export declare const toolKindValidator: import("convex/values").VUnion<"query" | "mutation" | "action", [import("convex/values").VLiteral<"query", "required">, import("convex/values").VLiteral<"mutation", "required">, import("convex/values").VLiteral<"action", "required">], "required", never>; export declare const auditOutcomeValidator: import("convex/values").VUnion<"allowed" | "denied" | "error", [import("convex/values").VLiteral<"allowed", "required">, import("convex/values").VLiteral<"denied", "required">, import("convex/values").VLiteral<"error", "required">], "required", never>; export declare const auditEntryTypeValidator: import("convex/values").VUnion<"tool" | "resource" | "task", [import("convex/values").VLiteral<"tool", "required">, import("convex/values").VLiteral<"resource", "required">, import("convex/values").VLiteral<"task", "required">], "required", never>; export declare const resourceAuditOperationValidator: import("convex/values").VUnion<"list" | "read" | "templates_list", [import("convex/values").VLiteral<"list", "required">, import("convex/values").VLiteral<"read", "required">, import("convex/values").VLiteral<"templates_list", "required">], "required", never>; export declare const taskAuditOperationValidator: import("convex/values").VUnion<"create" | "input" | "cancel" | "complete" | "fail", [import("convex/values").VLiteral<"create", "required">, import("convex/values").VLiteral<"input", "required">, import("convex/values").VLiteral<"cancel", "required">, import("convex/values").VLiteral<"complete", "required">, import("convex/values").VLiteral<"fail", "required">], "required", never>; export declare const taskStatusValidator: import("convex/values").VUnion<"completed" | "cancelled" | "working" | "input_required" | "failed", [import("convex/values").VLiteral<"working", "required">, import("convex/values").VLiteral<"input_required", "required">, import("convex/values").VLiteral<"completed", "required">, import("convex/values").VLiteral<"failed", "required">, import("convex/values").VLiteral<"cancelled", "required">], "required", never>; declare const _default: import("convex/server").SchemaDefinition<{ tools: import("convex/server").TableDefinition; description: import("convex/values").VString; kind: import("convex/values").VUnion<"query" | "mutation" | "action", [import("convex/values").VLiteral<"query", "required">, import("convex/values").VLiteral<"mutation", "required">, import("convex/values").VLiteral<"action", "required">], "required", never>; functionHandle: import("convex/values").VString; inputSchema: import("convex/values").VAny; /** * Optional MCP `outputSchema` (JSON Schema). When set, tools/list * advertises it and tools/call wraps results in `structuredContent` * alongside the text-JSON `content`. Pre-existing rows without the * column stay valid courtesy of `v.optional`. */ outputSchema: import("convex/values").VAny; /** * The schemas exactly as the host authored them, JSON-encoded, and * the form `tools/list` advertises. Two reasons they are strings * rather than objects, and both are load-bearing: * * - Convex reserves field names beginning with `$`, so a * spec-conformant `$schema` or `$defs` cannot be stored as a * Convex object at all. Inside a string it is just characters. * - Resolution inlines `$ref` and drops `$defs`, which is right for * the gateway's own `Mcp-Param-*` walk and wrong for the wire: * SEP-1613 asks that those keywords reach the client. * * So the resolved objects above stay the gateway's internal view and * these carry the client's. Rows written before this field fall back * to advertising the resolved form, which is what they did before. */ authoredInputSchemaJson: import("convex/values").VString; authoredOutputSchemaJson: import("convex/values").VString; /** * Name of the tool-function argument the gateway fills with the * resolved caller identity before dispatch. Excluded from the * advertised inputSchema and stripped from caller args. Optional; * unset means the tool takes no injected identity. Pre-existing rows * without the column stay valid courtesy of `v.optional`. */ identityArg: import("convex/values").VString; /** * Name of the tool argument the gateway fills with the MRTR * continuation's stable idempotency key when a verified retry * continues to dispatch (and with the task's own idempotency key * when the tool runs as an MCP task). Excluded from the advertised * inputSchema and stripped from caller args. Continuation state and * input responses are never injected; they stay in the host-side hook. */ mrtrArgs: import("convex/values").VObject<{ idempotencyKey: string; } | undefined, { idempotencyKey: import("convex/values").VString; }, "optional", "idempotencyKey">; /** * True when the tool was registered with a host-side `beforeCall` * hook (or reserves `mrtrArgs`). A gated row must never dispatch * without its hook: a handler serving this registry without a * matching `beforeCall` fails the call closed instead of silently * skipping the confirmation the row promises. */ mrtrGated: import("convex/values").VBoolean; /** * Opt-in MCP Tasks support (`io.modelcontextprotocol/tasks`). Only a * tool that sets this may be invoked as a task-augmented modern * `tools/call`; the catalog advertises it as * `execution: { taskSupport: "optional" }` when the host has * configured task execution. Pre-existing rows without the column * stay valid courtesy of `v.optional`. */ taskSupport: import("convex/values").VUnion, import("convex/values").VLiteral<"forbidden", "required">, import("convex/values").VLiteral<"optional", "required">, import("convex/values").VLiteral<"required", "required">], "optional", never>; /** MCP-facing title, annotations, `_meta`, and security schemes. */ protocolMetadata: import("convex/values").VAny; metadata: import("convex/values").VAny; }, "required", "description" | "kind" | "name" | "metadata" | "authoredInputSchemaJson" | "authoredOutputSchemaJson" | "functionHandle" | "identityArg" | "inputSchema" | "mrtrArgs" | "mrtrGated" | "outputSchema" | "protocolMetadata" | "taskSupport" | `metadata.${string}` | `inputSchema.${string}` | "mrtrArgs.idempotencyKey" | `outputSchema.${string}` | `protocolMetadata.${string}`>, { by_name: ["name", "_creationTime"]; by_functionHandle: ["functionHandle", "_creationTime"]; }, {}, {}>; resources: import("convex/server").TableDefinition; name: import("convex/values").VString; description: import("convex/values").VString; mimeType: import("convex/values").VString; metadata: import("convex/values").VAny; }, "required", "description" | "name" | "uri" | "metadata" | "mimeType" | `metadata.${string}`>, { by_uri: ["uri", "_creationTime"]; }, {}, {}>; /** * Persisted MCP resource templates (RFC 6570), the template counterpart * of `resources`. Stores catalog metadata only, never the `read` * handler or matcher. `annotations` is stored as `v.any()` (its shape is * validated host-side before write); `title`/`annotations` are persisted * here (unlike concrete resources, where they are runtime-only) so a * registry-only template still lists its full descriptor. */ resourceTemplates: import("convex/server").TableDefinition; name: import("convex/values").VString; title: import("convex/values").VString; description: import("convex/values").VString; mimeType: import("convex/values").VString; annotations: import("convex/values").VAny; /** * Icons a client may display next to the template. Stored as `v.any()` * like `annotations` (the shape is validated host-side before the * write), and persisted for the same reason `title` is: a registry-only * template must still list its full descriptor. */ icons: import("convex/values").VAny; }, "required", "description" | "title" | "name" | "mimeType" | "annotations" | "icons" | "uriTemplate" | `annotations.${string}` | `icons.${string}`>, { by_uriTemplate: ["uriTemplate", "_creationTime"]; }, {}, {}>; /** * Singleton row holding the OAuth 2.1 protected-resource metadata. * Empty until the host calls `gateway.setOAuthConfig`. * * Authorization itself is **not** stored here: it lives in the host * as a regular JS callback passed to `gateway.handleMcpRequest`, * because Convex doesn't propagate `ctx.auth` into component code. * * A row exists at most once. We don't use an index because lookups * always fetch the single row. */ config: import("convex/server").TableDefinition; /** * Canonical resource URL for this MCP server, returned in the * protected-resource metadata. Optional: when unset, the discovery * endpoint derives it from the inbound request URL (without the * `/.well-known/...` suffix), which is correct for single-tenant * deployments. */ resourceUrl: import("convex/values").VString; /** * Legacy field from the pre-callback authorizer model. Tolerated * here so old deployments deploy cleanly; the new `setOAuthConfig` * uses `db.replace` and silently drops it. Will be removed in a * future release. */ authorizerHandle: import("convex/values").VString; /** * Fingerprint of the declarative tool catalog last synced via the * `tools` option of `handleMcpRequest`. Lets the host skip rewriting * the registry when the list is unchanged (the common case on every * `initialize`). Set by the declarative sync, cleared by the * imperative `register` path. Optional: absent means "never synced * declaratively". */ toolsFingerprint: import("convex/values").VString; /** * Fingerprint of the declarative resource catalog last synced via * `handleMcpRequest`. Resource contents/read handlers are not stored * here; the registry stores stable catalog metadata only. */ resourcesFingerprint: import("convex/values").VString; /** * Fingerprint of the declarative resource-template catalog last synced * via the `resourceTemplates` option of `handleMcpRequest`. Mirrors * `resourcesFingerprint`; absent means "never synced declaratively". */ templatesFingerprint: import("convex/values").VString; }, "required", "authServerUrl" | "resourceUrl" | "authorizerHandle" | "toolsFingerprint" | "resourcesFingerprint" | "templatesFingerprint">, {}, {}, {}>; /** * MCP Streamable HTTP sessions. Created on `initialize` if the client * negotiated session-aware transport, looked up on every subsequent * request, and deleted on explicit `DELETE` or after a server-side * timeout (managed by the host via a cron, not the component). * * `sessionId` is a 128-bit cryptographically random hex string, * matching the MCP 2025-06-18 requirement that it be globally unique * and consist of visible ASCII characters only. * * `identitySubject` records the JWT `sub` claim that initialised the * session (or `null` for anonymous initialisation). It is set at * create time and never changes; `DELETE /mcp/` requires the same * subject to authorise teardown, so a leaked session id alone * cannot DoS an authenticated user's session. Optional for * forward-compat with pre-binding session rows: such rows skip the * identity check on DELETE. */ sessions: import("convex/server").TableDefinition; protocolVersion: import("convex/values").VString; createdAt: import("convex/values").VFloat64; lastSeenAt: import("convex/values").VFloat64; identitySubject: import("convex/values").VUnion, import("convex/values").VNull], "optional", never>; }, "required", "identitySubject" | "protocolVersion" | "sessionId" | "createdAt" | "lastSeenAt">, { by_sessionId: ["sessionId", "_creationTime"]; by_lastSeenAt: ["lastSeenAt", "_creationTime"]; }, {}, {}>; /** * Opt-in MCP resource subscriptions, one row per (session, resource URI). * Populated by `resources/subscribe` and cleared by `resources/unsubscribe` * (and cascaded on session teardown). The gateway's own HTTP transport * cannot push `notifications/resources/updated`, so this table only * *records intent*: a host that fronts the gateway with a push-capable * transport reads it via `listResourceSubscribers` to decide whom to * notify. Rows orphaned by idle-pruned sessions are cleaned by * `pruneOrphanResourceSubscriptions`. */ subscriptions: import("convex/server").TableDefinition; uri: import("convex/values").VString; createdAt: import("convex/values").VFloat64; }, "required", "uri" | "sessionId" | "createdAt">, { by_session_uri: ["sessionId", "uri", "_creationTime"]; by_uri: ["uri", "_creationTime"]; }, {}, {}>; /** * One-time redemption of MRTR continuations, one row per redeemed * continuation id (`jti`, minted into the sealed `requestState`). * A continuation stays cryptographically valid until its TTL, so * without this table a captured `requestState` could be replayed * with different `inputResponses` and flip an already-resolved * decision (decline to accept) on that same continuation. First * redemption wins: a retry with byte-identical responses is an * idempotent replay and re-processes; different responses for the * same `jti` are rejected. Expired rows are dropped by * `pruneMrtrRedemptions` from a host cron. * * This is per continuation. Chain-level resolution lives in * `mrtrChains` below, because `jti` is fresh per round and cannot * express "this conversation is over". */ mrtrRedemptions: import("convex/server").TableDefinition; responsesDigest: import("convex/values").VString; expiresAt: import("convex/values").VFloat64; }, "required", "expiresAt" | "jti" | "responsesDigest">, { by_jti: ["jti", "_creationTime"]; by_expiresAt: ["expiresAt", "_creationTime"]; }, {}, {}>; /** * One row per resolved MRTR chain, keyed by the chain's stable * idempotency key (constant across every round, unlike `jti`). * * A chain resolves exactly once, when the gateway either dispatches * the tool or finishes the call itself via `completeCall()`. The row * is inserted BEFORE either happens, so the insert is the decision: * whoever claims first wins, and every other continuation of that * chain is refused afterwards. * * Without it, redemption only protects a single continuation. Each * `inputRequired()` seals a new `jti` with no row of its own, so any * path that makes the hook ask again (an idempotent replay, or a * state-only retry) forks an independent branch that stays answerable * after a sibling already resolved the decision. Claiming the chain * closes every branch at once: only the continuation that resolved * the chain, re-sent with the same answer, may dispatch again. That * repeat is deliberate (a client whose response was lost), so the * gateway does NOT make dispatch strictly at-most-once; the tool's * injected idempotency key is what keeps the side effect single. * * Expired rows are dropped by `pruneMrtrRedemptions` alongside the * redemption rows, so hosts wire one cron, not two. */ mrtrChains: import("convex/server").TableDefinition; /** What resolved it, for operator forensics. Never sent on the wire. */ resolution: import("convex/values").VUnion<"dispatched" | "completed", [import("convex/values").VLiteral<"dispatched", "required">, import("convex/values").VLiteral<"completed", "required">], "required", never>; /** * WHICH continuation resolved it. A lost response may be retried, * so the resolving continuation is allowed to reproduce its own * outcome; every other continuation of the chain is not, even one * re-sent byte-identically. Without this the gateway could only ask * "was this continuation re-sent?", which a sibling also answers * yes to, letting it pass its own hook output off as the * chain's settled result. */ resolvedByJti: import("convex/values").VString; /** * Digest of the `inputResponses` that continuation carried, absent * when it carried none. A repeat has to present the same answer, * not just the same continuation: otherwise the holder of a * state-only continuation that already resolved the chain could * re-send it with arbitrary responses and run the host's hook on a * settled decision. */ resolvedByDigest: import("convex/values").VString; expiresAt: import("convex/values").VFloat64; }, "required", "chainKey" | "expiresAt" | "resolution" | "resolvedByJti" | "resolvedByDigest">, { by_chainKey: ["chainKey", "_creationTime"]; by_expiresAt: ["expiresAt", "_creationTime"]; }, {}, {}>; /** * MCP Tasks (`io.modelcontextprotocol/tasks`): one row per task-augmented * modern `tools/call`. The row is the durable source of truth for the * task lifecycle (`working` → `input_required` ⇄ `working` → * `completed` | `failed` | `cancelled`); the client polls it via * `tasks/get` and updates it via `tasks/update`, and the host finalizes * it through the trusted `completeTask` / `failTask` / * `requireTaskInput` client APIs. * * `taskId` is a 128-bit cryptographically random hex string generated * host-side (never client-supplied). `ownerSubject` binds the task to * the authenticated caller that created it; every owner-facing read or * update must match it, and a mismatch is answered exactly like an * unknown id so foreign tasks are unobservable. * * `args` snapshots the public tool arguments for deferred execution by * the built-in scheduled executor; `caller` snapshots the resolved * identity for `identityArg` injection at execution time. Neither is * ever returned on the wire, and neither appears in an * `entryType: "task"` audit row. The `entryType: "tool"` row that * `dispatch.runTool` writes for the run itself DOES carry the * arguments, verbatim: a `taskSupport` tool may not set * `metadata.auditArgs`, precisely so that this is unambiguous. * * `idempotencyKey` is issued once per task; the executing tool persists * it around its side effect so workflow retries and duplicate client * updates cannot double-apply. Repeated `tasks/update` submissions of * byte-identical responses are answered idempotently while the same * round is still pending; a re-send against a superseded round is * `stale_round`, and against a completed or failed row `conflict`. */ tasks: import("convex/server").TableDefinition; ownerSubject: import("convex/values").VString; toolName: import("convex/values").VString; toolKind: import("convex/values").VUnion<"query" | "mutation" | "action", [import("convex/values").VLiteral<"query", "required">, import("convex/values").VLiteral<"mutation", "required">, import("convex/values").VLiteral<"action", "required">], "required", never>; args: import("convex/values").VAny; caller: import("convex/values").VObject<{ claims?: any; subject: string; } | undefined, { subject: import("convex/values").VString; claims: import("convex/values").VAny; }, "optional", "subject" | "claims" | `claims.${string}`>; status: import("convex/values").VUnion<"completed" | "cancelled" | "working" | "input_required" | "failed", [import("convex/values").VLiteral<"working", "required">, import("convex/values").VLiteral<"input_required", "required">, import("convex/values").VLiteral<"completed", "required">, import("convex/values").VLiteral<"failed", "required">, import("convex/values").VLiteral<"cancelled", "required">], "required", never>; /** * The tool's own return value. The MCP `CallToolResult` a client polls * is derived from this and the two flags below when the task is read, * never stored: an envelope would keep the value twice over (escaped * inside `content[0].text` and again as `structuredContent`), so a * legal 256 KiB result could serialize past Convex's document limit * after the tool had already committed its writes. */ result: import("convex/values").VAny; /** The call ran and reported a failure: becomes `isError` on the wire. */ resultIsError: import("convex/values").VBoolean; /** The tool declares an `outputSchema`, so derive `structuredContent`. */ resultStructured: import("convex/values").VBoolean; error: import("convex/values").VObject<{ message: string; code: number; } | undefined, { code: import("convex/values").VFloat64; message: import("convex/values").VString; }, "optional", "message" | "code">; inputRequests: import("convex/values").VAny; inputResponses: import("convex/values").VAny; /** * Monotonic count of `input_required` rounds requested on this task * (0 before the first). A `tasks/update` submitting responses must * echo the round it is answering, so a stale retry of an earlier * round cannot be mistaken for the answer to a later, re-asked one. * Optional for forward-compat with rows written before this field. */ inputRound: import("convex/values").VFloat64; idempotencyKey: import("convex/values").VString; /** * `"component"`: the built-in scheduler-based executor runs the * registered tool function once and completes/fails the task. * `"host"`: the host started durable execution itself (typically a * `@convex-dev/workflow` run) and finalizes via the trusted APIs. */ executor: import("convex/values").VUnion<"component" | "host", [import("convex/values").VLiteral<"component", "required">, import("convex/values").VLiteral<"host", "required">], "required", never>; /** * Set once the host's `tasks.execute` returned for this row. Only * meaningful for `executor: "host"`: the component executor is * scheduled inside the creating mutation, so it is started by * construction. Without this marker a replayed request could not tell * "the row exists, so execution started" from "the row exists because * a start that then failed to be compensated left it behind", and the * retry whose job was to start the work would skip it. */ startedAt: import("convex/values").VFloat64; /** * Mount scope, from the host's `tasks.scope` option. The task table is * component-wide and `authorize` runs only at creation, so without * this any mount resolving the same subject could poll, cancel, or * answer input rounds for a task created through a mount with a * different policy. Every owner-facing function requires an exact * match (in both directions: a scoped row is invisible to an unscoped * mount and vice versa), and a mismatch is answered exactly like an * unknown id. Unset preserves the pre-scope behaviour, so * single-mount hosts need no migration. */ scope: import("convex/values").VString; /** * Set when the host's MRTR `beforeCall` hook approved this call before * the row was created. The built-in executor requires it for any tool * the registry currently marks `mrtrGated`: a task created while the * tool had no hook must not still execute after one was added (that * confirmation is what the row now promises), while a task the hook * already approved must not be blocked by the same rule. */ mrtrApproved: import("convex/values").VBoolean; createdAt: import("convex/values").VFloat64; updatedAt: import("convex/values").VFloat64; expiresAt: import("convex/values").VFloat64; }, "required", "error" | "taskId" | "toolName" | "args" | "expiresAt" | "ownerSubject" | "scope" | "result" | "caller" | "executor" | "idempotencyKey" | "mrtrApproved" | "toolKind" | "inputRequests" | "inputResponses" | "inputRound" | "createdAt" | "updatedAt" | "status" | "resultIsError" | "resultStructured" | "startedAt" | "error.message" | "error.code" | `args.${string}` | `result.${string}` | "caller.subject" | "caller.claims" | `caller.claims.${string}` | `inputRequests.${string}` | `inputResponses.${string}`>, { by_taskId: ["taskId", "_creationTime"]; by_idempotencyKey: ["idempotencyKey", "_creationTime"]; by_ownerSubject: ["ownerSubject", "_creationTime"]; by_owner_status: ["ownerSubject", "status", "_creationTime"]; by_expiresAt: ["expiresAt", "_creationTime"]; }, {}, {}>; /** * Shared audit log for tool calls, task lifecycle transitions, and * opt-in resource operations. Tool rows capture the tool name/kind, * outcome, duration, and optionally redacted args. Resource rows * capture operation metadata (resource URI, list/read, outcome, * duration) but never resource contents. Task rows capture the task * id, operation, tool name, and owner subject but never task payloads; * a task run by the built-in executor also writes the ordinary tool row * for the call itself. `identitySubject` is supplied by the host after * resolving auth at the HTTP boundary; component code never reads * identity directly. */ audit: import("convex/server").TableDefinition, import("convex/values").VLiteral<"resource", "required">, import("convex/values").VLiteral<"task", "required">], "optional", never>; toolName: import("convex/values").VString; toolKind: import("convex/values").VUnion<"query" | "mutation" | "action" | undefined, [import("convex/values").VLiteral<"query", "required">, import("convex/values").VLiteral<"mutation", "required">, import("convex/values").VLiteral<"action", "required">], "optional", never>; resourceUri: import("convex/values").VString; resourceOperation: import("convex/values").VUnion<"list" | "read" | "templates_list" | undefined, [import("convex/values").VLiteral<"list", "required">, import("convex/values").VLiteral<"read", "required">, import("convex/values").VLiteral<"templates_list", "required">], "optional", never>; taskId: import("convex/values").VString; taskOperation: import("convex/values").VUnion<"create" | "input" | "cancel" | "complete" | "fail" | undefined, [import("convex/values").VLiteral<"create", "required">, import("convex/values").VLiteral<"input", "required">, import("convex/values").VLiteral<"cancel", "required">, import("convex/values").VLiteral<"complete", "required">, import("convex/values").VLiteral<"fail", "required">], "optional", never>; args: import("convex/values").VAny; outcome: import("convex/values").VUnion<"allowed" | "denied" | "error", [import("convex/values").VLiteral<"allowed", "required">, import("convex/values").VLiteral<"denied", "required">, import("convex/values").VLiteral<"error", "required">], "required", never>; identitySubject: import("convex/values").VUnion, import("convex/values").VNull], "required", never>; durationMs: import("convex/values").VFloat64; errorCode: import("convex/values").VFloat64; errorMessage: import("convex/values").VString; }, "required", "entryType" | "outcome" | "resourceUri" | "taskId" | "toolName" | "args" | "durationMs" | "errorCode" | "errorMessage" | "identitySubject" | "resourceOperation" | "toolKind" | `args.${string}` | "taskOperation">, { by_toolName: ["toolName", "_creationTime"]; by_resourceUri: ["resourceUri", "_creationTime"]; by_taskId: ["taskId", "_creationTime"]; by_entryType: ["entryType", "_creationTime"]; by_outcome: ["outcome", "_creationTime"]; }, {}, {}>; }, true>; export default _default; //# sourceMappingURL=schema.d.ts.map