Skip to main content
Glama

A202: the Verifiable Agreement Protocol for Agent-Led Commerce

Status: Informative in full.

A202 is verifiable commerce for agent-to-agent or agent-led transactions: an open specification of commercial authority, negotiation state, and verifiable conformance for transactions between independent organisations, including transactions conducted on their behalf by software agents.

It defines typed objects for delegated commercial authority, a state machine for the transaction and for each bilateral session inside it, rules for what may be disclosed to whom, and an executable conformance suite that turns each of those into a check an implementation either passes or fails.

The full statement of purpose, scope, and non-goals is in CHARTER.md.

Created and developed by A. A. Musse. See MAINTAINERS.md.

Status

Released, pre-1.0.

  • v0.1.0 is the first tagged release of the set: a tag, a digest for every schema file, the conformance manifest, and release notes, published together. See RELEASES.md and CHANGELOG.md. Before 1.0 a MINOR increment may break compatibility, and any break carries migration notes.

  • The name is A202, spoken "A two-oh-two", and in full A202, the Verifiable Agreement Protocol for Agent-Led Commerce. The long form is a descriptor and not an expansion: the letters do not stand for it. The 202 is HTTP 202 Accepted, which A202-0017 makes the status an accepted submission returns, because acceptance is the primitive the rest of the specification is built on. The A202- reason-code prefix, the A202-NNNN proposal identifiers, and the a202-commercial/0.1 specification version string all follow from the name.

  • A202™ is a trademark of Plural Worlds. Permitted use of the name is stated in TRADEMARK.md.

  • Schema $id values resolve under https://schemas.a202.org. Fixture hosts use reserved .invalid names, because test data must never resolve.

  • Licensed under the Apache License, Version 2.0. One licence covers the whole repository: specification text, schemas, fixtures, manifest, runner, and informative documents. The licence carries an express patent grant from each contributor. See LICENSE and CONTRIBUTING.md.

  • External contributions are accepted on the terms in CONTRIBUTING.md: inbound contributions under the same licence, with a developer certificate of origin sign-off.

Related MCP server: pact-mcp

Layout

Path

Contents

CHARTER.md

Purpose, scope, non-goals, design principles

GOVERNANCE.md

How the project is run, and what the sponsor does and does not control

MAINTAINERS.md

Who maintains this repository

CONTRIBUTING.md

Contribution status, and the terms a contribution is accepted under

SECURITY.md

Private coordinated disclosure

THREAT-MODEL.md

Adversaries assumed, properties defended, and what is deliberately not defended

CODE_OF_CONDUCT.md

Expected conduct

TRADEMARK.md

The A202 name, and what use of it is and is not permitted

RELEASES.md

Versioning, what a release consists of, compatibility policy

CHANGELOG.md

What changed, and where the release notes required by RELEASES.md accumulate

.github/

Review routing, the pull request and issue forms, and the workflow that runs the suite on every change

proposals/

The A202 change proposal process

schemas/

Canonical commercial model, transaction profile extension model, and the JSON schemas

authority/

Commercial mandate: delegated authority, constraints, delegation, approval, revocation

discovery/

Counterparty invitation: how an unregistered party enters one named transaction

negotiation/

Transaction and session state machines, and auction event semantics

conformance/

Fixtures, manifest, normative runner, and the conformance grade definitions

Each specification document carries a status header stating which of its sections are normative and which are informative.

Running the conformance suite

The runner validates every fixture named in the manifest against the schemas, then applies the invariants that JSON Schema cannot express. Schema validity is not conformance, which is the reason the runner exists.

It needs jsonschema>=4.18. If that is not on the system interpreter, a virtual environment is enough:

python3 -m venv .venv && .venv/bin/pip install "jsonschema>=4.18"

Run it from the repository root:

python3 conformance/run-conformance.py --verbose

The expected result is every fixture passing and none failing, with the totals the manifest carries: the manifest is the single source for the count, and the runner prints it on every run. The runner also asserts that each negative fixture is refused for the reason code the manifest declares for it, wherever the normative layer raises codes at all. Run it before and after any schema change.

