Base Contracts

Test Accounts

Policies

Deploy Policy Contract

Rules

Policies

Facilitator Registry

Credits & Design Partners

Every Allowed email gets access + free credits and is marked a design partner by default, so Allowed ⊆ Design partners: an allowed partner is always a design partner, but a design partner is not necessarily allowed.

Allowed

Access allowlist

Allowed emails

Email Status Design partner Actions
No allowed emails yet

Waitlist

Email Design partner Actions
No waitlisted emails

Design partners

Partners

Design Partners

Partner ID Email Credits
No design partners yet

Task Proposals

Partner

Proposals history

Date Kind Task What By Status Decided at

Tasks

Slug Description Files
Load a partner's tasks to begin

Author Proposal

Stateful Integrations (Connections)

Registering a connector writes four artifacts in one transaction: the capability row, the connector spec, the composition-instructions card and one skill row per operation. A connector with 0 skills or no instructions is invisible to getAllowlist however correct its spec is — both are shown in the table below. A connector with no source descriptor (none in the Source column) is a third way to be invisible: cli 0.2.101+ drops a sourceless entry from the user's catalog, so the provider looks healthy here and does not exist for the client. To edit a registered connector, click its Edit button: the whole row loads into the register form below, and Register re-registers it in place (the endpoint is a whole-row upsert). A row registered before the card brief was stored comes back with the five brief boxes blank — restate them once.

Registered

Slug Name Base URL Skills Instructions Source Edit
Refresh to load registered connectors

Register Connector

Transactions

One partner's spend: settled rows, pending consumes and projected credit mints, in one union. Amounts are base units — the decimal shown is exact (BigInt), and the raw integer is on the cell's tooltip. The provider filter takes a bucket key (provider:<name>, bucket:legacy, bucket:top-up), which is why its options come from the totals grid rather than from typed-in names.

Partner

Transactions

Date (UTC) Provider Type Product Amount Status Source
Pick a partner and load their transactions

Totals — day × provider

Day (UTC) Provider Amount Rows
Pick a partner and load their transactions

Sign-up bonuses

Credits minted once, when a workspace finalizes: one amount for every new workspace, and a different one for a workspace whose profile is flagged as a design partner. Saving changes nothing retroactively — it arms every future finalize, which is why the save is confirmed on prod even though it writes no chain.

The bonuses

Whole credits only, zero or more — a decimal or a negative is refused. 0 turns a bonus off and is a supported setting, not a mistake. A workspace flagged as a design partner receives the design partner amount instead of the sign-up amount, never both.

Pro plan

0 = no credit included. Whole euros only, from 0 to 1000. The credit is granted to each Pro seat every time its subscription is paid and adds to the balance. Saving changes nothing already granted — it applies to future payments, which is why the save is confirmed on prod.

Billing alerts

What Stripe reported about a payment that needs an operator: a dispute, a fraud warning, a reversal that could not take all the credit back, a payment that could not be credited. A dispute or a fraud warning also freezes the workspace for new payments; the credit it already holds stays spendable. Acknowledge what you have looked at; lift a freeze once the dispute is acknowledged.

Euro-dollar rate

Press Refresh to load.

Tool prices are provider prices in US dollars read as euro, so the margin on tools is the rate minus 1. It has to cover card fees and conversion: below the threshold tools are sold at a loss, and the line above turns into a warning.

Open alerts

Press Refresh to load.

WhenKindWorkspaceStripe objectDetails

Frozen workspaces

Every workspace that may not start a new payment now, whether or not it still has an open alert. A freeze set by a fraud warning is lifted only here.

Press Refresh to load.

SinceReasonWorkspace

Plans

What each workspace plan grants. One saved cell changes what every workspace on that plan may do, within about a minute — which is why the save is confirmed on prod even though it writes no chain.

Entitlements

Press Refresh to load.

FeatureKindPay per useProEnterprise

Change one cell

A flag is true or false. A capacity or a window is a whole number, 0 or more, or the word unlimited — an empty box is refused, never read as unlimited. A floor is a whole number, 1 or more. A choice is standard or custom. Click a cell to fill the form with it.

AI prices

What each AI plan costs per month and what each model costs per million tokens, in EUR. The services read these lists as they are, so a saved row is the price from then on — which is why a save is confirmed on prod.

Plans, per month

Press Reload to load.

ToolPlanLabelEUR / month

Models, per million tokens

Press Reload to load.

Press Reload to load.

ModelInputOutputCache readCache write

