**Source URL:** https://limited.veevavault.dev/medical/vault-dx/dx-reference/plugin-reference/vault-developer

# vault-developer

Build Vault Java SDK entry-point classes, Custom Pages, Vault AI Agents, and integrations built on the Vault API.

## Overview

For Vault developers building custom server-side logic, UI components, AI agents, and integrations built on the Vault API. Use this plugin to generate Vault Java SDK entry-point classes (triggers, actions, job processors, Web APIs, and others), scaffold the three-file Custom Page contract (MDL + PageController + client bundle), author Vault AI Agents, or call and test Vault API endpoints.

### Dependencies

| Plugin / Tool | Why |
| --- | --- |
| [`vault`](/medical/vault-dx/plugins/reference/vault/) | VQL queries and basic API operations used during development |
| Vault CLI (`vault`) | Project structure, managing local files, and moving configuration and code between a Vault and the local workspace go through the CLI when installed. Otherwise the skills call the documented API. The CLI is optional, and Vault compiles Java on deploy either way. |
| [`vault-administrator`](/medical/vault-dx/plugins/reference/vault-administrator/) | MDL syntax, and rules for integrating code with configuration |
| Vault Documentation MCP | Answers API, SDK, VQL, and Help questions from official references. |

### Out of scope

| Topic | Owned by |
| --- | --- |
| Configuration authoring using MDL (objects, fields, lifecycles, workflows, picklists, and other Vault Component Types) | [`vault-administrator`](/medical/vault-dx/plugins/reference/vault-administrator/) |
| VQL query syntax and relationship traversal | [`vault`](/medical/vault-dx/plugins/reference/vault/) |
| User records, group membership, security profiles | Vault Admin UI, or  for API access |

## Skills

| Skill | Invoke with | What it does |
| --- | --- | --- |
|  | `/vault-developer:ai-agents` | Build Vault AI Agents: author Tool Types, Context Types, Agent MDL, and handler classes. |
|  | `/vault-developer:api` | Find Vault API endpoints, shape requests, run calls against a signed-in Vault, and submit approved Vault Loader jobs. |
|  | `/vault-developer:custom-pages` | Generate all three files required by a Vault Custom Page |
|  | `/vault-developer:java-sdk` | Write compliant Vault Java SDK entry-point classes that pass deploy-time validation. |

---

### ai-agents Skill

Build Vault AI Agents: author Tool Types, Context Types, Agent MDL, and handler classes.

For Vault developers who need to build Vault AI Agents. Use this skill when you need to author Tool Types, Context Types, Agent MDL, and the handler classes that implement agent behavior. Without this skill, developers produce Agent MDL with missing required attributes, wire Tool Types incorrectly, and ship handler classes that fail at runtime.

#### Triggers