Every negative fixture is minimal: removing the single offending element must leave a document that validates cleanly. A negative fixture that fails for an incidental reason tests nothing, so verify that when adding one.

The suite does not depend on anyone remembering to run it. It runs, together with the reference implementation tests and the MCP server tests, on every pull request and on every push to the default branch, under .github/workflows/checks.yml. GOVERNANCE.md section 3.4 requires the suite to pass for any change to schemas, fixtures, the manifest, or the runner, and that workflow is what turns the requirement into a gate.

Where to start reading

  1. CHARTER.md for what this is and what it deliberately is not.

  2. schemas/canonical-commercial-model-v0.1.md for the object model, the envelope, and the invariants schema validation cannot express.

  3. negotiation/pilot-transaction-state-machine-v0.1.md for what moves state and what does not.

  4. conformance/manifest-v0.1.json for the fixtures that decide whether an implementation agrees with either of the above.

Available Tools

7 tools
create_agreementForm an agreement with a known counterpartyA

Form an agreement between two parties who already know each other, with no marketplace and no negotiation room. Call this once per transaction.

Both parties present the allow decision their own mandate produced. The offeror verifies {"action_type": "offer.submit", "transaction_id": ..., "counterparty_organization_id": <the offeree's org>, "proposed_terms": } and the offeree verifies the same document with action_type offer.accept and the offeror's organisation. Pass each result as buyer_decision and supplier_decision. A decision over a different act, a different mandate, or an amount the mandate did not allow refuses the whole call and records nothing.

It writes the whole formation in one call: the offeror's signed offer carrying a session identifier it mints, the offeree's acceptance over the exact offer hash, the agreement carrying both parties' signatures over the same bytes, the supplier's commitment, and two events, agreement.direct (draft to agreement_pending) and agreement.committed (agreement_pending to committed), each countersigned by the other party.

The transaction ends this call in state committed. Follow with record_obligation act=issue.

Refusals: a transaction that already left draft (A202-STATE-TRANSITION-DENIED), an unregistered profile (A202-PROFILE-UNKNOWN), terms the profile does not allow (A202-PROFILE-TERMS-INVALID), an offer expiring before it was made (A202-OFFER-EXPIRED).

ParametersJSON Schema
NameRequiredDescriptionDefault
buyerYesThe buying party: organisation, agent, mandate, and signing key.
termsYesThe commercial terms. core is identical for every transaction profile; profile_terms is validated against the schema the profile names.
supplierYesThe supplying party: organisation, agent, mandate, and signing key.
session_idNoOptional session identifier, prefixed ses_. The offeror mints one when absent. Bilaterally this names the relationship; nothing orders it.
offeror_roleNoWhich party makes the offer. Defaults to supplier.
rules_versionNoThe rule set version the record is written under. Defaults to 1.3, the version that registers direct formation. Earlier versions never registered it and refuse the path.
buyer_decisionYesThe result verify_mandate returned for this exact act, passed through unchanged. It must be an allow, made under this party's own mandate, over the act document this tool builds, and made within the last 60 seconds. Where it does not match, the refusal detail states the exact proposed_action to verify. For the buyer this is the decision over its own act: offer.accept when the supplier is the offeror, offer.submit when the buyer is.
transaction_idYesThe transaction, prefixed txn_. Choose one per deal; it is the key everything else is recorded under.
offer_valid_untilYesRFC 3339 instant the offer expires. Must be later than now.
supplier_decisionYesThe result verify_mandate returned for this exact act, passed through unchanged. It must be an allow, made under this party's own mandate, over the act document this tool builds, and made within the last 60 seconds. Where it does not match, the refusal detail states the exact proposed_action to verify. For the supplier this is the decision over its own act: offer.submit when the supplier is the offeror, offer.accept when the buyer is.
offer_evidence_refsNoOptional evidence the offer relies on, such as an accreditation.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description discloses the full write path: 'It writes the whole formation in one call... two events, agreement.direct and agreement.committed, each countersigned by the other party.' It also details refusal conditions (A202-* codes) and notes that a non-matching decision 'refuses the whole call and records nothing.' These are meaningful behavioral details that go beyond the provided annotations (readOnlyHint=false, etc.), which are minimal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately dense for the tool's complexity. It is organized logically: purpose, scenario, verification steps, write behavior, follow-up, and refusals. Every sentence contributes necessary information without filler. It is longer than average, but the complexity of the tool justifies the length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description comprehensively covers the workflow, verification requirements, state transitions, refusal reasons, and next-step guidance. The only notable gap is that it does not explicitly describe the return value of the tool; since there is no output schema, a brief note on what the call returns (e.g., the transaction record or confirmation) would complete the picture.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema covers all parameters, the description adds essential semantic context for buyer_decision and supplier_decision by specifying the exact act documents to verify, the role-dependent action_type values (offer.submit vs. offer.accept), and the 60-second validity window. It also explains that session_id is minted by the offeror if absent. This substantially enriches the meaning of the parameters beyond the schema descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Form an agreement between two parties who already know each other, with no marketplace and no negotiation room.' This specifies the exact action and resource, and distinguishes it from marketplace-based flows or other transaction tools. It is not a tautology and clearly states the scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states 'Call this once per transaction' and clarifies the appropriate scenario (known counterparties, no marketplace, no negotiation). It also provides a clear follow-up action: 'Follow with record_obligation act=issue,' which orients the agent on the next step. This is strong when-to-use guidance with an explicit alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_transaction_recordRead the transaction recordA
Read-onlyIdempotent

Return this party's own copy of the hash-chained transaction record: every event in chain order with the state it moved the transaction to, which keys signed it, and the object it concerns, plus the state the record currently reaches and every object identifier held for the transaction.

Call it at any point to see where a transaction stands before deciding what to do next. Ordering is by predecessor reference rather than by a counter, because bilaterally there is no ordering service, and a record whose links do not form one chain is reported as broken with A202-EVIDENCE-CHAIN-GAP.

ParametersJSON Schema
NameRequiredDescriptionDefault
transaction_idYesThe transaction to read, prefixed txn_.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds substantial extra behavioral detail: ordering by 'predecessor reference rather than by a counter', the concept of a 'broken' chain, and the specific error code 'A202-EVIDENCE-CHAIN-GAP'. This goes well beyond 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, but the first is a long, dense list of contents. Every clause adds value, but the structure could be slightly improved by splitting into bullet points. It is generally efficient and information-dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description compensates well by enumerating what the record contains (events, state, keys, object), how ordering works, and how broken chains are reported. It is comprehensive for a read-only tool, though it could mention the exact return format (e.g., JSON structure) to be fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already covers the only parameter (transaction_id) with 100% coverage, including the prefix constraint 'txn_'. The description adds no extra parameter-specific semantics, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Return this party's own copy of the hash-chained transaction record'. It uses a specific verb ('Return') and identifies the resource, and the unique phrasing 'own copy' and 'hash-chained' differentiates it from sibling tools like verify_evidence or create_agreement.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use: 'Call it at any point to see where a transaction stands before deciding what to do next.' This gives clear context, though it does not explicitly name alternatives or state when not to use, which would be required for a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

issue_approvalApprove one exact actA

Record a named principal's approval of one exact act, bound to the action_hash verify_mandate reported. Call this only after verify_mandate answered require_approval, then call verify_mandate again passing approval_id and the identical proposed_action.

The approval is signed by the approving principal's own key, not by the agent's, because the control is that somebody other than the acting agent said yes. It binds one action hash and one transaction and is reusable across neither: change one byte of the act and the next verify_mandate returns A202-APPROVAL-HASH-MISMATCH. It also expires, after which it authorises nothing.

An approval never releases a deny. A denied constraint is a limit, not a question.

Returns the approval identifier, the action hash it binds, and when it expires.

ParametersJSON Schema
NameRequiredDescriptionDefault
approverYesThe principal giving the approval, and the key that principal signs with.
decisionNoDefaults to approved. A rejected approval releases nothing and is recorded as the refusal it is.
conditionsNoOptional conditions the approver attached. They are part of the signed approval and travel with it.
expires_atNoRFC 3339 instant the approval expires, when you would rather state it than count from now. Overrides expires_after_seconds.
action_hashYesThe action_hash verify_mandate returned for this act. 64 lowercase hexadecimal characters.
requested_byYesThe agent whose act is being approved. The approver is a principal of this same organisation.
transaction_idYesThe transaction the approved act belongs to, prefixed txn_.
expires_after_secondsNoHow long the approval is good for, from now. Defaults to 3600.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint=false, destructiveHint=false), the description discloses the signing key ownership, single hash/tx binding, expiration, and the A202-APPROVAL-HASH-MISMATCH behavior. This adds substantial behavioral context that annotations do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is several sentences long but each sentence earns its place: purpose, sequencing, signing details, hash binding, expiration, deny behavior, and return value. It is front-loaded and logically structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite 8 parameters, nested objects, and no output schema, the description states the return fields (approval identifier, action hash, expiration) and provides the full invocation sequence and behavioral constraints. The schema fully documents parameters, so the description covers all necessary context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds semantic meaning beyond the schema by linking action_hash to the verify_mandate result, explaining that conditions become part of the signed approval, and clarifying that a rejected decision releases nothing. This enrichment earns a 4.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific action: recording a named principal's approval of one exact act, bound to the action_hash verify_mandate reported. It clearly identifies the resource and distinguishes this from sibling tools by referencing the verify_mandate flow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs to call only after verify_mandate answered require_approval, then to call verify_mandate again with approval_id. It also states a key boundary: an approval never releases a deny, providing clear when-to-use versus when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