Amounts are in EUR, 0 or more, with at most 6 decimals (200, 3.75). An empty box is refused, never read as 0; a model with no cache pricing takes 0. Adding a tool + plan or a model that already exists replaces its row.

Customer plans

The plan each workspace is on. Pick a plan on a row and press its Save to move that one workspace; the row then shows what the server stored. The expiry is never changed here. Under each workspace, one row per member with their own plan and where it came from (subscription / operator / —); Make Pro or Make Pay per use moves that one member. A member whose Pro is paid by the workspace subscription cannot be changed here.

Workspaces

Press Refresh to load.

CompanyEmailPlanValid untilChange plan

Endpoint Pricing (Merchant Economics)

Per endpoint: the price we charge, the cost we pay upstream, the markup between them, and what the last 30 days of calls were worth.

Every amount is base units (×106). The decimal shown is exact (BigInt); the raw integer is on the cell's tooltip. Editing the markup shows the price that would be written — ceil(cost × (10000 + bps) / 10000) — before anything is saved or applied.

A dash is not a zero. — means the value has never been recorded (or could not be read); 0.000000 and 0% mean it was recorded and it is zero. Most of the pass-through fleet really does run at exactly 0% markup — that is the finding this table exists to make visible, and it must not look like missing data.

Recording and applying are two acts. Save writes the cost and markup and moves no price. Apply derives the price from the saved row and writes products.price and the bazaar row in one transaction, with an audit entry. Verify asks the live staging merchant what it actually quotes. Writes are staging-only server-side.

Provider

The picker counts each provider's endpoints running at 0% markup, code-pinned, in bazaar-drift and uncosted, so the providers worth opening are visible before opening one. Each line is named; its commerceInfoId is on the line's tooltip. Typing above narrows the list by substring across the name, the slug and the id — so a pasted id lands too. Filtering never changes what is selected: the provider currently loaded stays in the list even when it does not match, because a picker that silently re-pointed at another merchant would put one merchant's prices under another's name.

Endpoints

Endpoint Current price Upstream cost Markup % New price 30d calls 30d revenue Est. margin Status Actions
Pick a provider and load its endpoints

Est. margin is (price − recorded cost) × calls. Estimated is load-bearing: no measured per-call upstream cost is persisted anywhere yet, so for a pass-through endpoint this is 0 because cost was recorded as equal to price — which is the real finding, not a missing number. It is — when no cost is recorded.

Price changes

Applied Endpoint Old price New price Markup By Verification Actions
Pick a provider and load its endpoints

A revert does not rewrite the row it undoes: it writes a new row pointing at the original and stamps the original's revertedAt. Verification has three states — verified, checked and failed, and never checked. A failed check stamps its result and leaves the timestamp empty, so a change whose live 402 quoted the wrong amount never reads as merely un-examined.

Merchant Integration (x402)

How to onboard a stateless x402 merchant — a pay-per-call provider with no user account or stored state on our side. This is the manual runbook; every step below happens in the tools it names, not in this console.

  1. Scaffold the proxy. Add the provider to merchant-fixtures following the existing per-provider pattern (one proxy service wrapping the upstream API, prices declared per endpoint).
  2. Deploy it on Railway. The FIRST deploy of a new merchant is manual (create the service, set its env); after that, every merge to main redeploys it automatically.
  3. Route it. Add the merchant's route in merchants-router so its slug resolves to the deployed proxy.
  4. Register it in the supplier app. Sign up / sign in on the supplier app with the merchant's own account (name, email, password), then register the commerce info and every endpoint. Composition instructions MUST list the endpoints under an ## Endpoints heading — atoms outside it are invisible to getAllowlist.
  5. Products & pricing. Declare each product's price and (if deferred) the suggested allowance — base units, ×106.
  6. Whitelist on-chain — LAST. The payTo whitelist entry is always the final step, only after everything above is verified. Never whitelist first.
  7. Smoke test. From a staging MCP session: getAllowlist must surface the provider, and one real spend per payment shape (exact and deferred) must succeed end to end.

Full runbook with copy-paste values: eng-onboard-merchant (operator skill) and the loop-merchants queue for autonomous intake.

Ametyst Agent — getAllowlist

When a customer's agent calls getAllowlist, the Ametyst Agent chooses the skill with Jev from this catalog: every skill of the platform with a short line, an excerpt and a domain. Sync catalog reads every skill of the platform and rewrites only the new and changed ones (a few cents each); unchanged skills cost nothing. Reclassify all asks Jev the domain of every skill again, for after the domains changed: it only proposes moves, checks them on the test set, and writes nothing until you apply. Staging only.