*   Explicit: "Build a Vault AI agent", "Create an AI tool", "Write an agent action", "Scaffold a tool type handler", "Wire up the Agent MDL", `/vault-developer:ai-agents`.
*   Implicit: User is scaffolding an AI Tool Type or Context Type runtime handler, an `AgentActionResultHandler`, a record action or trigger that runs an agent and writes the result back, an Aitool wrapping a standard tool type, or a new Agent's MDL. User hits `Unknown component [Aitool]` or `[Agent]` on deploy, which means Vault AI is off in that Vault.
*   Not for these tasks: a record trigger, record action, job, or custom API with no agent in it (use ). Writing the VQL text inside a VQL Query tool (use [`query`](/vault-dx/plugins/reference/vault/#query-skill), which shapes the tool and its parameters, not the query). Running an agent action over the API or reading its execution status (use ). MDL as a language, including statement forms, ALTER versus RECREATE, and execution responses (use [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill)).

#### Success criteria

*   Agent components (Aitooltype, Aitool, Agent and their subcomponents) must be authored as files in the workspace and handler classes under `javasdk/`, all deployed through the workspace loop. Direct `RECREATE` statements are not the default.
*   The `java-sdk` criteria apply to handler classes. The bundled handler scaffolds must deploy as written for the common tool shapes, including a tool that takes no parameters, so a routine tool needs no documentation search.
*   An Agent action's `instructions` must not contain curly-brace placeholders. Vault reads a curly-brace token there as a field reference and rejects the Agent when it names no field. Tool output is described in prose.
*   The hand-off must say where users reach the agent, matched to its scope: an object-scoped agent is opened from the AI Chat entry on a record page of that object, which needs an action configured for that object. The skill must not point at an entry point the agent's scope or the Vault's enablement does not provide, and states the permissions an entry point needs from Vault Help rather than from memory.
*   The skill must load `java-sdk` before it writes a handler, because the query rules live there and reading its reference files alone skips them. The `java-sdk` query criteria apply to every VQL string in the handler.
*   A tool with an optional mode must not default to one mode silently, since the user never learns the other modes exist. Either the tool returns every mode in one call and the answer shows them all, or the action asks through the Ask User agent tool, and the action's description says which it does.
*   An Agent action's `instructions` ask for a count or total in the answer only when a tool the action calls returns that figure (a VQL aggregate or a handler that computes it). The skill must not leave the model to sum rows itself.
*   Debug log zips, extracted logs, and trace exports go in a folder beside the workspace, never under the pulled tree. A pull can drop them and a plan can list them.

#### Out of scope

| Topic | Owned by |
| --- | --- |
| MDL as a language: statement forms, ALTER versus RECREATE, execution responses | [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill) |
| Vault Java SDK platform constraints: the JDK allowlist, governor limits, bulk-safe service calls |  |
| Record triggers, record actions, jobs, or custom APIs with no agent in them |  |
| The VQL text inside a VQL Query tool | [`query`](/vault-dx/plugins/reference/vault/#query-skill) |
| Running an agent action over the Vault API and reading its execution status |  |
| Signing in, credentials, and which Vault is targeted | [`login`](/vault-dx/plugins/reference/vault/#login-skill) |
| Deploying the finished files within a Vault | [`config`](/vault-dx/plugins/reference/vault-administrator/#config-skill) and [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill) |
| Custom Page files |  |

---

### api Skill

Find Vault API endpoints, shape requests, run them against a signed-in Vault, and submit approved Vault Loader jobs.

For Vault developers and integration builders working against the Vault API directly. Use this skill to find the right endpoint, shape the request, run it against a signed-in Vault, and interpret the response across objects and records, documents, VQL as an API call, metadata and MDL retrieval, jobs, logs, and users and groups. It also submits approved bulk loads as Vault Loader jobs. Integration builders get the endpoint and request shape for their own code. Admins and developers use it to run the call in the current session.

#### Triggers

*   Explicit: "Does Vault have an endpoint for this", "Call the Vault API", "What's the endpoint for X", "Why did this API call come back wrong", "Poll this job", "Pull the debug log for this user", "Load this file into my Vault", "Load records.csv into Vault", "Bulk load these rows".
*   Implicit: User is building an integration and needs a request shape to run from their own code. User has a response in hand and isn't sure whether it worked. User wants a job's status read. User wants a component read back as MDL through the API. User needs SDK Debug Log, Runtime Log, API Usage Log, or audit trail data. User has a CSV, load-ready or a raw export, and wants it loaded into Vault. User needs records extracted to a file in bulk.
*   Not for these tasks: writing the VQL query text (use [`query`](/vault-dx/plugins/reference/vault/#query-skill), which shapes the API call, not the query). Authoring or executing MDL (use [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill)). Moving files in Vault File Staging (use [`file-staging`](/vault-dx/plugins/reference/vault-administrator/#file-staging-skill)). Taking on source-side work beyond mapping one CSV onto its target object, such as joining extracts or working out a multi-object load order (the user brings that done). A data pull meant to be read on screen (use [`query`](/vault-dx/plugins/reference/vault/#query-skill)). Writing Vault Java SDK source or Custom Pages code (use  or ). Sign-in and credential management (use [`login`](/vault-dx/plugins/reference/vault/#login-skill)).

#### Success criteria

*   The session comes from `vault`'s `login` skill. With the CLI installed, every call must go through `vault api` with the stored session. The skill must not read the session out of the CLI's credential store to build its own request. Without the CLI, each call sets `AUTH` and `VAULT_DNS` from `VAULT_DNS` and `VAULT_ACCESS_TOKEN` the user exported. The skill must never print the credential.
*   An API access token is sent as `Authorization: Bearer <token>`. A session ID is sent without any prefix: `Authorization: <session_id>`.
*   The skill must never ask for a credential in chat. A user who is not signed in is handed to [`login`](/vault-dx/plugins/reference/vault/#login-skill) and the skill stops.
*   For an integration builder, the endpoint, the request shape, and what the response means are the whole deliverable. The skill must not require a live run to answer.
*   Before any write (`POST`, `PUT`, `DELETE`, a job start, or a workflow or user action), the skill must run login's classification check and state the target and its classification in one line, even on a sandbox.
*   Writes run only against a Vault classified as non-production. On `Production` or `UNKNOWN` the skill must not run the call. It shows the exact call and hands it to the user. Reads run against any Vault, including production.
*   Endpoint detail must come from the Vault Documentation MCP rather than memory, with the release named when the answer depends on one.
*   Every call, run or drafted, must carry `Authorization`, `Accept: application/json`, `X-VaultAPI-ClientID: claude-plugins`, and a `Content-Type` matched to the body. When using `vault api`, the CLI adds its own client ID, so the skill does not add `X-VaultAPI-ClientID`. Add `-H "Accept: ..."` only where the endpoint needs a non-default Accept (for example, MDL retrieval).
*   Query text must go out URL-encoded as a form body: `--data-urlencode` with curl, or `-d "q=<url-encoded query>"` with form content type through `vault api`. Never a raw query string. A count is a query with `PAGESIZE 0` read from `responseDetails.total`.
*   MDL retrieval must use the versionless `/api/mdl/components/<Component>.<name>` path.
*   The skill must judge success by `responseStatus` in the body, not the HTTP status, and match failures on `errors[].type`. `INVALID_SESSION_ID` goes back to [`login`](/vault-dx/plugins/reference/vault/#login-skill) rather than being treated as a fault in the call.
*   A call that returns a `job_id` must get a follow-up poll of `GET /api/{version}/services/jobs/{job_id}` no more than every ten seconds.
*   A bulk load must be submitted as a Vault Loader job (`POST /api/{version}/services/loader/load`) built from the user's load-ready file, or the load-ready copy the skill made of a raw export, and the plan the user approved. The skill must not rebuild it as a batch of record POSTs, must not edit the user's file in place, and must not change the plan after it is approved.
*   When the user's CSV is a raw export rather than a load file, the skill maps it before the plan, with nothing written to the Vault: each column to a field on the target object from the configuration workspace or the object's metadata, with columns that have no field named as not loading. A load-ready copy beside the original uses field API names as headers, references as the reference field plus a unique field on the parent, picklist values and lifecycle states as API names, ISO dates, and numbers with no currency sign. A read-only check of every row confirms required fields are filled, unique fields are unique within the file, and each reference is found in the Vault through `vault`'s `query` skill. A row that fails is left out of the copy and named in the plan by its source key and reason. An exact duplicate keeps one copy. The skill must not fill a blank required value or a reference the user did not supply. A judgment-call value map, such as a source status onto a lifecycle state, is a proposal in the plan for the user to confirm, not a separate question.
*   The load file must already be in Vault File Staging, since the Loader job's `file` parameter is a staging path. The skill must not submit a job for a file that is not staged. The upload goes to [`file-staging`](/vault-dx/plugins/reference/vault-administrator/#file-staging-skill) as a step of the approved plan, and the load continues with the staged path.
*   Before each Loader job the skill collects and states a plan: target DNS and classification from `vault`'s `login` skill, object, row count and the rows left out with their reasons, the column mapping and value maps when the skill built the file, operation and key, the migration flags (`recordmigrationmode`, `notriggers`, `documentmigrationmode`) with a reason for each, the load sequence, and the VQL that will verify the load. The skill presents this plan and waits for the user to confirm before submitting. When the target is production, the skill warns explicitly.
*   When the job finishes the skill must read both the success log and the failure log and report row-level failures, even when the job status is `SUCCESS`.
*   Extract support: an extract must be submitted as a Vault Loader extract job (`POST /api/{version}/services/loader/extract`) under the same plan, confirmation, and write rules.
*   Loader job reference (staged file path, `idparam`, migration flags, success and failure log calls) must come from the skill's own reference, with no docs search during the run. An approved job must run in the session that received the go.
*   Verification: the plan's VQL run through `vault`'s `query` skill as a count compared with the planned row count. The skill's own report is the logs.
*   The VQL text that counts the loaded rows is written by the `query` skill, not this skill.

#### Out of scope

| Topic | Owned by |
| --- | --- |
| The VQL query text itself | [`query`](/vault-dx/plugins/reference/vault/#query-skill) |
| Authoring, editing, or executing an MDL script | [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill) |
| Moving files through Vault File Staging | [`file-staging`](/vault-dx/plugins/reference/vault-administrator/#file-staging-skill) |
| Vault Java SDK source, Custom Pages client code |  /  |
| Signing in, credentials, production/sandbox classification, session errors | [`login`](/vault-dx/plugins/reference/vault/#login-skill) |
| Packaging components for another Vault | Vault UI (import package) |
| The VQL text that counts the loaded rows | [`query`](/vault-dx/plugins/reference/vault/#query-skill) |

---

### custom-pages Skill

Generate all three files required by a Vault Custom Page: MDL Page component, Java PageController, and client bundle, wired together and ready to deploy.

For Vault developers scaffolding [Vault Custom Pages](/medical/custom-pages/). Use this skill when you need the three-file contract a Custom Page requires (MDL Page component, Java PageController, and client bundle) generated and wired together correctly.

#### Triggers

*   Explicit: "Create a custom page", "Scaffold a vault page", "Write a page controller", "Build a vault UI page", "Help me with definePage".
*   Implicit: User needs a UI component in Vault. User is adding a PageController with data fetching. User needs a client bundle that calls `definePage()`. User is building or modifying the distribution manifest.
*   Not for these tasks: Vault Java SDK record triggers or actions (use ). AI Tool Types, Context Types, or `AgentActionResultHandler` classes (use ). Packaging or deploying a Custom Page to another Vault (use the Vault UI import package flow).

#### Success criteria

*   All three files are generated: MDL Page component, Java PageController, and client bundle.
*   MDL uses `RECREATE Page` with all required attributes: `label`, `active`, `client_distribution`, `page_client_code`, `page_controller`, `url_path_name`.
*   The three wiring references match exactly: `client_distribution` ↔ manifest root name. `page_client_code` ↔ `pages[].name`. `page_controller` ↔ fully qualified class name.
*   `PageController` implements `com.veeva.vault.sdk.api.page.PageController` with `@PageControllerInfo` and `@ExecuteAs(ExecuteAsUser.REQUEST_OWNER)` annotations.
*   Client entry point calls `definePage()` and mounts only to `element` (shadow root host), never to `document`.
*   Distribution manifest root name and all page names end `__c`.
*   `page_controller` is included even for static or client-only pages when `client_distribution` is set.
*   The skill asks for the page label if missing and applies stated safe defaults for all optional inputs.
*   Shadow DOM styling uses `<style>` injected into the shadow tree, never into `document.head`.
*   `vault config push` deploys the distribution in a CLI workspace. The skill must not present a VPK import as the only way to deploy.
*   `custom_pages/<name>/` must hold only the built output and the distribution manifest. Client source and its dependencies live outside the workspace.
*   The distribution must hold minified output, with source maps included as separate map files. The skill watches the distribution size against the documented 50 MB limit. A controller that feeds a summary returns aggregates (counts and sums by the dimensions the page shows), not one row per record.
*   When no design system is named, state the page's own styling defaults: system fonts, neutral surfaces, one accent, direct chart labels, status never by color alone.
*   The java-sdk criteria apply to every VQL string in the PageController.
*   A distribution with several pages gets one built entry point per page, and `distribution-manifest.json` points each page at its own entry point.
*   The skill must load `vault`'s `query` skill for every `SELECT` in the PageController, however simple, and run each one read-only before hand-off. With no reachable Vault, it says the query is unverified.
*   The hand-off must ask how users reach the page, offering the URL only, a Tab or Subtab, or a Pagelink on an object, unless the request already says, and the skill must not add a Tab, Subtab, or Pagelink the developer did not choose. The skill must say that users need View on the Page in a permission set, and that a Tab, Subtab, or Pagelink deploys in a second push after the Page has landed, because in the same push Vault refuses the Tab with `value [Page.<name>] does not resolve to a valid [component]`.

#### Out of scope

| Topic | Owned by |
| --- | --- |
| Vault Java SDK record triggers, record actions, document actions |  |
| AI Tool Types, Context Types, `AgentActionResultHandler` |  |
| Packaging or moving a Custom Page to another Vault | Vault UI (import package) |
| VQL query syntax and relationship traversal | [`query`](/vault-dx/plugins/reference/vault/#query-skill) |
| MDL syntax beyond Page component attributes | [`mdl`](/vault-dx/plugins/reference/vault-administrator/#mdl-skill) |
| Vault UI SDK (`ControlRegistry`, `PageControllerContext`, `@vault/uisdk`) | Vault Documentation MCP |
| Vault API endpoints, auth, rate limits | Vault Documentation MCP |

---

### java-sdk Skill

Write Vault Java SDK entry-point classes that comply with Vault's platform restrictions and pass deploy-time validation.

For Vault developers writing Vault Java SDK entry-point classes. Use this skill to generate record triggers, record actions, job processors, custom APIs, and other SDK entry points that comply with Vault's platform restrictions and pass deploy-time validation.

#### Triggers

*   Explicit: "Write a record trigger", "Create a vault trigger", "Write a job processor", "Create a custom API endpoint", "Help me with the Vault Java SDK".
*   Implicit: User needs logic that fires automatically on record insert, update, or delete. User needs a scheduled or background bulk operation. User needs a custom REST endpoint for external system integration. User needs a record or document action invoked on demand.
*   Negative: Do not trigger for Custom Page `PageController`s. Hand off to . Do not trigger for AI Tool Types, Context Types, or `AgentActionResultHandler` classes. Hand off to . Do not trigger for packaging or moving Java code to another Vault.

#### Success criteria

*   The correct entry-point interface is identified before any code is written, with explicit disambiguation when the behavior description is ambiguous.
*   All collections use `VaultCollections` factory methods, never raw JDK constructors (`new ArrayList<>()` and so on).
*   All logging uses `LogService` with `{}` message-template overload, never `System.out`.
*   Only `RollbackException` is thrown or caught.
*   No forbidden constructs: No reflection, no threading primitives, no file I/O, no non-final static fields, no method references.
*   Service calls (`QueryService`, `RecordService`, and so on) are never made inside per-record loops, always batched.
*   No deprecated SDK methods are used. If the Vault Documentation MCP identifies a method as deprecated, use the documented replacement instead.
*   The generated class lives under the `com.veeva.vault.custom` package hierarchy.
*   All missing required inputs are gathered in a single message with a skip-to-defaults escape offered.
*   The skill names the limit of 10 triggers per object and event, and when the object already carries several, proposes adding the logic to an existing trigger before writing another class.
*   In a CLI workspace, `vault config push` deploys the class with the components. The skill must not present a VPK import as the only way to deploy code.
*   The skill must not build a VPK or deploy. It stops at source on disk and hands deployment to `vault-administrator`'s `config` and `mdl` skills for a workspace push, or to Import Package and Deploy Package for a package.
*   Vault compiles the class on deploy. No local SDK jar or build is needed.
*   Outside a workspace: the deploy route must be a VPK carrying `javasdk/`, through the Import Package and Deploy Package calls with the signed-in session. The skill must not route the deploy through a build-tool plugin that keeps its own credential file.
*   Every VQL string in the class must follow `vault`'s `query` skill criteria. A list of literal values is matched with `CONTAINS`. `IN` takes only a subquery.
*   Before the class is deployed, the skill must run each VQL string read-only through `vault query` with real values in place of any token, and fix any that fail. Without the CLI, hand the strings to the developer to run.
*   Every query must carry an `onError` that reports `getMessage()`. The skill must not call a method on an SDK enum (deploy validation rejects the class).
*   When a class fails with no error shown: compare service-call counts in the debug log against expected calls before blaming the platform.
*   Debug log zips, extracted logs, and trace exports go in a folder beside the workspace, never under the pulled tree.

#### Out of scope

| Topic | Owned by |
| --- | --- |
| Custom Page three-file shape (MDL + PageController + client bundle) |  |
| AI Tool Types, Context Types, `AgentActionResultHandler` |  |
| Moving Java code to another Vault | Vault UI (import package) |
| Loader job migration flag combinations (Record Migration Mode, No Triggers) |  |