issue_mandateIssue a commercial mandateA

Issue and sign a commercial mandate: the document stating which organisation an agent represents, which acts it may take, under which limits, for which transaction or category, and for how long. Call this once per acting agent before anything else. Every other tool names the mandate an agent acts under.

A spending_limit becomes two explicit constraints, an amount ceiling and a currency, both visible in the audit record.

The mandate is checked before it is signed, so a refused one never receives a signature that would make it look issued. Refusals: no constraint at all (A202-MANDATE-UNBOUNDED), a scope naming neither a transaction nor a category (A202-MANDATE-SCOPE-TOO-BROAD), an inverted validity interval (A202-MANDATE-INTERVAL-INVALID), a status endpoint that is not HTTPS (A202-MANDATE-STATUS-INSECURE), a subject naming both an agent and a principal (A202-MANDATE-SUBJECT-AMBIGUOUS).

Returns the mandate identifier and the signed document.

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeYesThe boundary of the authority. Must carry transaction_ids, categories, or both. Counterparty and geography narrow an existing boundary and cannot establish one, so a scope naming only a country is refused.
issuerYesThe principal issuing the authority, and the key it signs with.
actionsYesThe acts the subject may take, for example offer.submit, offer.accept, agreement.sign. Deny by default: an omitted act is not allowed.
subjectYesWho acts under the mandate: exactly one of an agent or a delegated principal, never both.
delegationNoOptional, defaults to no delegation. allowed false requires maximum_depth 0; allowed true requires at least 1. An incoherent pair is refused rather than interpreted.
mandate_idNoOptional explicit identifier, prefixed mnd_. One is minted when absent.
valid_fromYesRFC 3339 UTC instant. Must be strictly earlier than valid_until.
constraintsNoOptional further constraints, each with id, type, path, operator, value, and on_failure of deny or require_approval. At least one constraint must exist in total, counting those a spending limit generates.
valid_untilYesRFC 3339 UTC instant. The mandate authorises nothing at or after it.
evidence_refsNoOptional identity, role, or authorisation evidence supporting the issue.
approval_rulesNoOptional. Each rule carries id, a when predicate of path, operator, and value, an approver of organization_id and role, and expires_after_seconds. A matching act is held until an approval from that approver binds it.
spending_limitNoOptional. Becomes an amount ceiling and a currency constraint. A ceiling with no currency would be satisfied by that number of any currency, so both are written.
status_endpointYesHTTPS URL where this mandate's current status is published. HTTPS only: cached status is the only channel a revocation reaches a relying party through.
parent_mandate_idNoThe mandate this one is delegated from, or null for a root mandate.
represented_organization_idYesThe organisation the subject represents in its acts, prefixed org_.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes far beyond the annotations (which only say readOnlyHint=false, etc.). It discloses that a spending_limit becomes two constraints 'both visible in the audit record', that the mandate is checked before signing so refusals never receive a signature, and lists specific refusal codes. It also states the return value ('Returns the mandate identifier and the signed document'). These are significant behavioral details not derivable from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is longer than typical but well-structured: purpose and usage are front-loaded, followed by key behavioral notes, refusal list, and return value. Every sentence adds necessary information (e.g., audit record visibility, pre-signing checks, refusal codes), so it is appropriately sized for the tool's complexity. It is not minimal, but it is efficient and free of fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 15 parameters, 8 required, nested objects, and no output schema, the description is remarkably complete. It covers purpose, usage, side effects (audit record), failure modes (specific refusal codes), and return value. It also explains the global role of the mandate ('Every other tool names the mandate an agent acts under'), providing sufficient context for an agent to use it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 100% schema description coverage, the baseline is 3. The description adds extra meaning for spending_limit, explaining it becomes both an amount ceiling and a currency constraint with audit trail visibility, and clarifies the scope requirement that a scope must carry transaction_ids or categories. These enrich the parameter understanding beyond the schema's own descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states exactly what the tool does: 'Issue and sign a commercial mandate' and defines the document's content ('which organisation an agent represents, which acts it may take, under which limits, for which transaction or category, and for how long'). It clearly distinguishes from siblings like verify_mandate by saying 'Call this once per acting agent before anything else' and noting that every other tool names the mandate an agent acts under.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly instructs when to use the tool: 'Call this once per acting agent before anything else' and explains its role as a prerequisite for other tools. It doesn't explicitly name alternatives or exclusion conditions, but the 'once per acting agent before anything else' directive provides clear usage context. The refusal conditions also imply when a mandate would not be issued, which indirectly guides usage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

