MCP tools reference
The Amnetic marketplace exposes up to 40 MCP tools over the Model Context Protocol. This is the single authoritative list of what each tool takes and returns; the per-client connection config lives on Connect your agent, and the get-connected-fast path on Connect your MCP client.
All supported Claude models run through AWS Bedrock.
The 15 core tools are always registered — none is behind a feature flag. The
further groups register only behind a feature flag; where the flag is off they
are simply absent from tools/list and calling them is a not-found
(404-by-absence), never a disabled stub:
- the six buyer-posting request tools (
create_request_draft,list_my_requests,respond_request,list_open_requests, and the seller-writesubmit_request_candidateandpost_request_quote) register only whereBUYER_POSTING_ENABLEDis on; - seller-authored license-offer tools are removed while policy authoring moves to the replacement terms workflow;
- the two seller slice-policy tools (
set_slice_policy,get_slice_policy) register only whereSLICE_ON_DEMAND_ENABLEDis on. - the buyer Verify and Report tools register only where
CONSIGN_ENFORCER_ENABLEDis on. - the four seller derived-listing tools (
create_derived_listing,stage_derived_artifact,list_pending_signoffs,get_signoff_item) register only whereDERIVED_LISTINGS_ENABLEDis on. They are enabled in production; they are absent fromtools/listonly if that recovery kill-switch is off. - Pending SAT deliverable replacement is a human-seller REST-only flow. There is no replacement MCP tool; Seller's Agent tools cannot upload, cancel, or approve a replacement candidate.
- the SAT catalog, thread, Spec, approval-bundle, and seller-task tools register
only where
SELLER_TXN_ENABLEDis on. They are enabled in production; 404/absent only if that recovery kill-switch is off (.github/workflows/flag-rollout.yml).
With all feature flags enabled there are 40 tools in the roster below; the
same account can use the ordinary buyer/seller tools, while SAT's hosted
seller-front and seller-worker tools remain scoped and register only where
SELLER_TXN_ENABLED is on (production-on; kill-switch recovery only).
Authentication is transport-level
You authenticate once, on the transport — your amn_… API key travels as
Authorization: Bearer amn_… when the connection is established (or, for the
claude.ai browser connector, as a Cognito OAuth login). The key is never a
tool argument — it stays out of your agent's model context and out of tool-call
transcripts. The server refuses to start without an authenticator; there is no
open/anonymous mode. See Authentication.
Every response has two halves
Each tool answers with both an MCP content text block and a
structuredContent object. structuredContent is the machine-readable one, and
it always carries every documented field. The text block is a human- and
model-readable summary of the same answer — many MCP clients surface only that
half to the model, so it is written to be useful on its own: it names the
identifiers and the state, never a bare count.
For the list tools that means one line per row:
you have published 23 listing(s); this page has 20 (offset 0):
- listing 0f2a… ("Q3 Telemetry") is active; the public catalog serves it
- listing 7c11… ("Raw Logs") is active; the public catalog does NOT serve it yet (pending_publication)
A list names at most 20 rows and then says how many more the page held; the
page is complete in structuredContent either way, so read that when you need
every field — the text block carries the identifiers and the state, not every
timestamp and amount.
Counts in the text block say what they are. list_my_listings is the only list
that reports a genuine total; the others describe this page, and a page
that came back full says so rather than letting a page size read as a total.
Endpoints
The MCP server lives on the same host, port (443), and TLS certificate as
the REST API. It speaks two transports so every client can use streamable HTTP,
with SSE retained for legacy clients:
| Transport | Path | Clients |
|---|---|---|
| Streamable HTTP (recommended) | https://market.amnetic.ai/mcp |
Claude Code, Cursor, the claude.ai browser connector, ChatGPT, amnetic solution CLI, and generic MCP clients |
| HTTP + SSE (legacy fallback) | https://market.amnetic.ai/sse |
Older SDK-only clients that do not yet speak streamable HTTP |
Buyer tools (12)
enter_market
Hand your working context into the wall and get a buy recommendation. Free and read-only — it buys nothing.
| Param | Required | Meaning |
|---|---|---|
messages |
yes | Your working conversation as a standard chat stream (roles system | user | assistant). Must include at least one user message. |
llm_model |
no | The LLM the inner agent runs on. Must exactly match a supported Claude model ID such as claude-opus-4-6 (the default), claude-sonnet-4-6, or claude-haiku-4-5. All models run through AWS Bedrock. |
image_id |
no | The inner-agent image — a human-readable slug (e.g. code_solutions) or the raw sha256 from list_images. Defaults to the platform default. |
required_rights |
no | Buyer-declared minimum license rights, as a closed enum-only object. Request any subset of use, redistribution_scope, derived_display, training, training_serve, training_weights, term, and attribution; omitted dimensions mean “don't care.” Omitted, null, and {} all leave rights-fit inactive. This field is absent from tools/list while the counsel-gated licensing capability is dark. |
The request vocabulary is closed: use is non_commercial|commercial;
redistribution_scope is individual|entity|entity_affiliates;
derived_display is none|public; training is none|internal;
training_serve and training_weights are independently none|allowed;
term is 12|24|36|perpetual; and attribution is
required|not_required. exclusivity is not requestable. Unknown properties or
values are rejected before a market session starts.
Returns decision ("buy" or "no_match"), recommended_listings[] (each with
public catalog metadata: listing_id, document_type, title, description,
category, price_cents, currency, optional seller_name, data_format,
data_size_bytes, tags, status, created_at, updated_at, and an optional
trust band). Each recommendation also has a non-empty materialized
pre-purchase menu[]; every rung carries its immutable offer_id, offer_key,
price, and currency. This metadata is not operative license text, a grant, or
acceptance. When a non-empty
required_rights object is accepted, every recommendation additionally carries
platform-computed rights_fit: band is fit, partial, no_fit, or
unknown, and best_offer appears only for fit. Its
{offer_id, offer_key, price_cents, currency} is the normalized selector for
the selected visible quote. The base rung is materialized just like every other
menu rung; there is no synthesized null-id standard tier.
This is mechanical buyer-parameterized comparison,
not a legal interpretation, permission, warranty, reservation, or grant.
That exact-text read surface is not part of this phase, so do not treat the enum
metadata as the operative terms or purchase from it alone. The
response also includes recommended_total_cents and, on no-match, optional
gap_report.unmet[] class values. Gap classes are closed vocabulary
(coverage, freshness, granularity, format, price, trust, rights) and carry no
notes or prose. No raw seller id, document body, data_ref, data_dictionary,
inner-agent reason, confidence score, or other free-form inner-agent prose
crosses the wall.
While evaluating candidates inside the market, the forgetful buyer agent's
get_listing response includes a non-empty top-level menu array. In the
current slice it contains the one materialized base rung; each entry carries
offer_key, the fully materialized enum-only terms, price_cents, listing
currency, and its immutable offer_id. The platform attaches that same
always-on menu to the outer recommendation after the wall returns only listing
ids. The data is read from current platform listing/offer rows — never authored
by the inner agent.
After reviewing the operative terms through an available exact-text surface,
echo the selected tier's offer_id into an explicit purchase call; the
recommendation itself is read-only and neither grants rights nor records
acceptance.
With required_rights omitted, null, or {}, recommended_total_cents
retains its historical meaning: the sum of the recommendations' top-level
standard price_cents (and an all-zero total may remain omitted). With a
non-empty requirement, it is instead the sum of each fit row's current
best_offer.price_cents; partial/no-fit/unknown rows contribute zero, and the
field is emitted explicitly even when the active sum is 0. Either total is
advisory snapshot arithmetic, not a checkout amount or settlement promise.
To act on a fit, review the operative exact text, then echo
rights_fit.best_offer.offer_id into purchase. Purchase
re-resolves current state; only its minted grant is license evidence. If an
asynchronous card quote drifts after payment, fulfillment may finish
funded_only: the payment remains spendable, nonwithdrawable wallet credit and
no license grant is minted.
A seller account's own listings are excluded from that same account's
enter_market recommendations and in-wall listing reads. Settlement also refuses
self-purchase, so this filter is defense in depth and not the money-path guard.
Daily enter_market session quota is consumed only when the final response is
decision: "buy" and recommended_listings contains at least one listing.
no_match, rejected requests, setup failures, timeouts, and platform faults do
not consume the daily session quota, although concurrency limits still apply
while a session is running.
Tool errors are sanitized. When available, branch on structured error_code
instead of parsing text. Public codes include auth_failed,
invalid_request, unsupported_model, unknown_image,
insufficient_credit, no_candidates, balance_unavailable, rate_limited,
buyer_context_invalid, agent_artifact_invalid, sandbox_unavailable,
budget_exhausted, buyer_cancelled, platform_terminated, and
platform_error. Error responses never include seller body content,
inner-agent prose, raw stream details, stack traces, bearer tokens, presigned
URLs, or other platform internals. Some errors include a debug_id you can
share with support.
The examination-ceiling N, suggestion-budget B, and session timeout are platform-set defaults, not parameters of this tool. Tuning them is an advanced REST/SDK concern (see the API reference).
purchase
Buy listings. The debit is atomic (all-or-nothing). A successful response
confirms ownership and returns listing metadata; retrieve bytes with
ownership_download.
By default the MCP tool uses wallet credit and can buy a bundle atomically. It
also accepts funding_mode: "card" for a single
listing; card mode usually returns a hosted Stripe checkout_url and settles
asynchronously after payment. Card mode accepts the same offer-aware selectors
as wallet (offer_id, renew_of_grant_id), so a card-funded buyer uses the
same exact offer binding.
| Param | Required | Meaning |
|---|---|---|
items |
yes | Purchase items: {listing_id, offer_id, renew_of_grant_id?}. Use the materialized offer id returned by the listing/menu read. Send exactly one item or more for an atomic wallet bundle; card modes require one item. |
funding_mode |
no | wallet (default) or card. Card modes require exactly one item/listing and usually return checkout metadata instead of immediate ownership. |
Returns purchases[] (each with listing_id, seller_id, title,
price_cents, data_format, data_size_bytes, outcome, offer_id,
offer_key, terms_hash, and grant_id), total_cents, and
balance_cents_after for wallet purchases. Card-mode responses include
payment_method, funding_mode, status, checkout_url, session_id,
amount_cents, funded_cents, and wallet_applied_cents (the wallet amount
planned at checkout creation, rechecked at settlement). outcome is
purchased or already_licensed; skipped items are returned instead of silently
omitted. If the balance can't cover a wallet order, nothing is purchased and
nothing is debited.
Offer-level refusals return structured error_code, listing_id, and detail
fields: offer_unavailable, price_changed, or renewal_invalid.
offer_unavailable.detail.live_offers includes replacement offers with terms,
terms schema version, DLS version, and price.
Eligibility is an account setting, not a purchase argument. Some offers are
sold only to buyers in certain annual revenue bands. Declare your band once
with declare_representation ({"operand": "annual_revenue_band", "value": "under_1m" | "1m_10m" | "over_10m"}), or in the portal under Account →
Eligibility; check it with get_party. Every purchase uses that standing
declaration, and the signed Agreement records it. A band-restricted offer
refuses representation_required until you have declared one, and ineligible
(with detail.declared and detail.allowed) when your band isn't allowed; an
offer for legal entities refuses party_required until declare_party records
your entity. purchase has no representations argument, and the schema
rejects one.
Original-file uploads must pass the required malware scan before purchase.
Scanning covers the first 2,000,000,000 bytes (the whole file if smaller), and
scan_coverage discloses any unscanned remainder; the full-file digest is still
verified. Use stage_artifact followed by create_listing with
staged_artifact: {"stage_id": "…"} for file creation, or purpose
listing_replace followed by replace_listing_artifact for versioned replacement.
Multipart stages use presign_artifact_parts, complete_artifact_upload, and
abort_artifact_upload; completing an upload alone does not publish it.
Files that fail required scanning are reported as unavailable and no debit occurs.
ownership_list
No arguments. Lists every listing your account already owns (with title, description, the price you paid, and when you acquired it).
Each owned listing also carries a license block recording
the license evidence you hold:
{ "newest": {…grant…}, "grants": [ …newest-first history… ] }for a listing you hold a recorded grant on. Each grant view carriesgrant_id,offer_key,terms,terms_schema_version,dls_version,granted_at, and — for grants governed by the ToS draft —instrument_status: "pre_ratification". The grant view is token free (proof of what you hold, never a handle to buy again).{ "implied": true }for a listing you own with no recorded grant — the implied standard-license display convention (no grant row is synthesized).
The block is omitted entirely where the flag is off, so the wire is unchanged on the dark path.
ownership_download
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | A listing you own. |
format |
no | csv, parquet or xlsx. Omit for the listing's canonical bytes. |
Returns a short-lived presigned GET URL, plus data_format and
data_size_bytes. For text/plain payloads up to 256 KiB, the response also
includes body inline so MCP clients that cannot fetch arbitrary URLs still have
a one-call byte path. Refuses anything your account hasn't bought, or any
arbitrary uploaded file whose latest malware scan is not clean.
The handle is built for large objects, and is re-mintable: if the URL expires
part-way through a transfer, call the tool again and resume from where you
stopped with an HTTP Range request.
| Field | Meaning |
|---|---|
expires_at |
When download_url stops working. Read this instead of assuming a lifetime — operators set it with OWNERSHIP_DOWNLOAD_URL_TTL (default 20 minutes). |
served_content_type |
The media type of the exact object being served. data_format is the listing's catalog format, so the two differ whenever you select a format — a CSV original of a canonical-parquet listing reports text/csv here and the parquet media type there. |
total_size_bytes |
The size of the exact object being served, measured when the URL was signed. Plan the transfer against this, not data_size_bytes (the listing's advertised catalog size, which can differ if the listing changed after you bought it). |
sha256 |
Raw-byte checksum of the served object, present only when the platform can prove it describes those exact bytes. Absent is normal. |
recommended_part_size_bytes |
A good chunk size for a parallel or resumed fetch, when the object was uploaded in parts. |
resumable |
true when calling again is cheap and returns the same bytes. false means the listing is delivery-enforced: every call mints a brand-new signed bundle behind a rate limiter, so use the URL you were given and do not poll for a fresh one. |
matches_evaluated_pin |
Present only if you have a released evaluation of this listing. true only when the platform confirmed the exact object it is serving and its checksum equals the evaluation's pinned_artifact_sha256. false otherwise. |
evaluated_pin |
Which evaluation you were compared against (evaluation_id, pinned_artifact_sha256) and a status. match: confirmed, same bytes. changed: the listing changed after your evaluation. unverified: the platform could not confirm which bytes it is serving, so treat these bytes as unverified against your evaluation and check sha256 yourself. |
Omitting format returns the listing's canonical owned artifact, and is the only
form that can carry an inline body. The same menu is available over REST, via
GET /api/v1/ownership/{listingId}/download?format=parquet|xlsx|csv.
For a derived child, the menu is resolved from the child's recorded
derivation artifacts, so it covers a platform-created slice child and an
agent-derived listing alike. An agent-derived listing's canonical bytes are the
file its worker staged, in that file's own format (a csv stays a csv, an xlsx
stays an xlsx); csv or xlsx names that file explicitly, and parquet serves
the parquet copy the platform keeps beside a csv or single-sheet xlsx. (A child
created before this rule has the converted parquet as its canonical bytes and the
staged file as its csv/xlsx form.)
For an ordinary listing there are no such records, and csv is the one
selector still answerable: a listing ingested from a CSV keeps that original
beside the parquet it was converted into, and the platform serves it only after
confirming the object exists and is stored as text/csv. Use it whenever you are
going to process rows — the canonical bytes are parquet, which needs a parquet
reader. Anything else is unavailable in that format — an xlsx-ingested listing, a
listing that predates the retained original, any other format on an ordinary
listing, and any listing whose dataset the seller has since replaced (the
retained original describes the superseded bytes, so it is withheld from
everyone, the seller included). The call fails with format_unavailable, and
the fallback is to call again with no format.
Owners may download their own listings. In addition to your purchases, this
tool serves a listing whose seller is your own account even without a purchase
grant — so a Seller's Agent can fetch the parent it derives from. The owner serve
is scan-gated exactly like a buyer download (a listing whose latest scan is not
clean is refused), and it never routes through delivery marking. ownership_list,
by contrast, enumerates only your purchases; enumerate your own listings with
list_my_listings.
For listings with delivery enforcement enabled (CONSIGN_ENFORCER_ENABLED, dark by
default and pending counsel), the URL points at a signed per-delivery bundle and
no inline body is returned; if the marked bundle cannot be produced the tool fails
with a retriable materialization_unavailable error rather than serving the
plain object. Fixed-window quota exhaustion instead returns the stable retriable
materialization_rate_limited tool error. Admission happens before source
download or delivery-ID creation; failed admitted attempts remain charged and an
admitted retry always creates a fresh bundle. When enforcement is off the behavior
is exactly as above. The forensic-marker disclosure
(GET/POST /api/v1/consign/disclosure-acceptance) is a separate Cognito-only
REST act and is not an MCP tool; missing it does not change this download
acknowledgment, and canary-bearing delivery is gated in code later.
balance
No arguments. Returns your read-only credit balance in cents (e.g.
{ "balance_cents": 4200, "currency": "USD" }). There is no MCP top-up —
fund your account in the portal.
list_images
No arguments. Lists the inner-agent images selectable via enter_market's
image_id — each with an image_id, slug, name, description, and
default: true for the one used when you omit image_id.
purchase_status
| Param | Required | Meaning |
|---|---|---|
purchase_id |
yes | The UUID of one of your own purchase transactions. |
Buyer-scoped read. Returns listing_id, status, amount_cents, currency,
created_at, and completed_at. A transaction owned by another buyer is
reported not-found (no 403, so you can't enumerate other buyers' IDs).
The response also carries offer_key and terms_hash — the
licensing tier you purchased and the hash of its composed terms — for a
transaction that minted a license grant.
verify
Look up one record from a licensed Consign delivery. Available only where
CONSIGN_ENFORCER_ENABLED is on. The arguments object is closed: both fields
below are required and unknown properties are rejected.
| Param | Required | Meaning |
|---|---|---|
record_ref |
yes | The exact AMN1-… support handle carried by your delivered artifact. |
record_key |
yes | The unpadded base64url canonical key derived from the delivered Parquet row's ordered primary-key fields. See the API reference's v1 byte grammar and golden vector; once derived, treat it as an indivisible token. |
A found result is exactly:
{ "record_key": "opaque-token", "fields": { "COLA": "Palyt" } }
The response never says whether the row came from the seller's authoritative
data or a disclosed synthetic Consign record. The platform first resolves the
authenticated account to the owned delivery, an unexpired license grant, its
effective rotation cycle, and a ready content generation. Invalid, absent,
expired, and foreign selectors all produce the same not-found tool error;
dependency, collision, audit-append, and unwarmed-cycle failures produce
verify unavailable. Every resolved attempt is appended to the compliance
ledger before release.
MCP and REST serialize the same validated fields object losslessly; integers
larger than JavaScript's safe-integer range and precise JSON decimal lexemes are
never coerced through a binary floating-point map by the server. JSON object
member order is not significant and may differ between transports.
One server-configured absolute deadline is the response ceiling: warm work returns immediately and unfinished work fails unavailable at the boundary. Canary values are decrypted only when a rotation cycle enters the process-local warm overlay, never during a Verify call; the deployment gate statistically compares authoritative and canary warm-path latency. Do not send account, delivery, license, listing, source, or origin fields: none is part of the tool schema.
report
Report a questionable record from a licensed Consign delivery without receiving
a validity verdict or correction. Available only where
CONSIGN_ENFORCER_ENABLED is on.
| Param | Required for admission | Meaning |
|---|---|---|
record_ref |
yes | The exact AMN1-… support handle carried by the delivered artifact. The platform resolves it only through your authenticated account's delivery ledger. |
record_key |
yes | The opaque key of the record being reported. |
where_encountered |
no | Where you encountered the record, such as an exported customer file. This confession field is encrypted before durable storage. |
The tool deliberately advertises a permissive arguments-object schema: missing,
unknown, and wrong-typed values all reach the no-verdict handler. Every
syntactically valid authenticated report call returns the same non-error result:
{ "status": "Logged. Under review with the data provider." }
That response does not confirm that the RecordRef, record key, delivery, or
account relationship exists, and it is not proof that a report row committed.
Account, delivery, license, and listing IDs are never accepted as tool arguments;
they are derived server-side from transport authentication and the owner-scoped
delivery ledger. RecordRefs are high-entropy, unguessable support handles in
addition to being owner-scoped. The invariant covers the MCP result bytes and
non-error status, not processing-time distributions: an admissible report may
synchronously perform KMS encryption and a durable database commit, so Report
does not claim timing secrecy. Malformed JSON-RPC, a different tool name,
non-object arguments, or a transport body over the listener's request-body cap
is rejected before the Report callback and remains outside the Report contract.
That cap is applied after transport authentication — an unauthenticated
request is refused on its credential without its body being read — and is 1 MiB
for the ordinary tool surface, raised to 32 MiB only on a deployment that enables
the inline-artifact intake of create_derived_listing.
create_request_draft
Draft a buyer request — a public ask for information sellers can compete to
fill. Available only where BUYER_POSTING_ENABLED is on. Creating a draft
moves no money and posts nothing; the escrow bounty is reserved later, at
sign-off, which is a portal-only human approval (see the gaps below).
| Param | Required | Meaning |
|---|---|---|
title |
yes | Public one-line title of the request. |
body |
yes | Public description of the data/analysis you need. |
bounty_micro_usd |
yes | Escrow bounty in micro-USD (1 USD = 1,000,000 micro; e.g. 250000000 = $250). Must be positive. Reserved at sign-off, not on draft creation. |
expires_at |
yes | RFC-3339 timestamp; must be in the future. |
category |
no | Free-form category label. |
tags |
no | JSON array of discovery tags (e.g. ["finance","weekly"]). |
hints |
no | JSON object of structured hints about the shape of data you want. |
attribution |
no | named (default) or pseudonymous. |
acl_mode |
no | open (default) or allow (only the named access groups may see it). |
acl_group_ids |
no | Access-group IDs the request is visible to; required when acl_mode is allow (must be groups you own). |
Returns the new request_id, state ("draft"), bounty_micro_usd,
expires_at, attribution, acl_mode, and created_at.
list_my_requests
List your own requests and their current state. Available only where
BUYER_POSTING_ENABLED is on.
| Param | Required | Meaning |
|---|---|---|
limit |
no | Max requests to return (default 50). |
offset |
no | Requests to skip, for pagination (default 0). |
Returns your requests — each with request_id, title, state, category,
bounty_micro_usd, expires_at, attribution, signed_off_at (when signed
off), and created_at. The content text block names one request per line with
its id, title, state, bounty, and expiry. Its count is this page's, not a
total — this list has no total — and a full page says so, so raise offset to
read the rest.
respond_request
Act on a candidate that has passed evaluation on one of your own
requests. Available only where BUYER_POSTING_ENABLED is on.
| Param | Required | Meaning |
|---|---|---|
request_id |
yes | One of your own requests (from list_my_requests). |
candidate_id |
for confirm / decline |
The candidate to act on — one that has passed evaluation on that request. |
quote_id |
for commit |
The seller's quote to commit to. |
action |
yes | confirm to settle the fill, decline to pass on the candidate, or commit to accept a seller's above-bounty quote. |
action=confirm settles the fill. A normal pass atomically releases your
escrow bounty and buys the candidate's listing at the price captured when the
seller submitted it — never a later, higher price — and closes the request. If
the seller changed the listing price (or the listing is no longer available), the
confirm is rejected and the candidate is voided; if the captured price is above
your bounty, you must have enough spendable credit to cover the difference (top
up and retry otherwise). action=decline passes on a normal candidate and keeps
the request open for others — no money moves. A normal passed candidate
remains confirmable for 72 hours from the platform-recorded pass time. At the
exact deadline it lapses; a late confirm cannot charge, and a late decline
records and returns that same lapsed outcome.
action=commit accepts a seller's quote — a bespoke, above-bounty price the
seller offered (pass quote_id instead of candidate_id). It earmarks the
top-up (the amount above your bounty) in escrow and reserves the seller's
exclusive fill window so no one else can fill the request while they produce the
work. It settles nothing yet — the purchase happens automatically at the
quoted amount when the seller delivers. You must have enough spendable credit
to cover the top-up; a quote at or under your bounty is rejected. Committing moves
no request state (it stays open). If the seller never delivers, the commitment
lapses when the window elapses and the top-up is released back to your bounty.
If the seller's pass was durably recorded inside the commitment window
(including either exact boundary), the automatic fill remains recoverable after
the wall-clock window—even after a platform restart. That qualifying pass has
earned settlement at the quoted amount: it cannot be declined or lapsed, and
an explicit confirm routes through the same quote-settlement path. Only a
commitment with no such earned pass lapses. Quote lapse releases only the quote
top-up; the base bounty stays reserved until the request fills or finally
expires.
Returns the request_state (e.g. filled after a confirm, open after a
commit), the resulting candidate_state (confirmed / declined / lapsed) or
quote_state (committed), and — on a settled confirm — the
fill_transaction_id. A request, candidate, or quote that is not yours reads as
an opaque "request not found".
The unattended fill (the automatic purchase when a committed seller delivers) and the lapse of an expired commitment are platform/worker transitions with no tool or REST route.
At the request deadline, a request with no evaluation or committed quote in
flight becomes expired and releases its base bounty. A request with in-flight
work becomes closing: new responses stop, existing work may settle, and the
base bounty is released only if the final in-flight item ends without a fill.
Seller tools (19)
Seller identity always comes from the authenticated session — never a parameter.
seller_readiness
Call this first when planning seller work. Some preconditions belong to your account, not to any one listing — payout
onboarding, and the one-time legal acceptances. They are cheap to check and
expensive to discover the hard way: without a readiness read, an agent learns them
only by sending a real write and reading the refusal, and a create_derived_listing
refusal costs a full round trip carrying the entire artifact.
seller_readiness takes no arguments and is read-only and free. It reports one
row per account-level precondition this deployment actually has — a gate that is
not enabled here produces no row at all, rather than a misleading true.
| Field | Meaning |
|---|---|
ready |
true only when checks is non-empty and every row in it is ready. A false does not mean nothing can be done — read the rows. An empty checks reports false: nothing was measured, so nothing is asserted. |
checks[].check |
Stable id to branch on: payout_onboarding, derivation_authorization, slice_authorization. |
checks[].ready |
The verdict from the same predicate the corresponding write runs. |
checks[].detail |
The fact and, when not ready, its consequence. |
checks[].remedy |
What to do about it. Present only when ready is false. |
checks[].gated_tools |
The tools this precondition gates, so you can tell whether a failing row is relevant to what you are planning. |
The rows you may see:
payout_onboarding— whether this account can sell priced listings. When it is not ready,create_listingstill accepts a priced listing but holds it as an unpublished draft, andcreate_derived_listingrefuses a priced child outright. A $0 listing is unaffected. Where slice-on-demand is enabled it also gates the slice rail, and one of those gates is silent: creating a seller segment is refused, and your listings are left out of the buyer slice catalog with no error at all — so a slice policy you write successfully can simply produce no catalog entries. Remedy: complete Stripe Connect payout onboarding in the portal — it is not an MCP capability. Listings already held as drafts publish automatically once onboarding completes.derivation_authorization— whether this account has accepted the current Derivation Authorization. Present only where derived listings are enabled.slice_authorization— whether this account has accepted the current Slice Authorization rider. Present only where slice-on-demand is enabled.
Both acceptances are one-time human acts on the authenticated REST edge with your own Cognito session; an agent API key structurally cannot perform them, and there is no MCP tool for either — see What has no MCP tool at the end of this page. An acceptance of a version that has since been superseded reads the same as never having accepted.
seller_readiness is account-scoped only — it says nothing about any individual
listing. For a listing's publication state use
get_my_listing; the two answer different questions and are
deliberately not merged.
Reading your own listing's publication state
Every seller-facing read reports two different things, and confusing them is the single most common source of "my listing exists but nothing works":
statusanswers what you asked for:activemeans you published it (or it was accepted),inactivemeans you retired it, and so on. It is deliberately coarse — the platform never exposes its internal processing states here.public_visibilityanswers whether the public catalog serves it right now. It is an object{ "visible": bool, "reason": string }wherereasonis one ofvisible,not_active,restricted_access, orpending_publication.
status: "active" does NOT mean the listing is live in the public catalog.
A freshly created listing is normally {"visible": false, "reason": "pending_publication"} for a short period while it is processed. Gate anything
that genuinely depends on publication — sharing a public link, expecting the
listing to appear in catalog search — on public_visibility.visible, never on
status.
public_visibility answers publication, and only publication. It is not a
general-purpose eligibility check: other operations have their own preconditions
that it does not measure. In particular, create_derived_listing does not
require a publicly visible parent — see its Parent eligibility note below.
The reason is intentionally coarse and never explains a platform decision:
pending_publication covers every "not published yet" cause identically.
restricted_access means you set a non-open purchase ACL. If
public_visibility is absent from a response, the check was unavailable —
treat that as unknown, not as hidden.
public_visibility appears on list_my_listings, get_my_listing,
create_listing, and update_listing, and on the equivalent REST seller
endpoints (see the API reference and Selling data pages).
create_listing
List a document for sale (text/markdown body only).
| Param | Required | Meaning |
|---|---|---|
title |
yes | Public catalog title (≤200 chars). |
body |
yes | The full document content for sale (≤200000 bytes). Never shown pre-purchase. |
price_cents |
yes | Price in whole US cents. Open-market listings must be from 1 cent through $1,000,000. |
description |
no | Public catalog description (defaults to the title). |
currency |
no | 3-letter ISO-4217 code (defaults to usd). |
category |
no | Free-form category label (≤64 chars). |
document_type |
no | Free-form discriminator (the server does not branch on it). |
tags |
no | Up to 32 discovery tags, each ≤64 characters. |
purchase_acl_mode |
no | open (default) | allow | deny. A restricted listing may be priced at $0. |
purchase_acl_groups |
no | Named access-group IDs you own; used by allow/deny. |
Returns the new listing_id, status, created_at, and public_visibility.
status: "active" means the listing was accepted, not that the public catalog
serves it — read public_visibility.visible for that. A newly created listing
is normally pending_publication for a short period, and
create_derived_listing will refuse it as a parent
while it is still processing, so poll get_my_listing rather
than retrying the derivation blindly. Document body only — there is no file or
CSV/XLSX/parquet dataset upload path here (see the honest gaps below).
update_listing
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own listings. |
title / description / category / tags / status |
no | The fields you pass are updated (status is active or inactive). For a sidecar-less agent-derived child, the only permitted effective update is the one-way retirement {status: "inactive"} with no other non-null update field; it cannot be reactivated. tags is bounded the same way as on create: up to 32 entries, each ≤64 characters. |
Returns the updated listing_id, status, updated_at, and
public_visibility. As on create, status: "active" in the response means the
edit was accepted, not that the public catalog serves the listing — an edit to a
listing's content re-runs processing, so the listing can be accepted as active
and be {"visible": false, "reason": "pending_publication"} at the same moment.
Read public_visibility.visible, or poll get_my_listing.
Derived children remain immutable marketplace artifacts. A sidecar-less
agent-derived listing staged with create_derived_listing has one lifecycle-only
exception: its seller may retire it by passing only status: "inactive".
Retirement removes it from the sign-off queue and buyer surfaces and stops future
purchases, but does not change or delete its content, economics, ACL, offers,
sign-off history, or a prior buyer's ownership and download rights. It is one-way
in this release: status: "active", a mixed retirement-plus-edit request, and
every other edit are refused with "derived listing is frozen" (the REST edge
returns 409 platform_slice_frozen). Platform-created slice children do not use
this exception; retire an unsold slice child through its dedicated lifecycle.
Published multi-sheet workbook roots and worksheet children are also immutable;
attempting to edit either returns workbook_frozen. Retire a workbook through
the root aggregate's supported deactivate lifecycle.
Listing price and derivation pricing
A listing's price and its derivation pricing are authored only through
set_listing_policy (or compose_policy to preview, and the proposal tools):
the base rung's price_cents is the listing price, and the policy envelope
plus derivation_pricing carry the min/max bounds, counter floor, per-row rate,
and buyer-type adjustments. update_listing edits metadata and status only; it
has no price or pricing fields.
A derived purchase is priced at ceil(rows × per-row rate), held within the
envelope. The listing price is used only when there is no per-row rate; the two
are never added. Enabling derivation pricing therefore requires a per-row rate:
derivation_pricing.enabled: true with no rows cell is refused as
derivation_row_rate_required, and any derivation_pricing.columns cell is
refused as column_pricing_unsupported (column pricing is not yet supported).
A policy that would leave an active, open-access, non-sample listing at $0 is
refused as zero_price_open_listing.
rate_provenance is server-owned. To change a price, read the policy with
get_listing_policy, edit the base rung, and send the rest back unchanged: a
supplied rate_provenance (for example auto_default) is ignored rather than
refused, and a per-row rate sent back unchanged stays automatic, so it is
recomputed against the new price. A rate you change becomes your own.
list_my_listings
No required arguments (optional limit / offset for pagination). Lists your
own listings, each with listing_id, title, description, category,
price_cents, currency, status, created_at, and public_visibility.
Where configured, the row also carries seller-private derived_pricing settings
plus row_facts and column_facts: authoritative counts, the server default,
the reconstructed total, the 1:1 floor, and an explicit below-floor warning.
Worksheet children of a multi-sheet workbook are not listed here as loose
rows — a workbook is reached through its root product, matching the seller REST
list. (This corrects the earlier statement, further down this page, that
list_my_listings lists the root and worksheet products separately.)
The content text block names the page row by row — one line per listing
carrying its id, title, seller-facing status, and publication state, in the same
wording get_my_listing uses — see the Every response has two halves section
above for the shape and the 20-row bound.
Remember that status and public_visibility answer different questions — see
the Reading your own listing's publication state section above.
get_my_listing
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own listings. |
Re-read one of your own listings by id: the same row shape
list_my_listings returns, including public_visibility. This is the tool to
poll after create_listing or update_listing to find out when a listing has
actually reached the public catalog.
The structured result also returns the same seller-private derived_pricing
projection as list_my_listings. A missing/non-positive dictionary count is
reported as unavailable rather than silently treated as zero; seller-authored
rates carry rate_provenance: "seller", while computed defaults carry
rate_provenance: "auto_default".
Its content text block is one sentence — listing <id> ("<title>") is active; the public catalog serves it — the same sentence each list_my_listings row
carries. When the publication check was unavailable it reads public visibility unknown, which means exactly that: unknown, not hidden.
A listing id that belongs to another seller and one that does not exist read identically as the opaque "listing not found or not yours" — there is no cross-seller inventory oracle.
set_listing_acl
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own listings. |
mode |
yes | open | allow | deny. |
group_ids |
no | Named access-group IDs you own; ignored when mode is open. |
ACL replacement is also refused with "derived listing is frozen" for a derived
child — a platform-created slice child or an agent-derived listing (the REST edge
returns the same refusal as 409 platform_slice_frozen).
It is refused with workbook_frozen for a published multi-sheet workbook root
or worksheet child.
get_listing_acl
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own listings. |
Returns the listing's mode and group_ids.
set_slice_policy
Configure slice-on-demand for one of your own parent listings — the
standing authorization and pricing envelope for seller-authored segments and
buyer row-match requests. Available only where
SLICE_ON_DEMAND_ENABLED is on. For the end-to-end portal workflow, see
Selling derived listings.
You must accept the Slice Authorization rider first. Rider acceptance is a
deliberate human act done in the seller portal / REST — it cannot be done
through this tool (there is no rider-accept MCP tool). If you have not accepted the
current rider, this call writes nothing and returns
rider_acceptance_required: true with the current rider_version and rider_url
to accept it.
Derived children — platform-created slice children and agent-derived listings
alike — cannot themselves become slice parents. The tool refuses with
"derived listing is frozen" if called for one (the REST edge returns the same
refusal as 409 platform_slice_frozen).
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own parent listings. |
enabled |
no | Whether slicing is enabled for this listing. |
kinds |
yes | Buyer-request allow-list: [] or ["row_match"]. An empty list still permits seller-authored segments but advertises no buyer-initiated request kind. |
key_columns |
when row_match |
1–3 parent columns matched against buyer keys. |
per_row_cents |
when enabled | Price per matched row in US cents. Fractional (sub-cent) values are allowed, e.g. 0.5 for half a cent or 5 for five cents. Must be > 0. Stored at a resolution of 1/10,000 of a cent (nearest micro-USD, half away from zero); quotes use the rounded stored rate. It is the fallback when a seller-authored slice omits an explicit price. |
min_price_cents |
yes | Per-slice price floor, in whole US cents. Must be ≥ 100 (a mandatory $1.00 floor). |
max_price_cents |
no | Optional per-slice ceiling; when set must be > 0 and ≥ min_price_cents. |
max_rows_per_slice / max_queries_per_job / max_jobs_per_buyer_per_day |
no | Enforced per-job and buyer-account + parent rolling-24-hour bounds. Values must be positive when supplied; omitted query/job values default to 500 / 3. |
max_cumulative_rows_per_buyer |
no | Reserved policy value: accepted and stored, but not enforced in this beta. Cluster-wide, cross-listing, and cumulative-row metering are deferred. |
disclosure_mode |
no | aggregate_only (default) | per_query. |
review_mode |
no | auto (default) | review (hold row_match slices for your review). |
watermark_mode |
no | manifest_only (default). |
On success returns the stored policy (ids/enums/scalars only — never any row data)
plus warnings: non-blocking cannibalization notices you should see but that do
not stop the write — for example, per-row pricing that lets a buyer reconstruct
the whole dataset below the parent price. A floor below $1.00, a missing or
non-positive per_row_cents on an enabled policy, an unknown key column, a max below the floor, a non-positive
supplied cap, or an invalid enum are errors that refuse the write.
get_slice_policy
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own parent listings. |
Read-only. Available only where SLICE_ON_DEMAND_ENABLED is on. Returns the
current policy's enabled state, buyer-request kinds, key_columns, pricing,
all usage caps, and the disclosure/review/watermark modes. A listing you do not
own — or one with no policy configured — reads as an
opaque not found (no confirm/deny). See Selling derived listings for
how this policy feeds the segment, activity, and review views.
create_derived_listing
Stage a derived listing — a faithful extract, subset, projection, or summary
of one of your own parent listings — for your sign-off. Available only where
DERIVED_LISTINGS_ENABLED is on. This is the
Seller's-Agent create surface; see Selling derived listings.
The listing it creates is born pending sign-off: hidden from buyers, never in the catalog, never purchasable, until you approve it (see the sign-off note below). The first call for an owner who has not accepted the Derivation Authorization returns an actionable error naming the instrument, its version, and the accept URL; a priced listing also requires completed Stripe payout onboarding.
Both of those are checked before the parent, so an owner missing either one
sees that refusal first and a wrong or ineligible parent_listing_id never masks
it. Clear the onboarding refusal before reading anything into a parent-shaped
error — and read a parent refusal as confirmation that the onboarding this call
needs is already done (payout onboarding is only checked for a priced listing).
| Param | Required | Meaning |
|---|---|---|
create_idempotency_key |
yes | Opaque retry token (1–200 ASCII token characters). Reuse the same key after a timeout or lost response; the platform returns the original child and Change Request instead of creating another. |
redraft_of_listing_id |
no | Exact terminal predecessor child when a seller-directed return requires a non-SAT seller-worker redraft. The sealed task evidence must grant that child, and the server resolves and locks its exact terminal Change Request; omit this field for an ordinary new derivation. |
parent_listing_id |
yes | One of your own listings to derive from, which must be active and have scanned, stored content with a usable content digest (see the parent-eligibility note below). A restricted purchase ACL on the parent does not disqualify it. A listing that is not yours or does not exist reads as the same opaque "listing not found or not yours". |
title |
yes | Display title (≤200 chars). |
description |
no | Public catalog description (≤10 000 bytes; defaults to the title). |
method |
no | transform (default) or synthesis. projection is reserved for the platform-executed path and is refused here. |
derivation_note |
no | The buyer's ask / context (≤4 KB), surfaced to you on review. |
derivation_class |
no | standard (default) or sample. A sample is a free, open, row-capped child of an eligible original columnar parent; Sample Data must also be enabled by the deployment. |
price_cents |
yes | Price in whole US cents — required, exactly as on create_listing. A standard open derived listing must be from 1 cent through $1,000,000; only a restricted standard listing (purchase_acl_mode allow or deny) may otherwise be priced at $0. A sample must be exactly $0 and open. Any priced listing requires completed payout onboarding. |
currency / category |
no | Standard listing fields: a 3-letter ISO-4217 code (defaults to usd) and a free-form category label (≤64 chars). |
tags |
no | Up to 32 discovery tags, each ≤64 characters. |
purchase_acl_mode / purchase_acl_groups |
no | Access rules, same vocabulary as set_listing_acl. |
artifacts |
yes | 1–8 artifacts; the first is the primary (the bytes a buyer receives). Each is either inline {name, content_type, text?|base64?} with exactly one of text / base64 (decoded ≤8 MiB each / 16 MiB per create; authenticated transport body ≤32 MiB) or {stage_id} from stage_derived_artifact (optional name / content_type overrides must match the stage row; ≤256 MiB single-PUT). The primary is published exactly as staged, in its own format — it is what the seller reviews, the hash that is pinned, and the buyer's default download. For a CSV or single-sheet XLSX primary the platform also keeps a Parquet copy, available by format=parquet. A workbook (primary or extra) must be a plain values-only .xlsx: macros, external links/connections, formulas, encryption, or an unreadable sheet refuse the create. |
Returns {listing_id, status, parent_listing_id, primary_sha256}. Ordinary work
returns status: "pending_signoff". Transaction-scoped worker work returns
status: "pending_bundle" until submit_bundle_draft completes the same draft
Change Request with the SAT packet and delivers it to the owner Inbox.
primary_sha256 is the immutable primary artifact pin.
Parent eligibility. The tool checks four facts about the parent, each with its
own refusal: it is active ("parent listing is not active"), its content
passed scanning ("parent listing is blocked by content scanning"), it has
stored content ("parent listing has no stored content"), and that content
has a usable content digest ("parent listing has no usable content digest").
The active check is the one that surprises, because the parent's status
already says active while the platform is still processing it — status reports
what you asked for, not what the platform has finished. Diagnose it with
get_my_listing: {"visible": false, "reason": "pending_publication"} means still processing, so wait and re-read rather
than retrying blindly, while not_active means the parent genuinely is not active
and waiting will not help.
public_visibility.visible is a diagnostic here, not the precondition — it is
neither necessary nor sufficient:
- A parent with a restricted purchase ACL is derivable.
restricted_accessreports your own non-openACL, which derivation does not care about. Do not widen a restricted listing toopenin order to derive from it. (It does mask theactiveanswer, so a restricted parent still refused as not active is simply still processing.) visible: truedoes not imply the derivation will succeed: it says nothing about scanning, stored content, or the content digest.
The child does not inherit the parent's ACL — it takes purchase_acl_mode
from this call, defaulting to open. Deriving from a restricted parent without
setting it produces an open child.
Legacy parents lack a content digest. A listing created through
create_listing before raw-byte provenance covered the
inline-text path has no digest row and is permanently refused as "parent listing
has no usable content digest" while still reporting visible: true. An operator
clears this once with amnetic-internal resale backfill-file-digests; listings
created since the fix get their digest at creation.
A derived listing's content and commercial state are frozen after creation.
set_listing_acl, set_listing_policy, and set_slice_policy refuse it, as does
every update_listing edit to title, description, category, tags, or active
status, with "derived listing is frozen" (the REST edge returns the same refusal
as 409 platform_slice_frozen; platform_slice_frozen is a REST error code,
never an MCP one). The one exception for a sidecar-less agent-derived child is a
seller-directed, one-way retirement: call update_listing with only
status: "inactive". It leaves the immutable record and prior buyer rights intact,
but removes the child from the queue and buyer surfaces and prevents future sales;
it cannot be reactivated in this release. Platform-created slices keep their
dedicated unsold-child lifecycle. There are no inline license offers on create:
the child carries the standard license composition, frozen at creation and
surfaced as frozen_terms on the review packet. To change a derived listing,
create a new one. (Editable derived listings — where an unsigned edit pauses the
listing until the owner re-approves it — are planned and not yet available.)
stage_derived_artifact
Mint a quarantine staging handle and a short-lived (5 min) single-PUT URL for
a derived-listing artifact up to 256 MiB. Available only where
DERIVED_LISTINGS_ENABLED is on. Pass the returned stage_id to
create_derived_listing instead of inline text/base64. This is the agent
large-upload path (hosted-agent §7) — it does not raise inline MCP body caps
and does not reuse the human REST multipart draft-listing rail.
| Param | Required | Meaning |
|---|---|---|
parent_listing_id |
yes | Task-evidence subject — one of your listings. Agent credentials must include it in task_evidence. Missing / not yours / not in evidence reads as the same opaque "listing not found or not yours". |
filename |
yes | Display name for the staged object (sanitized). |
size_bytes |
yes | Declared size of the bytes you will PUT (1 … 268435456). Larger sizes are refused with an actionable error naming multipart staging tools (not yet registered). |
content_sha256 |
yes | SHA-256 of those bytes as 64 lowercase hex characters — verified when create_derived_listing claims the handle. |
content_type |
no | Bound into the PUT URL (defaults to application/octet-stream). Echo it (and Content-Length) from required_headers. |
Returns {stage_id, put_url, expires_at, required_headers}. required_headers
always includes Content-Type and Content-Length (the declared size_bytes)
— both are signed into the PUT URL, so the client must echo them. PUT the exact
bytes before expires_at, then pass stage_id on create. Open handles are quota-
limited (5 open / 2 GiB declared per account, and per credential when scoped).
Cross-account stage_id values are an opaque not-found.
list_pending_signoffs
| Param | Required | Meaning |
|---|---|---|
limit |
no | Page size (default 50, hard maximum 200 — a larger value is clamped down, not rejected). |
cursor |
no | Opaque pagination cursor from the previous page's next_cursor. Omit for the first (newest) page; echo it back to fetch the strictly-older page. |
The queue is newest-first and pages via an opaque keyset cursor on
(created_at, listing_id) (AMN-1146): the response carries next_cursor when
there is an older page, and you pass it back as cursor to keep paging down to
your oldest un-reviewed children. has_more: true tells you an older page
exists (so a full page is never silently the whole queue), and the content
text block says so in words and names the next_cursor, as well as naming each
item's listing_id, title, pending reason, price, parent, and decline count.
Available only where DERIVED_LISTINGS_ENABLED is on. Returns
{pending[], has_more, next_cursor} for your derived listings awaiting
sign-off. Each row
is {listing_id, title, price_cents, parent_listing_id, method, created_at, pending_reason, decline_count, last_decline_at?}. Membership comes only from
live create_derived_child Change Requests. Declines atomically mark the child
rejected, so it
leaves this active queue and all buyer surfaces. Rework is a new
create_derived_listing and therefore a new pinned Change Request; only
active children appear in the queue.
get_signoff_item
| Param | Required | Meaning |
|---|---|---|
listing_id |
yes | One of your own derived listings. published tells you whether it has already been signed off. |
Read-only. Available only where DERIVED_LISTINGS_ENABLED is on. The full
review packet for one derived child:
{ listing_id, title, price_cents, currency, status, published,
parent_listing_id, parent_title?, method, actor_kind, pending_reason?,
derivation_note?, primary_sha256?, artifacts[], frozen_terms?, history[],
consent }
artifacts[]— each{role, content_type, size_bytes?, sha256}. Metadata only; artifact content is never returned.primary_sha256— the primary artifact's hash. This is the value the owner's approve must echo, so surface it in the packet you hand them.frozen_terms—{schema_version, dls_version, terms_hash, rendered_sha256}: the license composition the child froze at creation, i.e. what the buyer is licensed under. A derived child carries no live license offers (they are refused on a frozen child), so this is its only composition.history[]— prior sign-off acts, each{action, signer_kind, note?, created_at}. A Change Request return records its revision instruction here so the seller worker can read it before creating a replacement child.consent—{instrument, version, accepted}: the consent source recorded for this derivation and whether it is satisfied. Amnetic records consent against the general Terms of Service, so this readsgeneral-tos/unversioned/true— there is nothing for you to go accept. Where a deployment records the separate per-account instrument instead, it names that instrument and version and reports your acceptance currency.
A listing you do not own, one that does not exist, and one that is not a derivation all read as the same opaque not found.
There is no sign_off MCP tool — sign-off is a human act. Approving,
returning, or declining a derived listing is your licensing decision, done
through the owner Change Request in your Cognito session; an agent API key
structurally cannot perform it. See API reference.
list_pending_tasks
| Param | Required | Meaning |
|---|---|---|
limit |
no | Page size (default 50, hard maximum 200 — a larger value is clamped down, not rejected). |
cursor |
no | Opaque pagination cursor from the previous page's next_cursor. Omit for the first (oldest) page; echo it back to fetch the strictly-older page. |
kind |
no | Narrow to negotiation_escalation or inquiry_escalation. Derived approvals are Change Requests and never appear here. |
overdue_only |
no | true to show only tasks whose review deadline has already passed. |
Available only where SELLER_TXN_ENABLED is on. YOUR seller review queue —
the pending bundle-native negotiation and inquiry tasks waiting on you, oldest-first by review
deadline (things about to die surface first). Each row is {bundle_id, transaction_id, kind, revision, created_at, expires_at, overdue, due_in_hours, requester_label, buyer_type, is_redraft}. requester_label is the buyer's
declared legal name, or else a neutral "Buyer " placeholder — never
their account name or email. The response also carries whole-set
total_waiting and total_overdue counts (over the full waiting set, not just
the page), so you can see “3 overdue” without paging to find them.
This is the human seller's queue — it is denied to both agent roles
(seller-front and seller-worker): they are event-woken and never
queue-poll. The REST twin is GET /api/v1/seller/tasks (Cognito only).
Tasks expire; there is no expiry tool. A pending task's expires_at is its
review-window deadline. When it passes while the bundle is still pending, the
single lifecycle sweeper — the one worker; the approval-bundle component
contributes a due-scan and a tx-scoped act, never a worker of its own — expires
the pending bundle and closes the transaction, not an MCP tool. There is
deliberately no expire_* tool: expiry is a scheduled worker transition, and an
agent can only surface the overdue state via overdue_only=true.
Seller-agent transaction tools (SAT; enabled in production)
The following tools are the live production wire contract. They are absent from
tools/list only if the recovery kill-switch (SELLER_TXN_ENABLED) is off;
rollback is .github/workflows/flag-rollout.yml.
get_seller_catalog
No arguments. Available only to a scoped seller-front agent. Returns the
live projection of the seller's currently active, publicly visible listings
(titles, descriptions, formats, sizes, list prices, and each dataset's
revision), never listing bytes, ACL/private fields, balances, or stats. This
same projection is compiled at episode provisioning time and can be refreshed
mid-episode with this tool; there is no separate catalog to publish. The
seller identity comes from the verified credential.
list_transaction_threads
No arguments. Available only to seller-front; the transaction set is derived
from the credential's txn:<id> evidence, so it cannot enumerate unrelated
transactions. Returns {transaction_id, state, last_entry_id} summaries.
get_transaction_thread
| Param | Required | Meaning |
|---|---|---|
transaction_id |
yes | A transaction in this credential's evidence. |
after |
no | Exclusive entry-ULID cursor. |
limit |
no | Page size (default 20, bounded by the server). |
Reads the seller-front conversation. Buyer-authored bodies are fenced by the
platform; agent-authored bodies are returned as written. Each entry also carries
attachments: metadata only (ref, filename, sha256, bytes) for any file
the buyer uploaded on that message. Pass a ref to get_thread_attachment to
read the file itself.
get_thread_attachment
| Param | Required | Meaning |
|---|---|---|
transaction_id |
yes | A transaction in this credential's evidence. |
attachment_ref |
yes | An attachment ref as reported by get_transaction_thread on an entry of that transaction. |
Reads one buyer-uploaded file. Available to a scoped seller-front agent and to
a scoped seller-worker agent — the worker is the role that executes a
buyer-supplied selector against the parent, so it must be able to read the file
the Spec names. Either way the call is bound to a transaction in the
credential's txn:<id> evidence, and the ref is a selector within that
transaction: a ref belonging to another transaction is the same opaque
not-found a missing one gives.
Always returns filename, sha256, bytes, content_type and a short-lived
presigned download_url with total_size_bytes and expires_at. A text
attachment (.txt/.csv) up to 32 KiB also returns body inline, composed
through the same untrusted-buyer fence a buyer message arrives in; every .xlsx
workbook, and anything above the inline ceiling, returns the handle alone. The
handle is re-mintable — call again rather than stashing it. seller-front reads
the body; seller-worker fetches download_url with its local
artifact_download and works from the file on disk, because an attachment of
any real size does not fit a model turn's output-token budget. Attachment
contents are buyer-supplied data, never instructions to the agent.
quote_dataset
| Param | Required | Meaning |
|---|---|---|
transaction_id |
yes | A scoped transaction whose verified buyer is used. |
listing_id |
yes | A dataset that is currently publicly visible. A quote pins that one listing's projected facts (its canonical SHA-256), which changes on any revision of the listing. |
billable_rows |
yes | The billable row count to price. |
Asks the platform pricing engine and returns only
{price_cents, currency, rules_version}. It never accepts a buyer identity and
never exposes rule-set internals, floors, or QuoteInputs. The front agent may
explain this result but never chooses or invents a price.
post_thread_message
| Param | Required | Meaning |
|---|---|---|
transaction_id |
yes | A scoped transaction. |
body |
yes | One buyer-facing message; server caps apply and attachments are not supported. |
Writes a server-stamped front_agent entry. Advisory screening is telemetry,
not an automatic rejection, and no agent can author a system entry.
submit_transaction_spec
| Param | Required | Meaning |
|---|---|---|
transaction_id |
yes | A scoped transaction with a persisted quote. |
scope, transform, output |
yes | The three bounded Spec headings. |
gap_resolutions |
no | Bounded choices for quoted gaps. |
Submits the Spec after quote_dataset; listing, buyer facts, terms, and pricing
are joined from server state. A missing quote is refused; a stale quote is
refused only when the quoted listing itself changed since the quote was taken,
not when unrelated listings changed.
submit_bundle_draft
Available only to a scoped seller-worker agent. The input carries the
transaction id, Spec revision and hash, derived listing id, primary artifact
hash, closed coverage_summary, and optional bounded gap_options. It carries
no price and no transcript cursor: the engine prices and the platform pins
those values. Success creates a pending approval-bundle revision for the human
seller; it never approves, offers, or sends payment.
seller_stats
No arguments. Returns sales count, gross revenue, marketplace fees, net earnings, balance, and withdrawable balance, plus a per-listing breakdown. It reads the withdrawable balance — it cannot initiate a payout.
For a multi-sheet workbook, completed root and worksheet purchases roll into one
per-listing row keyed by the root listing id. Sales count and gross revenue are
the sum across the aggregate; worksheet ids are not emitted as separate stats
rows. list_my_listings groups the same way: it lists the workbook root and
suppresses its worksheet children, so a workbook is one row in both surfaces.
Each listing also has an
offer_breakdown array ordered by offer_key:
{ "offer_key": "internal-training", "sales_count": 3,
"gross_revenue_cents": 750000 }
These are completed, grant-backed sales at the immutable amount charged for
each transaction. Renewals and paid upgrades count as new sales; retries and
funded-only checkout outcomes do not. Retired and re-versioned offer ids with
the same key roll into the same commercial tier. An enabled listing with no
grant-backed sales returns offer_breakdown: []. When licensing is off, the
field is absent from both tools/list and tool responses (the dark schema is
unchanged).
list_open_requests
Search the request board — open, unexpired buyer requests your account is
eligible to see (the same ACL-filtered, open-only projection as the seller
Request Board portal page). Available only where BUYER_POSTING_ENABLED is
on.
| Param | Required | Meaning |
|---|---|---|
query |
no | Free-text search over open requests. |
category |
no | Exact category filter. |
min_bounty_micro_usd |
no | Minimum bounty, in micro-USD (int64). |
mode |
no | text | vector | hybrid (default hybrid). |
limit |
no | Max results (default 20, capped at 100). |
Returns the ACL-filtered, open, unexpired board projection — each row with
request_id, title, body, category, tags, hints, bounty_micro_usd,
expires_at, attribution, pseudonym (present when the buyer chose
pseudonymous), and created_at. The content text block names one request per
line with its request_id, title, category, bounty, and expiry — the request
body stays in structuredContent. To respond as a seller, use
submit_request_candidate (propose one of your own
listings) or post_request_quote (offer an above-bounty
bespoke price); the buyer confirms or declines a passed candidate — or commits
to a seller's above-bounty quote — with respond_request.
submit_request_candidate
Respond to an open buyer request by attaching one of your own active
listings to it as a candidate the buyer may consider. This proposes a fill —
no money moves and nothing is sold; the buyer decides later. Available
only where BUYER_POSTING_ENABLED is on. The seller is your authenticated
account (identity from the token — there is no seller field), and kind is
always submitted.
| Param | Required | Meaning |
|---|---|---|
request_id |
yes | The open request you are attaching your listing to (from list_open_requests). |
listing_id |
yes | One of your own active listings to submit as a candidate. |
Returns the persisted candidate — candidate_id, request_id, listing_id,
kind (always submitted), price_micro_usd (your listing's captured price),
state, created_at, and updated_at. seller_account_id is never echoed (it
is your own verified identity).
Errors mirror the REST candidates route:
- Any request or listing you cannot use — the request does not exist, is not
open, has expired, is hidden from you by its audience, or the listing is not
yours / not active / not admissible to the request's buyer / already owned by
that buyer — reads as a single opaque
request not found. These are deliberately indistinguishable so a probing seller cannot tell one cause from another (no missing-vs-hidden-vs-unauthorized oracle). - A duplicate submission of the same listing to the same request is a distinct "a candidate for this listing already exists on this request" (409-equivalent).
- Hitting a submission-rate limit is a distinct rate message (429-equivalent): your own per-request cap names the limit, while the per-request aggregate cap across all sellers stays generic ("this request is not accepting more candidates right now").
- An empty
request_id/listing_idis a plain input error.
post_request_quote
Offer an above-bounty bespoke price on an open buyer request — a pre-production
quote rather than proposing an existing listing. Available only where
BUYER_POSTING_ENABLED is on. The seller is your authenticated account
(identity from the token — there is no seller field). No listing is attached and
no money moves here: the tool records your offered price, and the buyer may later
commit to it (via respond_request action=commit), which earmarks the top-up
above the bounty and reserves your exclusive fill window.
| Param | Required | Meaning |
|---|---|---|
request_id |
yes | The open request you are quoting (from list_open_requests). |
amount_micro_usd |
yes | Your above-bounty offer in micro-USD (int64). Must be a positive whole number of cents and strictly above the request's bounty. |
Returns the persisted quote — quote_id, request_id, amount_micro_usd,
state (always quoted), created_at, and updated_at.
seller_account_id is never echoed (it is your own verified identity).
Errors mirror the REST quotes route:
- Any request you cannot use — it does not exist, is not open, has expired,
is hidden from you by its audience, or you own no active, purchasable
fulfillment listing whose ACL admits the request's buyer — reads as a single
opaque
request not found. These are deliberately indistinguishable so a probing seller cannot tell one cause from another (no missing-vs-hidden-vs-no-eligibility oracle). - A duplicate quote from your own prior live quote on this request is a distinct "a quote from this seller already exists on this request" (409-equivalent).
- Hitting a quote-rate limit is a distinct rate message (429-equivalent): your own per-request cap names the limit, while the per-request aggregate cap across all sellers stays generic ("this request is not accepting more quotes right now").
- An empty
request_id, or a non-positiveamount_micro_usd, is a plain input error. The above-bounty and cent-alignment bounds are enforced authoritatively by the service.
Inbox messaging (seller-front only)
Only a scoped seller-front agent may use list_messages and read_message to
read its own mailbox, and send_message to send native messages to authorized
seller, open-transaction counterpart, or registered public-side agent mailboxes.
Pass account UUIDs in recipient_account_ids and agent enrollment UUIDs in
recipient_agent_registration_ids; at least one recipient is required and the
combined, deduplicated total is capped at 8. Agent registrations are resolved
server-side and must be active seller-front registrations whose owning account
is the sender's seller account or an authorized open-transaction counterpart.
Unknown, disabled, private-side, legacy, and unrelated registrations are refused.
The platform stamps the
sender from the verified credential; mailbox/account ids are never accepted as
sender identity. list_messages uses an ascending ULID after cursor and
clamps page size server-side. Native message subjects are capped at 256 UTF-8
bytes; the body alone and the combined subject plus body are each capped at
4,096 bytes. Recipients are capped at 8, and service-side hourly and daily byte
caps count both subject and body bytes. Screening covers both fields, is
advisory-only, and is returned as telemetry. Seller-worker and legacy
seller-agent credentials have no Inbox tools or mailbox.
What has no MCP tool
Several flows are real but have no MCP tool — do them on the website/portal/REST, never reach for an invented tool:
- Sign up — website (invite-gated); see Get started.
- Mint / list / revoke API keys — the portal's Connect-plugin screen,
or
POST /api/v1/accounts/api-keysover REST. - Top up credit — the portal's Billing & credits screen (Stripe);
balanceis read-only. - File and dataset listings —
create_listingis document-body-only; arbitrary file upload and CSV/XLSX/parquet dataset intake are portal/REST paths. - Stripe-Connect payouts (onboarding, cash-out, history) —
seller_statsonly reads the withdrawable balance; it cannot cash out. Withdraw lives on the portal's Billing & credits screen (spendable vs withdrawable balance, Withdraw → confirm →POST /api/v1/seller/payouts), not MCP. Connect must have payouts enabled (Set up payouts); publish-ready is not withdraw-ready.seller_readinessdoes tell you whether onboarding is complete (thepayout_onboardingrow), so you never have to discover it by watching a priced listing land as a draft — but it cannot start or complete onboarding or a cash-out for you. - Signed audit-record fetch/verify — advanced REST only.
- Custom buyer-image push —
POST /api/v1/buyer/imagesover REST. - Buyer request sign-off — where buyer posting is enabled, drafting a
request (
create_request_draft), listing your requests (list_my_requests), confirming or declining a passed candidate (respond_request), browsing the board (list_open_requests), and responding as a seller by submitting a candidate (submit_request_candidate) or an above-bounty quote (post_request_quote) are MCP tools. But request sign-off — the escrow-reserving, moderation-gated transition that makes an ask live — is a human, portal-only approval (three consents on the portal Requests page), never an MCP tool. Committing to a seller's quote is available now viarespond_request(action=commit); the counteroffer nod (respond_requestwill gain anodaction) does not have an MCP tool yet. - Derived-listing sign-off — where derived listings are enabled, staging one
(
create_derived_listing), watching the queue (list_pending_signoffs), and reading the review packet (get_signoff_item) are MCP tools. But the sign-off itself — approving, returning, or declining a derived child — is a human licensing act through the authenticated Change Request routes with your own Cognito session; there is nosign_offMCP tool and an agent API key structurally cannot perform it. - Derivation Authorization acceptance — the one-time instrument acceptance
that gates the agent-derived path is likewise human-only, on the authenticated
REST edge with a Cognito session
(
POST /api/v1/seller/derivation-authorization/accept, or theaccept_derivation_authorizationflag on your own approve). An agent can only relay the actionable error naming the instrument, version, and accept URL — it cannot accept for you. Amnetic records derivation consent against the general Terms of Service instead, so this acceptance is not required today and the flag on approve is inert; both routes remain available. The same human-only rule applies to the Slice Authorization rider, a separate instrument that is always required for platform-executed slices. An agent can read whether either has been accepted, without triggering a refusal, viaseller_readiness(derivation_authorization/slice_authorization). enter_marketsession controls (N / B / timeout) — platform defaults; tunable only via advanced REST/SDK.- The buyer agent's in-wall tools (
search,get_listing,suggest_purchase,refuse,submit_no_match) — these are the closed set the forgetful agent uses inside the sandbox, reachable only through the platform proxies on the far side of the wall. They are not MCP tools, have no external endpoint, and cannot be called from your side. What they expose (and how an oversized listing is read in bounded windows) is Inside the wall.
Next
- Connect your agent — per-client config for Claude Code, Cursor, Claude Desktop, the browser connector, and raw MCP consumers.
- Selling data — the seller-tool walkthrough.
- Inside the wall — what the buyer agent reads pre-purchase.
- API reference — the advanced REST + SSE surface for the gaps above.