How it works, and what you can do by hand
1. ANSWER  (under a second, at every request)

   agent: "what do I use for X?"
        |
        v
   Jev picks the DOMAIN  -->  Jev picks the SKILL inside it
                                   |
                                   |  at the same time: "is X the same kind of request as an
                                   |  EXAMPLE approved for this member / workspace / everybody?"
                                   v
                          yes (85% or more) -> the example's skill, alone
                          no                -> Jev's own choice
        |
        v
   answer to the agent  +  one row in "Latest decisions"


2. WATCH  (by itself, always)

   the agent uses a skill  -->  written next to the decision ("What the agent used next"):
                                followed / another one proposed / another app


3. LEARN  (once a day, or "Run review now")

   decisions that ended with another app
        |  Jev groups the ones that asked the same kind of thing
        v
   3 cases in 2 sessions?  -->  a PROPOSAL: "requests like this -> this skill"
        |                       for one member / one workspace / everybody
        |  tried on the test set: dropped if it answers worse
        v
   YOU: Approve / Refuse  -->  it becomes an EXAMPLE  -->  back to 1
You want toWhereWhat it does
Correct an answer now, without waiting for it to repeatLatest decisions → Right skill was another, then Examples → Add exampleFrom the next request of that kind, Jev answers the skill you wrote. Choose who it is for: one member, one workspace, everybody.
Take a correction backExamples → Deactivate · Proposals → UndoThe example stops being used at once. Jev answers as before.
Decide on what the review foundProposals → Approve / RefuseApprove creates the example. Before approving you can widen who it is for and rewrite the request in general words.
Look for repeated mistakes nowProposals → Run review nowSame as the daily review. It proposes only a mistake seen 3 times in 2 sessions.
Protect answers that are rightLatest decisions → Use as testAdds the request and its skill to the test set. Every proposal and every reclassify is checked against it.
Bring in new or changed skillsCatalog → Sync catalogReads the platform, rewrites only what is new or changed.
Fix skills filed in the wrong domainCatalog → Reclassify all, then Proposed moves → Apply selected / UndoOnly after the domains changed. Nothing is written until you apply. An example does not fix a wrong domain: this does.
Fix one skill filed in the wrong domainDomains → Show skills or Search skills, then MoveMoves that skill at once and shows how the test set answers before and after. Moving it to other takes it out of every answer.
Add a kind of request the catalog does not haveDomains → Add domainCreates the domain, empty. It starts to count when a skill is moved into it, by hand or by a reclassify.
Reword what a domain meansDomains → EditJev reads the new text from the next request. The test set is shown before and after, and Put back restores the old text.
Remove a domain nobody usesDomains → DeleteOnly a domain with no skill in it. other is never deleted.

Limits: it learns only from workspaces whose sessions reach the gateway and that share more than the minimal depth. The daily review runs only when the gateway has REVIEW_HOUR_UTC set. Nothing is ever applied without your approval.

Catalog

Press Refresh to load.

Proposed moves

Press Refresh to load.

ApplyFrom → toSkillsWhich ones (hover for all)

Proposals

Press Refresh to load.

ForRequest (editable before approving)Right skillEvidenceTestsStatus

Examples

Press Refresh to load.

ForRequestRight skillOriginUsed

Test set

Press Refresh to load.

IntentRight skillAdded

Latest decisions

Press Refresh to load.

WhenIntentVerdictDomainConfidenceCallsmsWhat the agent used next

Domains

A domain is what the caller wants, never the vendor. Jev picks a domain first, then a skill inside it. Changes here are live at once. A new domain is not offered until a skill is in it: move one in below, or run Reclassify all. A skill moved to other is never offered.

DomainSkillsWhat it means

Press Show skills on a domain, or search, to move a skill by hand.

SkillLineDomainMove to

Ametyst Agent — Session advice

While a member's agent works, the Ametyst Agent looks at the conversation every 20 events and on each prompt, and says one line when it sees a known waste (retry too fast, same search rephrased, paid after a free search, …) or when a prompt needs an app and getAllowlist was not called. The line reaches the agent at its next action as Ametyst Agent: …. Whether it was followed is read from what the conversation did next: Followed (the waste stopped, or getAllowlist was called), Ignored (it went on), No later activity (nothing more within 30 minutes), Not delivered (the cli never took it). Staging only.

