tracepass-mcp-server
You can use this MCP server to manage TracePass products and EU Digital Product Passports, their data, parties, supply-chain events, and regulatory templates through AI assistants.
Manage product catalogue: list, get, create, batch-create, update, archive products.
Manage Digital Product Passports: create (billable), list/get by id or serial, run compliance and registry-readiness checks, manage condition flags, capture/list battery measurements, suspend (reversible), archive (irreversible), get QR/Data Matrix codes, list/get snapshots.
Update passport category-specific data fields by id or serial.
Set or remove economic-operator parties such as manufacturer, importer, etc., with EN 18219 identifier schemes.
Work with GS1 EPCIS 2.0 events: export, capture, poll capture jobs, query.
Browse DPP templates: list 13 categories and get regulatory field schemas with legal citations.
Read MCP resources for products, passports, EPCIS, compliance, registry-readiness, snapshots, templates.
Run reusable prompts for passport audit, product onboarding, requirements explanation, compliance gap checks, EPCIS review.
Use hosted OAuth (recommended) or API key auth; local npx is API-key only.
For suppliers: answer TracePass data requests via a separate tokenized endpoint (get request, validate/submit answers, upload evidence, check review status).
TracePass MCP Server
A Model Context Protocol server for TracePass — the EU Digital Product Passport platform. It lets AI assistants (Claude, Cursor, IDE agents) manage products, Digital Product Passports, economic-operator parties, and GS1 EPCIS 2.0 supply-chain events.
It speaks the full MCP protocol — tools, resources, resource templates, and prompts.
Two ways to use it
The same server core ships two ways:
Hosted — point your MCP client at
https://ai.tracepass.eu/mcp. Nothing to install; always current.Local (npm) — run
tracepass-mcp-servervianpx. The MCP client launches it as a subprocess and speaks MCP over stdio.
Related MCP server: fallpharm-mcp
Authentication
The server accepts either of TracePass's two v1 auth methods on the
same Authorization: Bearer … header — it forwards whatever you send to
the API, which decides. Pick the one that fits how you're connecting:
API key | OAuth 2.0 | |
Best for | A single user, scripts, server-to-server | AI assistants / apps acting on a user's behalf |
What you send | A static | A scoped access token obtained via the OAuth flow |
Setup | Mint at Developer → API Keys | The user clicks Connect and approves scopes |
Scope | All-or-nothing (the whole workspace) | Exactly the scopes the user granted; revocable |
Works with | Hosted and local (npx) | Hosted endpoint only (needs a browser consent step) |
Which should an AI assistant use? If your MCP client supports OAuth (Claude.ai, ChatGPT, and others), prefer OAuth — the user authorizes the connection once on a TracePass consent screen, you never handle a secret, and access is least-privilege and revocable. If your client only takes a header/token, use an API key.
OAuth 2.0 (recommended for hosted clients)
No config beyond pointing your client at the hosted endpoint — discovery
is automatic. On the first unauthenticated request the server returns a
401 whose WWW-Authenticate header carries a resource_metadata URL
(RFC 9728) pointing at /.well-known/oauth-protected-resource, which
names the TracePass authorization server. The client runs the standard
authorization-code flow with PKCE (/api/oauth/authorize →
/api/oauth/token), the user approves scopes, and the client stores +
refreshes the token. If you distribute your own client, register an app
under Developer → OAuth Apps to get a client_id; many hosted
clients self-register via Dynamic Client Registration automatically.
Request only the scopes you need, e.g. passports:read passports:write offline_access. Users manage connected apps (and revoke) under
Developer → OAuth Apps → Connected Apps.
API key
Mint a tp_… key under Developer → API Keys and send it as a Bearer
token.
Hosted:
{
"mcpServers": {
"tracepass": {
"url": "https://ai.tracepass.eu/mcp",
"headers": { "Authorization": "Bearer tp_YOUR_KEY" }
}
}
}Local (npx / stdio) — the local subprocess can't do an interactive
OAuth consent step, so it's API-key only, via the TRACEPASS_API_KEY env:
{
"mcpServers": {
"tracepass": {
"command": "npx",
"args": ["-y", "tracepass-mcp-server"],
"env": {
"TRACEPASS_API_KEY": "tp_YOUR_KEY"
}
}
}
}Optional env var: TRACEPASS_BASE_URL (defaults to
https://app.tracepass.eu) — point the tools at a different
TracePass deployment.
Tools
The TracePass v1 API operations are grouped into 7 tools. Each takes an action enum plus action-specific arguments. The tools are:
tracepass_products- manage the product catalogue (list, get, create, create_batch, update, archive products).tracepass_passports- manage Digital Product Passports (list, get, compliance check, registry-readiness check, get/set condition flags, create, suspend, archive, get QR, list snapshots, get snapshot), by id or by serial. Passports are identified via GS1 or four additional EN 18219 schemes (iso15459, iec61406, did, doi); battery passports accept only gs1 and iso15459 (Art. 77(3)). Condition flags are approved yes/no facts (e.g. battery:hasBMS,rechargeable,externalStorageOnly,isStationaryBess) that gate conditional legal duties — setting an approved flag may make additional fields required and block publishing if those fields are empty.tracepass_passport_fields- update a passport's category-specific data fields, by id or by serial.tracepass_passport_parties- set or remove a passport's economic-operator parties (manufacturer, importer, etc.).tracepass_epcis- export, capture, and query a passport's GS1 EPCIS 2.0 supply-chain events.tracepass_templates- list and get the DPP category field schemas, each field traced to the EU instrument that mandates it.tracepass_scope- check whether a product type needs a Digital Product Passport (check), read the company's catalogue-wide scope report (catalogue_report), and trigger or poll a catalogue refresh run (catalogue_run, catalogue_run_status).
Each tool's full action set:
Tool | Actions |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The *_by_serial actions address a passport by the customer's own serial
number instead of its TracePass id. A serial is unique only within a GTIN, so
if the same serial exists under two GTINs in your account a serial-only call
returns 409 ambiguous_serial — pass the optional gtin arg to disambiguate
(or use the by-id action). The same gtin disambiguator applies to every
*_by_serial action.
The tracepass_passports compliance action returns a three-tier
compliance verdict (compliant / compliant_with_warnings /
incomplete) with regulation-cited findings — missing required fields,
missing economic-operator parties, format issues, and per-category
conditional rules. Read-only; use it to gap-check a passport, fix the
cited gaps, then re-check.
A compliant verdict means this passport satisfies the rules encoded here,
not this product may be placed on the market. The field specifications are
hand-authored from the regulations, not an official EU artefact, and delegated
acts are still landing. It is not legal advice.
Second-life batteries
A repurposed, remanufactured or reused battery needs a new passport
linked to the original one(s) (Battery Regulation Art. 77(7)). Pass a
lineage block to tracepass_passports create:
{ "predecessors": [ { "internalPassportId": "<your original passport id>", "trigger": "repurposing" } ] }A predecessor is named by internalPassportId (one of your own passports)
or by its resolvable identifier. trigger is one of
preparation_for_reuse, preparation_for_repurposing, repurposing or
remanufacturing. The platform derives batteryStatus from the
triggers, stores the block immutably, and links your own originals back
to the new passport (successors). A battery placed on the market before
18 Feb 2027 has no original passport: send an empty list with
noPredecessorReason. Rule violations return 422 with the rule code.
Battery measurements (living record)
capture_measurements pushes over-life data from your own equipment into a
published battery passport: state of health, fades, cycle counts, dynamic
values, state of charge, negative events, temperature history (Battery
Regulation Annex XIII point 4). Every measurement is kept; the newest per
field becomes the passport's current value and sets dynamicDataAsOf.
list_measurements and latest_measurements read them back.
They are metered against the plan's monthly measurement allowance, not the daily write budget. Paid plans keep counting past the allowance at no charge; the Free plan stops at its allowance. Reading a passport is never metered.
A note on writes
Some actions cost money or are irreversible — the server's tool descriptions tell the model so:
tracepass_passportscreateconsumes billable DPP slots. Over-quota creation incurs a per-passport overage charge; the tool surfaces a 402-style message and only proceeds withargs.confirmOverage: trueafter the user agrees.tracepass_passportsarchiveis irreversible — the public QR permanently 404s. Usesuspend(reversible) when a change might be undone.tracepass_epciscapture/queryrequire the paid EPCIS add-on;exportis included on Starter plans and up.
Resources
Read-only entity data you can attach as conversation context:
tracepass://products— the product cataloguetracepass://product/{id}— one producttracepass://passport/{id}— one passport, full field detailtracepass://passport/{id}/epcis— a passport's EPCIS 2.0 eventstracepass://passport/{id}/compliance— a passport's compliance verdicttracepass://passport/{id}/registry-readiness— a mechanical pre-submission check modelled on the EU DPP Registry's formal gate: mandatory-field presence, formatting, a resolvable public link, item-level granularity (no commodity-code check: a battery passport's registration identifier is not entered in the customs declaration). Not the substantive compliance verdict, and not a prediction of the real registry's response — its registration API has no published spec. Battery only.tracepass://passport/{id}/snapshots— the snapshot history of a passport (newest first): a snapshot on publish and after every change to a non-draft passport; each entry carries version, reason (e.g. published, field_edit, status_change, baseline), actor, snapshotAt, contentHash, hashValid (re-verified on read), restorable flag, and field count.tracepass://templates— all 13 DPP category field schemastracepass://template/{category}— one category's full field schema
Prompts
Reusable DPP workflows the client surfaces as slash-commands:
audit_passport— review a passport for completeness and compliance readinessonboard_product— create a product and its first passportexplain_dpp_requirements— explain what a category's compliant DPP must contain, and the regulation behind each fieldcompliance_gap_check— produce a prioritised, regulation-cited list of what's blocking a passport's compliant publicationreview_epcis_events— summarise a passport's supply-chain trail
For suppliers: answering a data request
A second, separate endpoint serves suppliers who receive a TracePass data request. It is not part of the tools above. The request email carries a personal address:
https://ai.tracepass.eu/supplier/mcp/<token>Add it to an AI assistant as a custom connector. For clients that can set
headers, https://ai.tracepass.eu/supplier/mcp with
Authorization: Bearer <token> works too. The token authorises that one
request only; there is no account and no OAuth. The assistant can then:
Tool | What it does |
| Start here: who is asking, for which product, and every field asked for, each with its meaning, unit, format and legal source; plus answers already sent and the review outcome |
| A dry run: what would be stored, which keys were not requested, and what does not fit. Writes nothing |
| The best way to attach a datasheet or certificate when the assistant can run shell commands: returns a |
| Attach a very small file (a few kilobytes) inline as base64; prefer |
| Send answers with evidence per value to the requester's human review; can be repeated (answers merge) until reviewed |
| Whether the requester has reviewed them, the outcome, accepted fields, and when the link expires |
Answers go to the requester's human review; they never publish anything on their own.
Development
npm install
npm run build # tsc -> dist/
npm run typecheck
npm test # vitest
npm run lint
npm start # run the hosted HTTP service locally (:8080)
npm run start:stdio # run the stdio server locallyThe hosted service is a plain Node HTTP server (dist/http.js),
stateless — each request carries its own API key and builds a fresh
MCP session. It is containerised via the Dockerfile; the hosted endpoint
runs in the EU.
Listed on Glama
This server is published in the official MCP Registry
as eu.tracepass/tracepass and listed on Glama:
License
MIT
Available Tools
6 toolstracepass_epcisTracePass EPCIS 2.0AInspect
GS1 EPCIS 2.0 supply-chain events. export is included on Starter plans and up; capture, capture_job, and query require the paid EPCIS add-on (those actions return a 403-style message without it).
Actions (pass via action, with args):
export — args: { id }. Export a passport's events as an EPCIS 2.0 JSON-LD document. Read-only.
export_by_serial — args: { serial, gtin? }. Same as export, addressed by your own serial. A serial is unique only WITHIN a GTIN — if it isn't unique in your account the call returns 409 ambiguous_serial; pass
gtin(or use export by id). Read-only.capture — args: { events }.
eventsis an EPCISDocument, a single event, or an array of events (JSON-LD). Returns a 202 with a captureJobId.capture_job — args: { jobId }. Poll an async capture job. Read-only.
query — args: { params? }.
paramsis a key/value map of standard EPCIS query parameters (EQ_bizStep, GE_eventTime, MATCH_epc, …). Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; required fields depend on `action`. | |
| action | Yes | EPCIS 2.0: export a passport's events (export | export_by_serial), capture new events, poll a capture job, or query events. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only idempotentHint: false in annotations, the description carries the full behavioral burden and does so extensively. It marks four actions as read-only, reveals that capture returns a 202 with a captureJobId and is asynchronous, and discloses specific error conditions like 409 ambiguous_serial and 403-style messages. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a concise lead sentence, a critical plan-requirement note, and a clean action-by-action bullet list. Every sentence adds value, and the structure makes the multi-action tool easy to scan and understand.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (five actions, nested args, async behavior, plan restrictions), the description is complete. It covers all actions, their required args, error conditions, and asynchronous behavior. Return values are not detailed, but an output schema exists, so that omission is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already has 100% description coverage, the description adds substantial meaning beyond it. It maps each parameter to its action, clarifies that a serial is unique only within a GTIN, explains that events can be an EPCISDocument or an array, and gives examples of EPCIS query parameters. This goes well beyond the schema's field-level descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'GS1 EPCIS 2.0 supply-chain events.' It then enumerates each specific action (export, export_by_serial, capture, capture_job, query) with a precise verb and resource. This distinguishes it from sibling tools like tracepass_passports and tracepass_products.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage context: it notes which actions are included on Starter plans vs. require the paid add-on, and explains when to use export_by_serial versus export with a GTIN. It does not explicitly name alternative sibling tools, but the action-level guidance is clear enough for correct selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracepass_passport_fieldsTracePass passport fieldsAIdempotentInspect
Update field values on a Digital Product Passport. Every change is recorded in the passport's audit trail with the credential that made it (API key or connected app) and this MCP channel.
source (optional) says where the value came from. Omit it, or pass "manual", when the user gave you the value or it comes from their own records: it is written with the user's rights (approved for an API key or an admin; sent to review for a connected app acting for an editor). Pass "ai_suggested" when you found or inferred the value yourself (web research, reading a document): it lands in the dashboard review queue for a human to approve, and it is refused on fields only the economic operator may state or that must be measured (e.g. battery stateOfHealth).
Actions (pass via action, with args):
update — args: { id, fieldKey, value, source? }.
valuetype matches the field's dataType (string, number, boolean, array, object).update_by_serial — args: { serial, fieldKey, value, gtin?, source? }. Same as update, addressed by your own serial. A serial is unique only WITHIN a GTIN — if it isn't unique in your account the call returns 409 ambiguous_serial; pass
gtin(or use update by id) to resolve exactly.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; required fields depend on `action`. | |
| action | Yes | Update one passport field, addressed by passport id (update) or by your serial (update_by_serial). |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only idempotentHint in the annotations, the description carries the behavioral burden well: it discloses the audit-trail recording (credential plus MCP channel), the human review queue behavior of ai_suggested values, refusal on operator-only or measured fields such as battery stateOfHealth, and the 409 ambiguous_serial failure mode. This is rich context beyond the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but front-loaded with the core purpose, then organized into `source` semantics and an action list with per-action args. Nearly every sentence earns its place, though the action bullets partially restate parameter details already visible in the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need no explanation, and the description fully covers the mutation semantics, error path, and review behavior for a nested-argument tool with minimal annotations. Nothing an agent needs to invoke it correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: it explains the rights implications of each `source` value (approved for API key/admin, sent to review for connected apps), how `value` must match the field's dataType, and how `gtin` disambiguates a non-unique serial. That goes meaningfully beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening sentence states a specific verb and resource: 'Update field values on a Digital Product Passport,' which is more precise than the title alone. It is clear what the tool mutates, but it never contrasts itself with the related tracepass_passports sibling, so an agent must infer the boundary between editing fields and managing the passport itself.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use rules for `source`: omit it or pass 'manual' when the user supplied the value or it comes from their own records, and pass 'ai_suggested' when the agent inferred it. It also explains when to prefer update_by_serial over update by id, and the 409 ambiguous_serial fallback condition, leaving little to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracepass_passport_partiesTracePass passport partiesAIdempotentInspect
Manage the economic-operator parties on a passport — manufacturer, importer, authorisedRepresentative, distributor, recycler, producerResponsibilityOrg. Each party carries a legal name and at least one identifier.
Identifier rules (EN 18219 §6.2–6.5): a party needs at least one of gln, legacyOperatorId, or operatorIdentifier. If both gln and operatorIdentifier (scheme gln) are provided they must agree — a mismatch returns 400. An operatorIdentifier of scheme gln also fills the top-level gln field; facilityIdentifier never does. Typed identifiers (operatorIdentifier / facilityIdentifier) are not set by AI extraction or CSV import.
operatorIdentifier schemes:
• iso6523 — { scheme:"iso6523", icd:"<4 digits>", value } — ICD 0199 = LEI (ISO 17442), 0088 = GLN, 0060 = DUNS.
• gln — { scheme:"gln", gln:"<13 digits>" } — also fills top-level gln.
• did — { scheme:"did", did:"did::" } — syntax-checked only (EN 18219 §6.4.2(b)).
• doi — { scheme:"doi", doi:"10./" } — doi:/https://doi.org/ prefix accepted and stripped.
facilityIdentifier schemes: same four; the gln variant also accepts optional extension (GS1 SGLN sub-location).
Actions (pass via action, with args):
set — args: { id, role, legalName, gln?, country?, legacyOperatorId?, operatorIdentifier?, facilityIdentifier? }. Sets or updates one role.
remove — args: { id, role }. Clears one role.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; required fields depend on `action`. | |
| action | Yes | Set (add/replace) or remove an economic-operator party on a passport by its role. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only provide idempotentHint=true, so the description carries the behavioral burden and does so richly: a gln/operatorIdentifier mismatch returns 400, a scheme-gln operatorIdentifier also fills the top-level gln while facilityIdentifier never does, and typeds are excluded from AI extraction/CSV import. These are non-obvious behaviors beyond anything in the structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is long, but the length is earned by real complexity (two actions, six roles, four identifier schemes) and is well front-loaded and sectioned with bullets. The identifier-scheme enumeration is detailed but necessary; only minor tightening is possible.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with nested objects, an action enum, and an output schema already present, the description supplies everything an agent needs to call it correctly (required fields per action, identifier fallbacks, scheme syntaxes, error conditions). Return values need not be explained given the output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds genuine cross-field semantics: the at-least-one-identifier rule (gln/legacyOperatorId/operatorIdentifier), the agreement constraint between gln and operatorIdentifier, and the four operatorIdentifier schemes with their shapes. This goes beyond the per-field schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource ("Manage the economic-operator parties on a passport") and enumerates the exact roles covered (manufacturer, importer, authorisedRepresentative, distributor, recycler, producerResponsibilityOrg). This clearly distinguishes it from siblings like tracepass_passport_fields and tracepass_passports, which handle different sub-resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The two actions (set/remove) are documented with their full args, giving clear context for when each applies, and the note that typed identifiers are "not set by AI extraction or CSV import" signals a manual-only usage constraint. It stops short of explicitly routing the agent against sibling tools when a party vs. a generic field is at stake, so it is not a full 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracepass_passportsTracePass passportsAInspect
Manage Digital Product Passports — create, read, and run lifecycle actions.
IMPORTANT: create consumes DPP slots and IS BILLABLE. Over-quota creation incurs a per-passport charge; the tool surfaces a 402-style message — only re-run with args.confirmOverage=true after the user explicitly agrees. archive is IRREVERSIBLE (the public QR permanently 404s); prefer suspend when a change might be undone.
IDENTIFIER SCHEMES (EN 18219): passports are identified by one of five schemes. Battery passports (Battery Regulation Art. 77(3)) accept ONLY gs1 and iso15459. • gs1 — { scheme:"gs1", gtin, serialNumber } — GS1 GTIN + serial; gtin is 8/12/13/14 digits, stored as GTIN-14. • iso15459 — { scheme:"iso15459", issuingAgencyCode, primaryId, serial? } — ISO/IEC 15459; the server derives raw (IAC + primaryId + serial). • iec61406 — { scheme:"iec61406", uri } — IEC 61406 Identification Link (https URI). Not valid for batteries. • did — { scheme:"did", did, method } — W3C DID Core. Not valid for batteries. • doi — { scheme:"doi", doi, granularity:"model"|"batch"|"item" } — ISO 26324 DOI, stored as bare 10./ (any https://doi.org/ or doi: prefix stripped on input; resolves as https://doi.org/); granularity REQUIRED per EN 18219 §5.6.2(b). Not valid for batteries. The legacy top-level gtin + serialNumber pair is still accepted as a deprecated alias for scheme:"gs1".
Actions (pass via action, with args):
list — args: { page?, limit? (≤100), productId?, status?, search? }. status ∈ draft|in_review|approved|published|suspended|expired|archived. Read-only.
get — args: { id, format? (summary|full), lang? }. Read-only. Response includes
identifier,identifierKey, and (for GS1 passports)gs1.get_by_serial — args: { serial, format?, lang?, gtin? }. Read-only. Addresses the passport by your own serial. A serial is unique only WITHIN a GTIN — if the same serial exists under two GTINs in your account the call returns 409 ambiguous_serial; pass
gtin(or use the by-id action) to resolve exactly.compliance — args: { id }. Read-only. Returns a three-tier compliance verdict (compliant | compliant_with_warnings | incomplete) with regulation-cited findings — use to gap-check a passport against the rules for its category, fix the cited fields/parties, then re-check. Also returns byRegulation[]: the same findings grouped per regulation, worst first, so you can tell WHICH regime is failing instead of reading one
incompleteas everything being wrong. A regulation absent from that array raised no finding — that is not the same as it having passed.registry_readiness — args: { id }. Read-only. Returns { ready, findings[] } — whether the passport would pass the EU DPP Registry's FORMAL submission gate (mandatory fields present, correct formatting, a resolvable public link, item-level granularity via a serial number, and a well-formed commodity code where the category carries one). This is the registry's mechanical pre-submission check, NOT the substantive compliance verdict; a passport can be registry-ready yet not substantively compliant. Battery passports only.
create — args: { productId, identifier?, gtin?, serialNumber?, confirmOverage?, lineage? }. BILLABLE. Provide identifier (preferred) or legacy gtin + serialNumber. Battery passports accept only gs1 and iso15459 schemes — other schemes return 400. A duplicate identifier returns 409. lineage (battery only) — a repurposed, remanufactured or reused battery needs a NEW passport linked to the original(s) (Battery Regulation Art. 77(7)): { predecessors: [ { internalPassportId? | identifier?, trigger: preparation_for_reuse|preparation_for_repurposing|repurposing|remanufacturing } ] (≤10), noPredecessorReason? (only with an empty list, e.g. placed on the market before 18 Feb 2027) }. The server derives batteryStatus from the triggers and links your own predecessor passports back. Immutable after create. Rule violations return 422 with the rule code (duplicate_predecessor, predecessor_not_found, status_trigger_mismatch, …).
suspend — args: { id }. Reversible — public QR shows 'suspended'.
suspend_by_serial — args: { serial, gtin? }. Same as suspend, addressed by your serial. 409 ambiguous_serial if the serial isn't unique in your account — pass
gtin.archive — args: { id }. IRREVERSIBLE — confirm with the user first.
archive_by_serial — args: { serial, gtin? }. IRREVERSIBLE, addressed by your serial — confirm first. 409 ambiguous_serial if the serial isn't unique — pass
gtin.get_qr — args: { id, format? (svg|png), symbology? (qr|datamatrix) }. Read-only. symbology=datamatrix renders an ISO/IEC 16022 Data Matrix instead of a QR (EN 18220 permits both; same passport URL).
get_qr_by_serial — args: { serial, format? (svg|png), symbology? (qr|datamatrix), gtin? }. Read-only. Same as get_qr, addressed by your own serial. A serial is unique only WITHIN a GTIN — if the same serial exists under two GTINs in your account the call returns 409 ambiguous_serial; pass
gtin(or use get_qr by id) to resolve exactly.list_snapshots — args: { id, page?, limit? (≤100), at? (ISO 8601) }. Read-only. Returns a paginated list of snapshots for the passport (newest first). A snapshot is written on publish and after every change to a non-draft passport (EN 18221 change archive); each carries id, version, reason (e.g. published|field_edit|status_change|baseline), actor (who caused it, when known), snapshotAt, contentHash, hashValid (re-verified on every read), restorable, fieldCount. With
at, returns instead the single snapshot valid at that instant (full record plus validFrom/validUntil) — answers "what did this passport say on date D"; 404 before the first snapshot. Counts 1 against the daily read budget.get_snapshot — args: { id, snapshotId }. Read-only. Returns the full archival record of one snapshot: the complete JSON-LD the passport asserted at that time, plus hash and hashValid. Counts 1 against the daily read budget.
get_condition_flags — args: { id }. Read-only. Returns the resolved condition profile Record<flagKey,{value,status,source}>. Condition flags are reviewer-approved yes/no facts gating conditional legal duties. Battery flags: hasBMS, rechargeable, externalStorageOnly, isStationaryBess. An approved flag makes specific fields required — a missing gated field is a hard publish block (conditional_missing). Counts 1 against the daily read budget.
get_condition_flags_by_serial — args: { serial, gtin? }. Read-only. Same as get_condition_flags, addressed by your own serial. 409 ambiguous_serial if serial not unique — pass gtin.
set_condition_flags — args: { id, flags: Record<flagKey, boolean|null> }. WRITE. Set or clear condition flags (null clears). Keys must be registered for the passport category (battery: hasBMS, rechargeable, externalStorageOnly, isStationaryBess). WARNING: approving a flag can make fields required and block publishing if those fields are empty — fix any gated fields before or immediately after setting the flag. Writes are approved + audited. Idempotency-Key supported. Counts 1 write.
set_condition_flags_by_serial — args: { serial, gtin?, flags }. WRITE. Same as set_condition_flags, addressed by your own serial. 409 ambiguous_serial if serial not unique — pass gtin.
capture_measurements — args: { id, measurements: [ { fieldKey, value, measuredAt (ISO 8601), externalId?, unit? } ] (≤500) }. WRITE, battery passports only, published only. Pushes over-life measurements from the customer's own equipment (e.g. a BMS reporting stateOfHealth, numberOfFullEquivalentChargingCycles; the Annex XIII point 4 use-data keys). Every measurement is stored; the newest per field becomes the passport's current value and sets dynamicDataAsOf. externalId makes a measurement idempotent. A value may be at most 16 KB serialised. batteryStatus is NOT a measurement (400 invalid_field_key). A key the Regulation keeps off this battery category returns 422 field_not_applicable (e.g. stateOfCertifiedEnergy on an LMT battery). Metered against the plan's monthly measurement allowance, not the daily write budget: paid plans keep counting past it at no charge; Free stops at its allowance. Reading a passport is never metered.
capture_measurements_by_serial — args: { serial, gtin?, measurements }. Same, addressed by your own serial.
list_measurements — args: { id, fieldKey?, from?, to? (ISO 8601), limit? (≤200), cursor? }. Read-only. Measurement history, newest first; page with the returned nextCursor.
list_measurements_by_serial — args: { serial, gtin?, fieldKey?, from?, to?, limit?, cursor? }. Read-only.
latest_measurements — args: { id }. Read-only. The newest measurement per accepted key (null where none yet).
latest_measurements_by_serial — args: { serial, gtin? }. Read-only.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; required fields depend on `action` (see each action above). | |
| action | Yes | Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_condition_flags | get_condition_flags_by_serial | get_qr | get_qr_by_serial | list_snapshots | get_snapshot | list_measurements(_by_serial) | latest_measurements(_by_serial). Writes: set_condition_flags | set_condition_flags_by_serial | capture_measurements(_by_serial) | create (BILLABLE). Lifecycle: suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With only `idempotentHint: false` in annotations, the description carries the full burden and discloses critical behaviors: `create` is billable and over-quota triggers 402-style responses, `archive` is irreversible while `suspend` is reversible, writes are approved and audited, and some operations count against daily read or write budgets. It also documents idempotency behavior for individual measurements via `externalId`, without contradicting the tool-level `idempotentHint: false`.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very long, but the complexity of 24 actions and regulatory constraints largely justifies the size. It is well structured with a critical billing/irreversibility warning front-loaded, followed by identifiers and actions, though the repeated ambiguous_serial and by-id guidance across multiple actions introduces some redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the high action count, nested schema, output schema presence, and minimal annotations, the description is unusually complete. It covers billing, lifecycle reversibility, identifier schemes, error handling, metering, idempotency, and action-specific constraints, leaving no major gap an agent would need to infer before calling the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema description coverage is already 100%, the description adds substantial semantic meaning beyond the schema: it defines the five EN 18219 identifier schemes, battery-specific scheme restrictions, DOI granularity requirements, legacy GS1 alias behavior, lineage constraints, measurement key rules, and specific error codes. These details materially improve correct parameter construction beyond the already strong schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb and resource: 'Manage Digital Product Passports — create, read, and run lifecycle actions.' It then enumerates every action, making it clear this tool owns passport lifecycle and data operations rather than fields, parties, products, templates, or EPCIS data. An agent can identify the tool's scope immediately without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance throughout: use `suspend` instead of irreversible `archive`, use `registry_readiness` for formal submission checks versus `compliance` for substantive verdicts, and use `gtin` to resolve 409 ambiguous_serial cases. It also instructs the agent to confirm overage charges with the user before setting `confirmOverage` and to confirm before irreversible archive operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracepass_productsTracePass productsAInspect
Manage the TracePass product catalogue. A product is the catalogue layer — one product can have many passports (one per serialised unit). Products are not billable on their own.
Actions (pass via action, with args):
list — args: { page?, limit? (≤100), category?, status?, search? }. Read-only.
get — args: { id }. Read-only.
create — args: { name, model, category, description? }.
categoryis one of: battery, textile, electronics, construction, steel, detergents, paints-coatings, packaging, furniture, tyres, jewelry, toys, fmcg.update — args: { id, name?, model?, description? }; pass at least one field to change.
create_batch — args: { products: [ { name, model, category, description? }, … ] }, up to 100. Partial-success: the response carries a per-item status, so some items can be created while others error. The whole batch consumes N writes upfront; if that would exceed the daily cap NOTHING is created (429).
archive — args: { id }. Soft-archive a product. Blocked with 409 while any non-archived passport still references it — archive those passports first. This is reversible and is NOT deletion.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; required fields depend on `action` (see each action above). | |
| action | Yes | Which product operation to run: list | get | create | create_batch | update | archive. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given only idempotentHint=false annotation, the description carries the full burden of behavioral disclosure. It explicitly marks list and get as 'Read-only', describes create_batch's partial-success model with per-item status, mentions the daily cap for batch operations returning 429, and details archive as a reversible soft-archive (not deletion) with conflict conditions. No contradictions with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with clear section headers (Actions) and bullet-point style for each action. Every sentence provides essential operational detail without redundancy. It front-loads the core concept ('A product is the catalogue layer') and then precisely documents each action's semantics in minimal space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having an output schema, the description fully characterizes the tool's behavior across six actions, including error conditions (409, 429), success semantics (partial-success), and limitations (batch max 100, daily cap). Given the complexity (nested objects, multiple actions, edge cases), the description is remarkably complete without relying on output schema documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds significant value by grouping parameters per action (e.g., 'args: { page?, limit? (≤100), category?, status?, search? }'), enumerating valid category values, clarifying that update passes 'at least one field to change', and specifying batch limits. However, the description doesn't document all nested object properties for create_batch's products array beyond the example structure, which the schema also lacks.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Manage the TracePass product catalogue' and defines a product as 'the catalogue layer — one product can have many passports'. It explicitly enumerates six distinct actions (list, get, create, update, create_batch, archive) with their specific behavior, which distinguishes this tool from siblings like tracepass_passports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides excellent when-to-use guidance by explaining the relationship between products and passports, noting that 'Products are not billable on their own' and for archive action specifying when a 409 conflict occurs (blocked while any non-archived passport references it). This context helps the agent decide when to use this catalog tool vs passport-specific tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
tracepass_templatesTracePass DPP templates (regulatory schemas)ARead-onlyIdempotentInspect
Discover the regulatory field schema for each DPP category — what a COMPLIANT passport must contain, per the governing EU regulation. Read-only reference data. Use this to advise on requirements before creating products/passports, and to gap-check a draft against the rules.
Actions (pass via action, with args):
list — args: {}. Lists all 13 categories with their field count, required-field count, and governing regulation (name + number + effective/mandatory dates).
get — args: { category }. Full field schema for one category: every field's key, label, dataType, whether it is REQUIRED, its access level (public/restricted/authority), enum options, validation bounds, and — where known — the regulation article/annex that mandates it.
categoryis one of: battery, textile, electronics, construction, steel, detergents, paints-coatings, packaging, furniture, tyres, jewelry, toys, fmcg.
BATTERY — required-ness is per-category, so required alone is the wrong answer. Resolve it in this order:
SCOPE FIRST. Only EV, LMT and industrial_gt_2kwh batteries owe a passport at all (Art. 77(1), Reg (EU) 2023/1542). For portable, SLI or industrial_lte_2kwh, NO field is required — do not list mandatory fields for them; say the battery is out of scope.
Then
requiredBy[batteryCategory]where the field carries that map (required | conditional | notApplicable).Then fall back to
required. The map is keyed ONLY by the three in-scope categories, so skipping step 1 falls through torequiredand invents an obligation the Regulation does not impose. Note also that EV and LMT report state-of-health through MUTUALLY EXCLUSIVE field sets — an EV battery must leave the remaining-capacity cluster empty and an LMT battery must leave stateOfCertifiedEnergy empty, so no single battery ever fills every field.
| Name | Required | Description | Default |
|---|---|---|---|
| args | No | Arguments for the chosen action; `category` is required for get, ignored for list. | |
| action | Yes | List all DPP category templates, or get one template by category. |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | The resource's TracePass id, when the response is a single entity. |
| page | No | Current page number (list actions). |
| error | No | Machine-readable error code, when the API rejected the request. |
| items | No | The page of results, when the action is a list. |
| limit | No | Page size (list actions). |
| total | No | Total matching records across all pages (list actions). |
| result | No | Wraps a non-object response body (e.g. a QR code string). |
| message | No | Human-readable error or status detail, when present. |
| totalPages | No | Total number of pages (list actions). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true, indicating safe, repeatable reads. The description adds substantial behavioral context beyond these annotations: it explains that the data is regulatory schema (not actual passport data), details the resolution logic for the battery 'required' field, warns about mutual exclusivity of field sets for EV/LMT, and describes the scope-first rule. This provides rich behavioral transparency without contradicting the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear intro sentence, followed by action specifications and a detailed battery resolution section. It is front-loaded with the main purpose and use cases. The battery section is somewhat long but necessary for safe usage. Slightly verbose in the enum listing, which could be redundant given schema coverage. Overall earns its length with valuable content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity of regulatory schema, two actions, and an output schema existence, the description is comprehensive. It covers return value semantics for both actions, provides critical edge case handling for battery category, explains the resolution order for 'required-ness', and notes the mutual exclusivity rule for EV/LMT. The output schema likely documents the return structure, so the description does not need to duplicate that. A fully complete description for a moderately complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%; the schema already documents both parameters (action and category) with enums and descriptions. The description adds value by explaining what each action returns (list yields category list with field counts; get yields full field schema) and provides the complete list of category enum values. It also adds critical context about the battery category's special resolution logic, though parameter semantics themselves are mostly covered by the schema. Baseline 3 plus one extra for the battery-specific nuance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it is a 'read-only reference data' tool to 'discover the regulatory field schema for each DPP category'. It explicitly distinguishes two actions (list and get) and specifies what each returns, making the purpose unambiguous. The verb 'discover' combined with the resource 'regulatory field schema' provides a specific verb+resource pairing that differentiates it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells when to use this tool: 'advise on requirements before creating products/passports' and 'to gap-check a draft against the rules'. It provides clear guidance on the actions (list vs. get) and when to use each. No explicit when-not-to-use exclusions are needed as the scope is well-defined, and there are no obvious alternative siblings that compete for the same use case.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.17.0- Changed
tracepass_passport_fields1 field changed- added
Input schema / properties / args / properties / sourceAdded value: +{ + "description": "Where the value came from: \"manual\" (default — the user's statement) or \"ai_suggested\" (you found it; it goes to human review).", + "enum": [ + "manual", + "ai_suggested" + ], + "type": "string" +}
1 tool update
v1.16.2- Changed
tracepass_passports8 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_condition_flags | get_condition_flags_by_serial | get_qr | get_qr_by_serial | list_snapshots | get_snapshot. Writes: set_condition_flags | set_condition_flags_by_serial | create (BILLABLE). Lifecycle: suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant."New value: +"Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_condition_flags | get_condition_flags_by_serial | get_qr | get_qr_by_serial | list_snapshots | get_snapshot | list_measurements(_by_serial) | latest_measurements(_by_serial). Writes: set_condition_flags | set_condition_flags_by_serial | capture_measurements(_by_serial) | create (BILLABLE). Lifecycle: suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant." - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "get_by_serial", - "compliance", - "registry_readiness", - "get_condition_flags", - "get_condition_flags_by_serial", - "set_condition_flags", - "set_condition_flags_by_serial", - "create", - "suspend", - "suspend_by_serial", - "archive", - "archive_by_serial", - "get_qr", - "get_qr_by_serial", - "list_snapshots", - "get_snapshot" -]New value: +[ + "list", + "get", + "get_by_serial", + "compliance", + "registry_readiness", + "get_condition_flags", + "get_condition_flags_by_serial", + "set_condition_flags", + "set_condition_flags_by_serial", + "capture_measurements", + "capture_measurements_by_serial", + "list_measurements", + "list_measurements_by_serial", + "latest_measurements", + "latest_measurements_by_serial", + "create", + "suspend", + "suspend_by_serial", + "archive", + "archive_by_serial", + "get_qr", + "get_qr_by_serial", + "list_snapshots", + "get_snapshot" +] - added
Input schema / properties / args / properties / cursorAdded value: +{ + "description": "list_measurements(_by_serial): nextCursor from the previous page.", + "type": "string" +} - added
Input schema / properties / args / properties / fieldKeyAdded value: +{ + "description": "list_measurements(_by_serial): only this field key.", + "type": "string" +} - added
Input schema / properties / args / properties / fromAdded value: +{ + "description": "list_measurements(_by_serial): measuredAt from (ISO 8601).", + "type": "string" +} - added
Input schema / properties / args / properties / lineageAdded value: +{ + "description": "create, battery only: link a second-life battery's new passport to the original passport(s) (Art. 77(7)). See the create action.", + "properties": { + "noPredecessorReason": { + "maxLength": 500, + "type": "string" + }, + "predecessors": { + "items": { + "properties": { + "identifier": { + "maxLength": 2000, + "type": "string" + }, + "internalPassportId": { + "type": "string" + }, + "trigger": { + "enum": [ + "preparation_for_reuse", + "preparation_for_repurposing", + "repurposing", + "remanufacturing" + ], + "type": "string" + } + }, + "required": [ + "trigger" + ], + "type": "object" + }, + "maxItems": 10, + "type": "array" + } + }, + "required": [ + "predecessors" + ], + "type": "object" +} - added
Input schema / properties / args / properties / measurementsAdded value: +{ + "description": "capture_measurements(_by_serial): [{ fieldKey, value, measuredAt, externalId?, unit? }], max 500.", + "items": { + "properties": { + "externalId": { + "type": "string" + }, + "fieldKey": { + "minLength": 1, + "type": "string" + }, + "measuredAt": { + "minLength": 1, + "type": "string" + }, + "unit": { + "type": "string" + }, + "value": {} + }, + "required": [ + "fieldKey", + "value", + "measuredAt" + ], + "type": "object" + }, + "type": "array" +} - added
Input schema / properties / args / properties / toAdded value: +{ + "description": "list_measurements(_by_serial): measuredAt to (ISO 8601).", + "type": "string" +}
2 tool updates
v1.14.1- Changed
tracepass_passport_parties6 fields changed- changed
Input schema / properties / args / properties / country / descriptionPrevious value: -"Party country code (set, optional)."New value: +"ISO 3166-1 alpha-2 country code (set, optional)." - added
Input schema / properties / args / properties / facilityIdentifierAdded value: +{ + "additionalProperties": {}, + "description": "Structured facility identifier per EN 18219 §6.2–6.5. Same four schemes as operatorIdentifier; the gln variant also accepts optional `extension` (GS1 SGLN sub-location). Never fills the top-level gln field. Not set by AI extraction.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Input schema / properties / args / properties / gln / descriptionPrevious value: -"GS1 Global Location Number for the party (set, optional)."New value: +"GS1 Global Location Number (13 digits). Strongly recommended for multi-role disambiguation." - changed
Input schema / properties / args / properties / legacyOperatorId / descriptionPrevious value: -"Your internal operator id for the party (set, optional)."New value: +"Free-text fallback identifier (VAT, EORI, supplier code). Required when gln and operatorIdentifier are both absent." - added
Input schema / properties / args / properties / operatorIdentifierAdded value: +{ + "additionalProperties": {}, + "description": "Structured operator identifier per EN 18219 §6.2–6.5. Must have `scheme` plus scheme fields. Schemes: iso6523 {icd:\"<4 digits>\", value} | gln {gln:\"<13 digits>\"} | did {did:\"did:<method>:<id>\"} | doi {doi:\"10.<registrant>/<suffix>\"}. scheme gln also fills the top-level gln field; they must match if both are set (400 otherwise). Not set by AI extraction.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Input schema / properties / args / properties / role / descriptionPrevious value: -"Economic-operator role, e.g. manufacturer | importer | distributor | authorised_representative (required)."New value: +"Economic-operator role: manufacturer | importer | authorisedRepresentative | distributor | recycler | producerResponsibilityOrg (required)."
- Changed
tracepass_passports11 fields changed- changed
Input schema / properties / action / descriptionPrevious value: -"Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_qr | get_qr_by_serial. Lifecycle: create (BILLABLE) | suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant."New value: +"Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_condition_flags | get_condition_flags_by_serial | get_qr | get_qr_by_serial | list_snapshots | get_snapshot. Writes: set_condition_flags | set_condition_flags_by_serial | create (BILLABLE). Lifecycle: suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant." - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "get_by_serial", - "compliance", - "registry_readiness", - "create", - "suspend", - "suspend_by_serial", - "archive", - "archive_by_serial", - "get_qr", - "get_qr_by_serial" -]New value: +[ + "list", + "get", + "get_by_serial", + "compliance", + "registry_readiness", + "get_condition_flags", + "get_condition_flags_by_serial", + "set_condition_flags", + "set_condition_flags_by_serial", + "create", + "suspend", + "suspend_by_serial", + "archive", + "archive_by_serial", + "get_qr", + "get_qr_by_serial", + "list_snapshots", + "get_snapshot" +] - added
Input schema / properties / args / properties / atAdded value: +{ + "description": "list_snapshots: ISO 8601 instant — return the snapshot valid then instead of the list.", + "type": "string" +} - changed
Input schema / properties / args / properties / confirmOverage / descriptionPrevious value: -"Set true to accept a per-passport overage charge when create is over the plan quota (402)."New value: +"Set true to accept per-passport overage charges when over the plan quota (402). Applies to create." - added
Input schema / properties / args / properties / flagsAdded value: +{ + "additionalProperties": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ] + }, + "description": "For set_condition_flags / set_condition_flags_by_serial: Record<flagKey, boolean|null>. null clears the flag.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Input schema / properties / args / properties / gtin / descriptionPrevious value: -"GTIN disambiguator for *_by_serial actions when a serial isn't unique across GTINs (else 409 ambiguous_serial)."New value: +"For create (legacy): GS1 GTIN. Also used as a disambiguator for *_by_serial actions when a serial isn't unique (else 409 ambiguous_serial)." - changed
Input schema / properties / args / properties / id / descriptionPrevious value: -"Passport id. Required for get/compliance/create-result/suspend/archive/get_qr (the by-id actions)."New value: +"Passport id. Required for get/compliance/suspend/archive/get_qr (the by-id actions)." - added
Input schema / properties / args / properties / identifierAdded value: +{ + "additionalProperties": {}, + "description": "EN 18219 scheme-tagged identifier for create. Must have `scheme` plus scheme-specific fields. Schemes: gs1 {gtin, serialNumber} | iso15459 {issuingAgencyCode, primaryId, serial?} | iec61406 {uri} | did {did, method} | doi {doi, granularity} (granularity: \"model\"|\"batch\"|\"item\" REQUIRED per EN 18219 §5.6.2(b)). Battery passports: gs1 and iso15459 only.", + "propertyNames": { + "type": "string" + }, + "type": "object" +} - changed
Input schema / properties / args / properties / serialNumber / descriptionPrevious value: -"Serial for the new passport. Required for create."New value: +"Serial for the new passport (create, legacy gs1 path)." - added
Input schema / properties / args / properties / snapshotIdAdded value: +{ + "description": "Snapshot id. Required for get_snapshot.", + "type": "string" +} - added
Input schema / properties / args / properties / symbologyAdded value: +{ + "description": "get_qr/get_qr_by_serial: qr (default) | datamatrix.", + "type": "string" +}
2 tool updates
v1.8.0- Changed
tracepass_products1 field changed- changed
Input schema / properties / args / properties / category / descriptionPrevious value: -"DPP category for create: battery | textile | electronics | construction | steel | chemicals | packaging | furniture | tyres | jewelry | toys | fmcg."New value: +"DPP category for create: battery | textile | electronics | construction | steel | detergents | paints-coatings | packaging | furniture | tyres | jewelry | toys | fmcg."
- Changed
tracepass_templates1 field changed- changed
Input schema / properties / args / properties / category / descriptionPrevious value: -"DPP category to fetch (required for get): battery | textile | electronics | construction | steel | chemicals | packaging | furniture | tyres | jewelry | toys | fmcg."New value: +"DPP category to fetch (required for get): battery | textile | electronics | construction | steel | detergents | paints-coatings | packaging | furniture | tyres | jewelry | toys | fmcg."
6 tool updates
v1.7.3- Changed
tracepass_epcis7 fields changed- added
Input schema / properties / action / descriptionAdded value: +"EPCIS 2.0: export a passport's events (export | export_by_serial), capture new events, poll a capture job, or query events." - changed
Input schema / properties / action / enumPrevious value: -[ - "export", - "capture", - "capture_job", - "query" -]New value: +[ + "export", + "export_by_serial", + "capture", + "capture_job", + "query" +] - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description."New value: +"Arguments for the chosen action; required fields depend on `action`." - added
Input schema / properties / args / propertiesAdded value: +{ + "events": { + "description": "EPCIS 2.0 event payload (an EPCISDocument or event list). Required for capture." + }, + "gtin": { + "description": "GTIN disambiguator for export_by_serial when the serial isn't unique (else 409).", + "type": "string" + }, + "id": { + "description": "Passport id. Required for export.", + "type": "string" + }, + "jobId": { + "description": "Capture job id to poll. Required for capture_job.", + "type": "string" + }, + "params": { + "additionalProperties": { + "type": "string" + }, + "description": "EPCIS query parameters as key→value strings (query, optional).", + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "serial": { + "description": "Your serial. Required for export_by_serial.", + "type": "string" + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
- Changed
tracepass_passport_fields7 fields changed- added
Input schema / properties / action / descriptionAdded value: +"Update one passport field, addressed by passport id (update) or by your serial (update_by_serial)." - changed
Input schema / properties / action / enumPrevious value: -[ - "update" -]New value: +[ + "update", + "update_by_serial" +] - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description."New value: +"Arguments for the chosen action; required fields depend on `action`." - added
Input schema / properties / args / propertiesAdded value: +{ + "fieldKey": { + "description": "The field key to set (required).", + "type": "string" + }, + "gtin": { + "description": "GTIN disambiguator for update_by_serial when the serial isn't unique (else 409).", + "type": "string" + }, + "id": { + "description": "Passport id. Required for update.", + "type": "string" + }, + "serial": { + "description": "Your serial. Required for update_by_serial.", + "type": "string" + }, + "value": { + "description": "The new value for the field (required). Type depends on the field's dataType." + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
- Changed
tracepass_passport_parties6 fields changed- added
Input schema / properties / action / descriptionAdded value: +"Set (add/replace) or remove an economic-operator party on a passport by its role." - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description."New value: +"Arguments for the chosen action; required fields depend on `action`." - added
Input schema / properties / args / propertiesAdded value: +{ + "country": { + "description": "Party country code (set, optional).", + "type": "string" + }, + "gln": { + "description": "GS1 Global Location Number for the party (set, optional).", + "type": "string" + }, + "id": { + "description": "Passport id (required).", + "type": "string" + }, + "legacyOperatorId": { + "description": "Your internal operator id for the party (set, optional).", + "type": "string" + }, + "legalName": { + "description": "Party legal name. Required for set.", + "type": "string" + }, + "role": { + "description": "Economic-operator role, e.g. manufacturer | importer | distributor | authorised_representative (required).", + "type": "string" + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
- Changed
tracepass_passports7 fields changed- added
Input schema / properties / action / descriptionAdded value: +"Which passport operation to run. Reads: list | get | get_by_serial | compliance | registry_readiness | get_qr | get_qr_by_serial. Lifecycle: create (BILLABLE) | suspend (reversible) | archive (IRREVERSIBLE), each with a _by_serial variant." - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "get_by_serial", - "create", - "suspend", - "archive", - "get_qr" -]New value: +[ + "list", + "get", + "get_by_serial", + "compliance", + "registry_readiness", + "create", + "suspend", + "suspend_by_serial", + "archive", + "archive_by_serial", + "get_qr", + "get_qr_by_serial" +] - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description for each action's shape."New value: +"Arguments for the chosen action; required fields depend on `action` (see each action above)." - added
Input schema / properties / args / propertiesAdded value: +{ + "confirmOverage": { + "description": "Set true to accept a per-passport overage charge when create is over the plan quota (402).", + "type": "boolean" + }, + "format": { + "description": "get/get_by_serial: summary|full. get_qr/get_qr_by_serial: svg|png.", + "type": "string" + }, + "gtin": { + "description": "GTIN disambiguator for *_by_serial actions when a serial isn't unique across GTINs (else 409 ambiguous_serial).", + "type": "string" + }, + "id": { + "description": "Passport id. Required for get/compliance/create-result/suspend/archive/get_qr (the by-id actions).", + "type": "string" + }, + "lang": { + "description": "Resolve field values to one of the 24 EU locales server-side (get/get_by_serial).", + "type": "string" + }, + "limit": { + "description": "Page size for list, max 100.", + "type": "number" + }, + "page": { + "description": "Page number for list (1-based).", + "type": "number" + }, + "productId": { + "description": "Parent product id. Required for create.", + "type": "string" + }, + "search": { + "description": "Filter list by a search term.", + "type": "string" + }, + "serial": { + "description": "Your own serial number. Required for the *_by_serial actions.", + "type": "string" + }, + "serialNumber": { + "description": "Serial for the new passport. Required for create.", + "type": "string" + }, + "status": { + "description": "Filter list by status: draft|in_review|approved|published|suspended|expired|archived.", + "type": "string" + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
- Changed
tracepass_products7 fields changed- added
Input schema / properties / action / descriptionAdded value: +"Which product operation to run: list | get | create | create_batch | update | archive." - changed
Input schema / properties / action / enumPrevious value: -[ - "list", - "get", - "create", - "update" -]New value: +[ + "list", + "get", + "create", + "create_batch", + "update", + "archive" +] - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description for each action's shape."New value: +"Arguments for the chosen action; required fields depend on `action` (see each action above)." - added
Input schema / properties / args / propertiesAdded value: +{ + "category": { + "description": "DPP category for create: battery | textile | electronics | construction | steel | chemicals | packaging | furniture | tyres | jewelry | toys | fmcg.", + "type": "string" + }, + "description": { + "description": "Free-text product description (create/update).", + "type": "string" + }, + "id": { + "description": "Product id. Required for get and update.", + "type": "string" + }, + "limit": { + "description": "Page size for list, max 100.", + "type": "number" + }, + "model": { + "description": "Manufacturer model / SKU. Required for create; optional on update.", + "type": "string" + }, + "name": { + "description": "Product name. Required for create; optional on update.", + "type": "string" + }, + "page": { + "description": "Page number for list (1-based).", + "type": "number" + }, + "products": { + "description": "Products to create for create_batch: [{ name, model, category, description? }], max 100.", + "items": { + "additionalProperties": {}, + "propertyNames": { + "type": "string" + }, + "type": "object" + }, + "type": "array" + }, + "search": { + "description": "Filter list by a search term.", + "type": "string" + }, + "status": { + "description": "Filter list by product status.", + "type": "string" + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
- Changed
tracepass_templates6 fields changed- added
Input schema / properties / action / descriptionAdded value: +"List all DPP category templates, or get one template by category." - removed
Input schema / properties / args / additionalPropertiesRemoved value: -{} - changed
Input schema / properties / args / descriptionPrevious value: -"Action-specific arguments — see the description for each action's shape."New value: +"Arguments for the chosen action; `category` is required for get, ignored for list." - added
Input schema / properties / args / propertiesAdded value: +{ + "category": { + "description": "DPP category to fetch (required for get): battery | textile | electronics | construction | steel | chemicals | packaging | furniture | tyres | jewelry | toys | fmcg.", + "type": "string" + } +} - removed
Input schema / properties / args / propertyNamesRemoved value: -{ - "type": "string" -} - changed
Output schema / (root)Previous value: -nullNew value: +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "additionalProperties": false, + "properties": { + "error": { + "description": "Machine-readable error code, when the API rejected the request.", + "type": "string" + }, + "id": { + "description": "The resource's TracePass id, when the response is a single entity.", + "type": "string" + }, + "items": { + "description": "The page of results, when the action is a list.", + "items": {}, + "type": "array" + }, + "limit": { + "description": "Page size (list actions).", + "type": "number" + }, + "message": { + "description": "Human-readable error or status detail, when present.", + "type": "string" + }, + "page": { + "description": "Current page number (list actions).", + "type": "number" + }, + "result": { + "description": "Wraps a non-object response body (e.g. a QR code string)." + }, + "total": { + "description": "Total matching records across all pages (list actions).", + "type": "number" + }, + "totalPages": { + "description": "Total number of pages (list actions).", + "type": "number" + } + }, + "type": "object" +}
6 tool updates
v1.1.4- First observed
tracepass_epcis - First observed
tracepass_passport_fields - First observed
tracepass_passport_parties - First observed
tracepass_passports - First observed
tracepass_products - First observed
tracepass_templates
TDQS
Scored across 6 tools
Each tool maps to a clearly distinct resource domain: passports, fields, parties, products, templates, and EPCIS events. An agent can unambiguously pick the right tool for a given resource, and the action parameter further separates operations within each tool.
All six tools share a consistent `tracepass_` prefix and snake_case noun convention (tracepass_passports, tracepass_products, tracepass_epcis). Minor inconsistency: some use singular nouns (tracepass_epcis, tracepass_templates) while others are plural/compound (tracepass_passport_fields, tracepass_passport_parties), but the pattern is still predictable.
Six well-scoped tools, each representing a coherent domain that groups related actions via the `action` parameter rather than exploding into dozens of separate tools. This is an efficient, appropriate granularity for the breadth of the DPP lifecycle.
The surface covers the full passport lifecycle (create/list/get/suspend/archive), field edits, parties, products, templates, EPCIS events, measurements, condition flags, and snapshots. Minor gap: snapshots expose `restorable` but there is no restore action, and there is no explicit delete for products/passports (soft-archive only), though that appears intentional.
Maintenance
Related MCP Connectors
MCP server for Boson Protocol — on-chain agentic commerce for physical & digital goods.
MCP server for Product Management
MCP Server for agents to onboard, pay, and provision services autonomously with InFlow
MCP server for verifying EUDI/Talao wallet data via OIDC4VP (pull) for AI agents.
Related MCP Servers
- AlicenseAqualityAmaintenanceModel Context Protocol (MCP) server for French Electronic Invoicing (NF XP Z12-013). Provide tools to validate, generate, and explore API specifications for PDP/OD interoperability.234Apache 2.0
- AlicenseNot gradedqualityCmaintenanceProvides a sovereign, MIT-licensed MCP server for professional-service workflows, running entirely on your infrastructure with Ed25519 cryptographic signing for every action.MIT
- AlicenseNot gradedqualityDmaintenanceA hosted remote MCP server for verifying C2PA intakes, classifying source risk, issuing media receipts, and exporting intake logs. Designed for AI governance, trust and safety, and compliance teams.MIT
- AlicenseAqualityAmaintenanceMCP server for GoCertius: certified evidence, dossiers, notifications and chats via AI agents.4183 npmMIT