On this pageWhat it is
Let the coding agent you already use — Claude Code, Codex or Cursor — work with your battery passports directly. The Collecta DPP MCP server gives the agent tools to read models, see what is missing, look up the EU data points and inspect passports; AGENTS.md gives it the rules to write an integration that is correct the first time. API access is included on every plan.
What it is
The Model Context Protocol (MCP) is the open standard coding agents use to call external tools. The Collecta DPP MCP server runs on your machine next to the agent, holds your API key, and turns the REST API into tools with descriptions an agent can act on: which call to make first, what a field is called, why a publish was refused and what to do about it.
- Read-only by default. Twelve read tools are always there; the six write tools are not even registered unless you turn them on.
- Structured answers. Every result is JSON with a
request_infoblock —request_id, key mode, whether it was a dry run, the idempotency key used. Failures come back as tool errors withcode,message,request_idand a hint saying what to do next. - Two resources and two prompts.
dpp://field-catalogue(the 71 EU data points) anddpp://openapi(the OpenAPI document); the promptsfill_model_gapsandintegration_review.
Set it up
Create a test key (dpp_test_…) in the app under Organisation → API keys. With a test key every write is a dry run — validated against your real data, never stored — so the agent can explore safely. Then register the server with your tool: Claude Code with claude mcp add, Codex in ~/.codex/config.toml, Cursor in .cursor/mcp.json in the project (or ~/.cursor/mcp.json for every project).
# Adds the server for this project. Use --scope user for every project.claude mcp add collecta-dpp \--env DPP_API_KEY=dpp_test_… \-- npx -y @collecta/dpp-mcpclaude mcp list # collecta-dpp: … ✔ Connected| Variable | Required | Meaning |
|---|---|---|
DPP_API_KEY | Yes | dpp_test_… to start, dpp_live_… when you trust the workflow. |
DPP_BASE_URL | No | Defaults to https://dppapi-production.up.railway.app/v1. |
DPP_ALLOW_WRITES | No | true registers the write tools. Anything else, or unset: read-only. |
Share it with your team (Claude Code)
Commit a .mcp.json at the root of the repository and every teammate gets the server. Keep the key out of the file: Claude Code expands ${DPP_API_KEY} from each person’s environment.
{"mcpServers": {"collecta-dpp": {"command": "npx","args": ["-y", "@collecta/dpp-mcp"],"env": { "DPP_API_KEY": "${DPP_API_KEY}" }}}}Enable the write tools
Add DPP_ALLOW_WRITES=true. Keep the test key until the agent’s work looks right: the server then validates every write for real and stores nothing.
claude mcp remove collecta-dppclaude mcp add collecta-dpp \--env DPP_API_KEY=dpp_test_… \--env DPP_ALLOW_WRITES=true \-- npx -y @collecta/dpp-mcpTool catalogue
Read tools — always available
| Tool | What it does |
|---|---|
whoami | The key’s organisation, plan, scopes, mode (live or test), usage and rate limit, and whether write tools are enabled. |
list_models | Models with completeness and counts; filter by category, complete and updated_since. |
get_model | One model with every stored field, conformity record, documents and declarations. |
model_completeness | What is still missing for the model’s category, grouped by Annex XIII point, with how to fill each gap. |
validate_model_draft | Validate a model before creating it: missing data and unknownFields (usually typos). Stores nothing. |
list_passports | Passports with identifier, serial, status and links; filter by model, serial, identifier, status, published, updated_since. |
get_passport | One passport: battery, model, every field, recent events and lineage. |
passport_events | A passport’s dynamic-data history (state of health, cycles, repairs…), by type and time. |
list_documents | Model documents with type, Annex XIII point and download link. |
search_field_catalogue | Search the 71 EU data points by text, category and obligation; returns the exact API field name and endpoint. |
audit_trail | Who changed what and when; filter by entity, record and time. |
list_webhooks | Webhook endpoints with subscriptions, last delivery and failure count. Never secrets. |
Write tools — only with DPP_ALLOW_WRITES=true
| Tool | What it does |
|---|---|
create_model | Create a battery model. |
update_model_fields | Merge data points into a model; keys you omit are kept. |
create_batteries | Create up to 1000 batteries (serials, or a count with a prefix), each with its own passport. |
publish_passports | Publish up to 1000 passports with per-row results; a dry run lists what blocks each one. |
record_passport_event | Append a dynamic-data event, such as a state-of-health reading. Append-only. |
change_passport_status | Repurpose, re-use, remanufacture (forks a linked passport) or mark as waste. |
Every write tool takes dry_run, and is safe to retry: the idempotency key is derived from the tool and its input, so a repeated call within 24 hours returns the first answer instead of creating a second battery. Pass idempotency_key to repeat an identical write on purpose.
Example prompts
- “Which DPP organisation is this key for, which plan is it on, and is it a test key?”
- “List our EV models that are not complete yet, and for the first one tell me what is still missing by Annex XIII point.”
- “Which data points are required for industrial batteries, and what are their API field names?”
- “Here is the datasheet for our NV-EV-90 pack. Use the fill_model_gaps prompt and propose values for every missing field — don’t write anything yet.”
- “Validate this LMT model from our spec sheet before we create it, and fix any unknown field names.”
- “Which passports changed since yesterday? Show the state-of-health readings of the newest one.”
- “Dry-run publishing every draft passport of model NV-EV-90 and tell me what blocks each one.”
- “Review src/dpp-sync.ts with the integration_review prompt, focusing on retries and webhook verification.”
Safety model
- 1
Read-only unless you opt in
Without
DPP_ALLOW_WRITES=truethe write tools do not exist, so no prompt can make the agent call them. - 2
Test keys first
With a
dpp_test_…key the API itself turns every write into a dry run. Even with writes enabled, nothing is stored. Switch to a live key only when you trust the workflow. - 3
Dry runs on live keys
Every write takes
dry_run: true, and the tool descriptions tell the agent to use it first. A dry-run publish lists what blocks each passport. - 4
Nothing is ever deleted
The API has no DELETE: passports must stay available for ten years.
change_passport_statusis marked destructive so clients ask before running it, and recycling is not offered at all. - 5
Safe retries, least privilege
Derived idempotency keys mean a retried call never acts twice. A key with only the
readscope refuses every write, whatever the server allows.
AGENTS.md for your repository
Coding agents read an AGENTS.md at the root of a repository before they write code. Ours is the integration rulebook for this API, in one page: base URL and keys, test keys first, an Idempotency-Key on every write, validate before create, completeness before publish, never DELETE, cursor pagination and updated_since for sync, webhook signature verification, error handling with request_id, and rate limits. Drop it into the repository that talks to the API — with or without the MCP server.
AGENTS.md
Plain Markdown. Save it at the root of your repository, next to your README, or merge it into an AGENTS.md or CLAUDE.md you already have.
# AGENTS.md — Collecta DPP API integration rulesDrop this file into any repository that integrates with the Collecta Digital Product Passport (DPP) API. Coding agents (Claude Code, Codex, Cursor and others) read it before they write code. The rules are not style preferences: breaking one creates duplicate batteries, lost updates, forged webhooks or passports that cannot be published.Source of truth: https://www.collectadpp.com/developers · OpenAPI 3.1: https://dppapi-production.up.railway.app/v1/openapi.json · LLM index: https://www.collectadpp.com/llms.txt (full corpus: /llms-full.txt)## The domain in one paragraphEU battery passports under Regulation (EU) 2023/1542. A **model** holds the data every battery of one design shares. Each **physical battery** has exactly one **passport** (Art. 77(1)) with a unique identifier that never changes and must resolve for ten years. Data point names come from the field catalogue (`GET /v1/field-catalog`, 71 EU data points with the obligation per category: `EV`, `LMT`, `INDUSTRIAL`). Never invent a field name: look it up.## Base URL and authentication- Base URL: `https://dppapi-production.up.railway.app/v1`. Read it from configuration (e.g. `DPP_BASE_URL`), never hard-code it in business logic.- Every request: `Authorization: Bearer <key>`. Keys are created in the app under Organisation → API keys and shown once.- Keys come from the environment (`DPP_API_KEY`) or a secret manager. Never commit a key, log it, or put it in client-side code.- Scopes: `read` and `write`. Give each system the smallest scope it needs.- API access is included on every plan. A `402 plan_upgrade_required` means the plan does not include that operation (e.g. publishing on Free) — a plan problem, not a bug.## Always start with a test key- `dpp_test_…` keys run **every write as a dry run**: validated against your real data (auth, scope, plan, schema, ownership, publish gate) and nothing is stored, sent or counted. Develop and run CI with a test key.- Switch to `dpp_live_…` only when the integration is reviewed. The code must not change — only the key.- With a live key, send `X-DPP-Dry-Run: true` (SDK: `{ dryRun: true }`) to validate a single write first.- Check the mode on startup with `GET /v1/me` (also returns plan, usage and rate limit). The `X-DPP-Mode` response header repeats it.llms.txt and Copy page
- /llms.txt lists every docs page with a one-line summary; /llms-full.txt is the full corpus in one file. Point an agent at either when it needs the docs.
- Copy page in the header of every docs page copies it as clean Markdown, code samples included in the language you picked — ready to paste into an agent’s context.
- The OpenAPI 3.1 document is public and needs no key; the MCP server also serves it as
dpp://openapi.