How it works, and what you can do by hand
1. LOOK  (while a member's agent works; the line arrives about 20 seconds after the fact)

   what the agent does (prompts, tool calls, results)  -->  stored by the gateway
        |
        |  every 20 events, or 5 events older than 2 minutes, and on each prompt
        v
   Jev reads the last 40 events against the PATTERNS of that member:
   everybody's + its workspace's + its own, minus the ones MUTED for it
        |
        +--  a pattern at 75% or more (50% while the agent is stuck or wasting)  -->  ONE LINE
        +--  a prompt that needs an app, and no getAllowlist in the next 5 events  -->  the REMINDER
        +--  anything else                                                         -->  silent
        |
        v
   "Ametyst Agent: ..." at the agent's next action   +   one row in "Lines said"


2. WATCH  (by itself, from what the conversation does next)

   the waste stopped, or getAllowlist was called     -->  Followed
   it went on                                        -->  Ignored
   nothing more within 30 minutes                    -->  No later activity
   the cli never took the line                       -->  Not delivered

   3 Ignored in a row, same member, same pattern     -->  MUTED for that member, by itself
                                                          (a Followed in between resets the count)


3. LEARN  (once a night, or "Run review now")

   a pattern said 10 times or more in 30 days, followed less than 1 time in 5
        -->  a PROPOSAL to retire it

   a waste seen 3 times in 2 conversations, and no pattern for it
        |  a model writes the pattern from those sessions (no e-mail, URL, path or long number)
        |  Jev tests it: recognised on its own cases, no test window changing verdict
        v
        -->  a PROPOSAL to add it, for that workspace (or everybody when 2 workspaces saw it)

   YOU: Approve / Refuse / Undo  -->  it becomes a PATTERN (or one is switched off)  -->  back to 1
You want toWhereWhat it does
See what was said to whom, and whether it workedLines saidOne row per line, newest first, with its outcome. Hover the pattern for Jev's numbers.
Teach it a waste it does not know, nowPatterns → Add patternFor one workspace, one member or everybody. Said from the next look. The same id as a general pattern rewords it for that level.
Stop a pattern for everybodyPatterns → DeactivateNo longer offered to Jev; it stays listed.
Stop a line for one member or one workspaceMuted → MuteThat pattern (or reminder) is no longer said to them. Everybody else still hears it.
Give a muted line backMuted → UnmuteSaid again from the next look. An automatic mute then counts again from zero.
Decide on what the night foundProposals → Approve / RefuseApprove of an add creates the pattern (you may first choose Everybody and edit the line); of a retire, switches the pattern off.
Take a decision backProposals → UndoThe pattern an approval created is switched off; the one it retired comes back.
Look for new waste nowProposals → Run review nowSame as the nightly review. The line above the table says what the run found and why something was dropped.

Limits: it looks only at workspaces that share the full session with the gateway. A line can use only what the window holds: a pattern whose text needs something the code cannot read from it stays unsaid. The nightly review runs only when the gateway has REFLEX_REVIEW_HOUR_UTC set; without a writer key it proposes only retirements. Nothing here changes a threshold: the outcomes do.

Lines said

Loading…

WhenWorkspaceMemberPatternLine saidOutcome

Patterns

What the Ametyst Agent can recognise and say, at three levels: everybody (the catalog), one workspace, one member. The most specific wins: a pattern added for a workspace with the id of a general one rewords it there; a new id adds one. A pattern switched off is no longer offered and stays listed.

Loading…

ForPatternLine saidOfferedOriginLast 30 days

Muted

Who no longer hears which pattern. Automatic: the same line ignored three times in a row by one member (a followed line in between resets the count). By hand: added here for a member or a whole workspace; reminder is the getAllowlist reminder. Unmute brings the line back; an automatic mute then counts again from zero.

Loading…

WhoPatternHowSinceState

Proposals

Once a night the Ametyst Agent reviews what it said and what it saw. Retire: a pattern said at least 10 times in 30 days and followed fewer than one time in five. Add: a waste it saw three times in two conversations with no pattern for it; a model writes the pattern from those sessions and it is tested before it reaches this table (recognised on its own cases, no test window changing verdict). Nothing is applied until you approve it; an add for one workspace may be approved for everybody, and its line edited first. Undo reverses an approval.

Loading…

KindForPatternSignatureLineCasesTestsState

Treasury

The treasury account's money, for invoicing: current balance, every on-chain transfer in and out, and who the counterparty was. Every amount is base units (×106), shown as an exact decimal — the CSV carries both forms. A counterparty label is operator-curated: merchants' payTo addresses are not recorded off-chain anywhere, so name them here (click Label on a row) and the name sticks for every future transfer.

Press Refresh to load.

TimeDirCounterpartyLabelAmountTx