record_obligationIssue, assert, or answer an obligationA

Record one act in the obligation exchange. Three acts, in this order, each signed by a different party, and each carrying that party's own allow decision from verify_mandate.

act=issue: the obligee derives an obligation from a committed agreement and activates it. Needs agreement_id, obligor, obligee, term_path, quantity, unit_code, due_condition, and a decision the obligee obtained for {"action_type": "obligation.activated", "transaction_id": ..., "counterparty_organization_id": <the obligor's org>, "proposed_terms": {"core": {"quantity": ..., "unit_code": ..., "total": }}, "agreement_id": ...}. The transaction moves to in_performance.

act=assert: the obligor asserts it performed. Needs obligation_id, obligor, obligee, asserted_quantity, at least one evidence entry, and a decision the obligor obtained for action_type performance.declared naming the obligee as counterparty, the asserted quantity and unit as proposed_terms, and the obligation_id. An assertion with no evidence is refused with A202-OBLIGATION-ASSERTION-UNEVIDENCED. The transaction moves to acceptance_pending.

act=respond: the obligee accepts or rejects, bound to the exact assertion hash. Needs assertion_id, responder, counterparty, response_type, and a decision the responder obtained for action_type acceptance.granted or acceptance.rejected naming the counterparty and the assertion_id. A response signed by anyone but the obligee is refused with A202-OBLIGATION-RESPONSE-UNAUTHORIZED; accepting less than is owed without naming a remainder obligation is refused with A202-OBLIGATION-REMAINDER-MISSING. Accept moves the transaction to settlement_pending, reject back to in_performance, where the obligor may assert again.

ParametersJSON Schema
NameRequiredDescriptionDefault
actYesWhich act to record. Which other fields are required depends on it.
obligeeNoact=issue and act=assert. The party owed to.
obligorNoact=issue and act=assert. The party that owes.
decisionYesThe result verify_mandate returned for this exact act, passed through unchanged. It must be an allow, made under this party's own mandate, over the act document this tool builds, and made within the last 60 seconds. Where it does not match, the refusal detail states the exact proposed_action to verify. The acting party is the obligee for issue, the obligor for assert, and the responder for respond.
evidenceNoact=assert. At least one entry. Each becomes a signed evidence object the assertion references by hash.
quantityNoact=issue. Base-10 string of how much is owed.
responderNoact=respond. Must be the obligee named on the obligation.
term_pathNoact=issue. The owed term, addressed under $.terms.core or $.terms.profile_terms. The obligation points at the agreement's terms and never restates them, so drift shows up as a hash mismatch.
unit_codeNoact=issue. UN/ECE Recommendation 20 common code, matching the terms.
reason_codeNoact=respond with reject. The list is closed and anything else is refused.
agreement_idNoact=issue. The committed agreement the obligation derives from, prefixed agr_.
assertion_idNoact=respond. The assertion being answered, prefixed prf_.
counterpartyNoact=respond. The other party, which countersigns the event.
commitment_idNoact=issue. Optional. Defaults to the agreement's first commitment.
considerationNoact=issue. The money attached to this obligation as currency and amount, or null.
due_conditionNoact=issue. One of due_at_time with at, due_on_event with act_ref or evidence_type, due_on_discharge with obligation_id, or all_of with at least two of those. Anything else is refused with A202-OBLIGATION-CONDITION-UNKNOWN.
obligation_idNoact=assert. The obligation being performed, prefixed obl_.
response_typeNoact=respond.
rules_versionNoThe rule set version the record is written under. Defaults to 1.3.
accepted_quantityNoact=respond with accept. Defaults to the asserted quantity. Below what is owed, a remainder_obligation_id is required.
asserted_quantityNoact=assert. Base-10 string of how much was performed.
remainder_obligation_idNoact=respond with a short acceptance. The obligation carrying the shortfall, so it stays in the record.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description richly discloses state transitions (in_performance, acceptance_pending, settlement_pending), failure modes with error codes (A202-OBLIGATION-ASSERTION-UNEVIDENCED, A202-OBLIGATION-RESPONSE-UNAUTHORIZED), and constraints on evidence and decisions. This goes far beyond the minimal annotations (all hints false) and provides significant operational detail. 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well-structured with an intro and three clearly labeled act blocks, following a consistent pattern of required fields then outcome/state transition. It is long but every sentence conveys necessary conditional information; however, it could arguably be tightened without losing value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with no output schema and high complexity, the description covers all essential selection and invocation aspects: prerequisites, per-act requirements, error handling, and resulting states. A minor gap is not stating the return value or how to reference the resulting obligation/assertion record, which would be expected when no output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema already documents all parameters at 100% coverage, the description adds crucial conditional logic: which fields are required per act, how the decision's proposed_action must align, and how accepted_quantity below owed interacts with remainder_obligation_id. That interplay is not visible from schema alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence 'Record one act in the obligation exchange' clearly states the verb and resource. It then breaks down three distinct acts (issue, assert, respond) with specific purposes, distinguishing itself from sibling tools like create_agreement or verify_mandate.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit preconditions: each act must carry a decision obtained from verify_mandate, and identifies required fields per act. It also explains when each act applies (issue derives from agreement, assert follows performance, respond accepts/rejects). However, it does not explicitly mention when not to use this tool or contrast with sibling alternatives like issue_approval, so it stops short of full alternatives coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_evidenceVerify a record against the published procedureA
Read-onlyIdempotent

Run the seven-step verification procedure over a set of objects: content hashes, signatures and the purpose each was issued for, version chains, event-chain continuity, guarded transitions replayed against the rules version in force, whether each determination follows from its rules, and what could not be checked. Use it on your own record before relying on it, and on anything a counterparty sends you.

Pass transaction_id to verify this server's record of one transaction, object_ids to verify part of it, or objects to verify a bundle somebody handed you.

Every check returns verified, failed, or not_checkable, and the result carries no overall boolean, because a report reduced to one discards what could not be checked. A signature whose key you do not hold is not checkable and is never thereby verified. Without rules_version, guarded transitions are not checkable rather than verified: an unresolvable rule set is not permission in either direction.

ParametersJSON Schema
NameRequiredDescriptionDefault
objectsNoObjects presented by value, for example a bundle a counterparty sent.
object_idsNoIdentifiers of objects this server holds.
rules_versionNoThe rule set version in force when the record appended, for example 1.3. A record replays against the version it was written under, never the current one.
transaction_idNoVerify every object this server holds for one transaction.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds critical behavioral detail beyond the read-only/idempotent annotations: every check returns verified, failed, or not_checkable; there is no overall boolean because it would mask non-checkable results; a signature with an unheld key is not checkable and never verified; missing rules_version makes guarded transitions not_checkable rather than verified. These are non-obvious semantics the annotations do not convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence earns its place: first sentence defines the procedure, second gives usage context, third maps input modes to usage, and the final two sentences disclose edge-case behaviors. Perfectly front-loaded and free of fluff.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Despite having no output schema, the description explains the per-check outcomes, the intentional omission of an overall boolean, and the conditional behavior of guarded transitions based on rules_version. For a complex seven-step verification tool, this provides a complete mental model without needing to inspect additional structured fields.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema already covers all four parameters, so baseline is 3. The description adds value by clarifying the selection semantics: transaction_id verifies 'this server's record of one transaction,' object_ids verifies 'part of it,' and objects verifies 'a bundle somebody handed you.' It also explains the rules_version parameter's effect on guarded transitions. This goes beyond the schema's literal field definitions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Run the seven-step verification procedure over a set of objects,' then enumerates the seven steps (content hashes, signatures, purpose, version chains, event-chain continuity, guarded transitions, determination follow-through, and non-checkable items). This clearly distinguishes it from sibling verify_mandate, which has a different object of verification.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs when to use the tool: 'Use it on your own record before relying on it, and on anything a counterparty sends you.' It also maps input modes to scenarios: transaction_id for the server's record, object_ids for partial records, and objects for counterparty-supplied bundles. This gives clear, actionable guidance on selecting the right input.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

verify_mandateVerify a mandate and decide on an actA
Read-onlyIdempotent

Check a mandate and decide whether an act is permitted under it. Call this before every act, on your own mandate or on one a counterparty presented.

It checks the document against the published schema and the rules the schema cannot express, verifies the issuer signature, checks the validity interval, and, when proposed_action is given, checks the act against the mandate's actions, its four scope axes, its constraints in stable order, and its approval rules.

Returns one decision, allow, deny, or require_approval, with the registered reason codes behind it, the per-constraint outcomes, and action_hash, the hash of the exact act evaluated.

On require_approval: pass that action_hash to issue_approval, then call this tool again with the returned approval_id and the identical proposed_action. The decision becomes allow. A deny is never approvable.

This server makes no network call. Resolve the mandate's status_endpoint yourself and pass the result as status. An absent result, one older than 60 seconds, or any status other than active denies with A202-MANDATE-STATUS-UNRESOLVED or A202-MANDATE-INACTIVE: unavailability is not permission.

ParametersJSON Schema
NameRequiredDescriptionDefault
atNoRFC 3339 instant to check against. Defaults to now.
statusNoWhat you retrieved from the mandate's status endpoint, and when. Omit it and the decision is deny.
mandateNoThe mandate document, when it came from a counterparty.
approvalNoAn approval object presented directly, instead of approval_id.
mandate_idNoA mandate this server holds, as returned by issue_mandate.
approval_idNoAn approval this server holds, from issue_approval, that releases a require_approval hold.
proposed_actionNoThe act to evaluate against the mandate. Constraint paths address this document from $, so a spending limit reads $.proposed_terms.core.total.amount.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, but the description adds substantial behavioral context: no network call is made, status handling rules (older than 60 seconds counts as no result), deny is never approvable, and the exact checks performed. This goes well beyond the annotations with no contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but every sentence earns its place, covering purpose, checks, return values, approval flow, and status constraints in a logical structure. It is front-loaded with the core purpose and contains no redundant or filler content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity (7 params, nested objects, no output schema), the description fully covers what the tool does, what it returns (decision, reason codes, per-constraint outcomes, action_hash), and the approval workflow. It even notes the 'unavailability is not permission' edge case, making it complete for an agent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although schema coverage is 100%, the description adds meaningful context: it explains the relationship between mandate and mandate_id, defines the required status object semantics, clarifies that proposed_action paths address from $, and describes the action_hash/approval_id flow. This significantly enriches the bare schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Check a mandate and decide whether an act is permitted under it.' It clearly distinguishes itself from sibling tools by focusing on mandate verification and decision, and explicitly says 'Call this before every act' and covers both own and counterparty mandates.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit when-to-use guidance: 'Call this before every act.' Also explains the require_approval flow with issue_approval and re-invocation, and describes how to handle status endpoints. It clearly delineates the alternative paths (mandate vs mandate_id) without needing to mention every sibling.

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. Dates show when Glama detected each change.

  1. 7 tool updatesv0.1.0
    • First observedcreate_agreement
    • First observedget_transaction_record
    • First observedissue_approval
    • First observedissue_mandate
    • First observedrecord_obligation
    • First observedverify_evidence
    • First observedverify_mandate

TDQS

A4.6/5.0
Disambiguation5/5

Each tool addresses a distinct phase of the transaction lifecycle: issuing/verifying mandates, approving specific acts, forming agreements, recording obligation states, retrieving transaction records, and verifying evidence. The descriptions clearly separate these concerns, with no apparent overlap or ambiguity in purpose.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (issue_mandate, verify_mandate, create_agreement, record_obligation, get_transaction_record, verify_evidence, issue_approval). The verbs and nouns are descriptive and match the tool's function, making the API predictable.

Tool Count5/5

With 7 tools, the server is well-scoped for its purpose of managing commercial mandates, agreements, and obligations. Each tool has a clear and necessary role in the workflow, and the count is neither too sparse nor overwhelming.

Completeness4/5

The core lifecycle is covered: mandate issuance, verification, approval, agreement creation, obligation recording, and evidence verification. However, there is no tool for updating or revoking a mandate, and no explicit final settlement step after acceptance_pending, which are minor gaps that could be worked around but may cause dead ends in some scenarios.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    MCP server that gives AI agents the ability to discover, match with, and build relationships with other autonomous agents. Supports agent registration, matchmaking, messaging, shared goals, relationship lifecycle management, and real-time event subscriptions.
    50
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    MCP server for Pact, an escrow protocol for agent-to-agent commerce, enabling agents to create pacts, fund escrow, deliver work, and settle with an LLM evaluator as dispute backstop.
    17
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides a sovereign, MIT-licensed MCP server for professional-service workflows, running entirely on your infrastructure with Ed25519 cryptographic signing for every action.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A sovereign, MIT-licensed MCP server for professional-service workflow tools that runs on your infrastructure with Ed25519 signing, enabling autonomous agents to discover and invoke tools securely.
    MIT

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/a202-protocol/a202'

If you have feedback or need assistance with the MCP directory API, please join our Discord server