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-write submit_request_candidate and post_request_quote) register only where BUYER_POSTING_ENABLED is 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 where SLICE_ON_DEMAND_ENABLED is on.
  • the buyer Verify and Report tools register only where CONSIGN_ENFORCER_ENABLED is on.
  • the four seller derived-listing tools (create_derived_listing, stage_derived_artifact, list_pending_signoffs, get_signoff_item) register only where DERIVED_LISTINGS_ENABLED is on. They are enabled in production; they are absent from tools/list only 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_ENABLED is 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 carries grant_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_listing still accepts a priced listing but holds it as an unpublished draft, and create_derived_listing refuses 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":

  • status answers what you asked for: active means you published it (or it was accepted), inactive means you retired it, and so on. It is deliberately coarse — the platform never exposes its internal processing states here.
  • public_visibility answers whether the public catalog serves it right now. It is an object { "visible": bool, "reason": string } where reason is one of visible, not_active, restricted_access, or pending_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_access reports your own non-open ACL, which derivation does not care about. Do not widen a restricted listing to open in order to derive from it. (It does mask the active answer, so a restricted parent still refused as not active is simply still processing.)
  • visible: true does 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 reads general-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_id is 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-positive amount_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-keys over REST.
  • Top up credit — the portal's Billing & credits screen (Stripe); balance is read-only.
  • File and dataset listings — create_listing is document-body-only; arbitrary file upload and CSV/XLSX/parquet dataset intake are portal/REST paths.
  • Stripe-Connect payouts (onboarding, cash-out, history) — seller_stats only 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_readiness does tell you whether onboarding is complete (the payout_onboarding row), 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/images over 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 via respond_request (action=commit); the counteroffer nod (respond_request will gain a nod action) 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 no sign_off MCP 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 the accept_derivation_authorization flag 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, via seller_readiness (derivation_authorization / slice_authorization).
  • enter_market session 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.