Skip to main content

Command Palette

Search for a command to run...

BDK

Artifacts

Artifacts are durable outputs such as reviewed pull requests, reports, or decision records. An artifact kind defines the data it accepts, and the artifacts API tags or updates records by key. Records persist across sessions and can be listed, streamed, or downloaded.

Artifact kinds

Author bot/artifacts.ts with defineArtifacts from @cursor/bdk/artifacts:

import { z } from "zod";import { defineArtifacts } from "@cursor/bdk/artifacts";export default defineArtifacts({  kinds: {    "reviewed-pr": {      description: "A pull request this agent reviewed.",      schema: z.object({ url: z.string(), verdict: z.string() }),    },    report: { description: "A generated report." },  },  agentTool: true,});
OptionContract
kindsMap of accepted kind names to a non-empty description and optional Zod schema
agentToolExpose tag_artifact to the model; requires at least one declared kind
maxPositive retention cap, default 1000. Local and self-hosted servers evict the oldest-updated record; hosted deployments don't evict.

With declared kinds, tag rejects any other kind. With no registry, it accepts free-form kind names and defaults an omitted kind to "artifact". A kind's schema validates data, and the parsed value is stored, including schema defaults and coercions.

Tag artifacts from host code

Tools, hooks, channel handlers, channel onStart, schedules, and reminders receive an ArtifactsApi with tag and list.

await ctx.artifacts.tag({  kind: "reviewed-pr",  key: prUrl,  title: `Reviewed ${prUrl}`,  data: { url: prUrl, verdict: "approve" },});
Tag fieldContract
dataRequired JSON data, validated when the kind has a schema
kindDeclared or free-form kind
keyAgent-wide upsert key; the same key updates one record across kinds
titleOptional display title
contentsString or bytes served by the content route
contentTypeMIME type for contents
sessionId, turnIdAttribute the artifact to a session or turn
source"host" or "model"; defaults to "host"

Tool, hook, result, and channel-event contexts are session-bound, so they fill sessionId and the current turnId. Channel routes, onStart, schedules, and reminders receive an unbound facade; pass sessionId to attribute an artifact.

Re-tagging a key without contents keeps its file or blob when the sessionId stays the same. Rebinding the key to another session without new contents removes the previous payload. tag returns the stored ArtifactRecord.

Record fieldContract
idStable ID derived from key, or a generated ID when no key is set
kind, dataValidated kind and JSON payload
key, titleOptional upsert key and display title
contentOptional { size, contentType? } metadata
sessionId, turnIdOptional session attribution
source"host" or "model"
createdAt, updatedAtISO-8601 timestamps

Expose tag_artifact to the model

With agentTool: true, the tag_artifact server tool materializes from the kinds registry. Its input accepts the declared kinds and validates their data with the same schemas as host-side tagging. The kind descriptions tell the model which output each one represents.

An authored tool named tag_artifact takes precedence over the generated tool.

List artifacts

list({ kind?, sessionId? }) returns matching records newest-updated first. HTTP callers can list records and download content through the artifact routes.

Stream artifact tags

Tagging an artifact with a sessionId emits artifact.tagged on that session. Its event data contains id, kind, key, title, data, and source. See Stream events for the event envelope.