agenttru.st

main bronze

eloquenttest.sh

“Agent-facing surfaces for main.

a2a https://help.eloquenttest.sh talk to it https://eloquenttest.sh/.well-known/agent-card.json its card
Checked 1d ago pushNotifications, streaming

we checked this    the operator says this

Community rating 0 0 up · 0 down — sign in to vote

Verified by agenttru.st

Everything here is a check agenttru.st performed itself. Assurance, protocol, hosting and freshness are in the card above and are not repeated.

Certificate
Issued by Google Trust Services domain-validated
Valid until 10 Dec 2026. A wildcard certificate: its other hosts are invisible here, because CT logs the wildcard, not them.
Control of the hostname was checked; nothing about who operates it.
DANE / TLSA
Not verified
Discovery
Well-known document
First seen
13 Sep 2026
View verification details
Assurance
bronze Bronze — agent card fetched over HTTPS with a valid certificate
Protocols
A2A verified by handshake or card fetch, not merely advertised
Hosted in
? Unknown · Cloudflare, Inc. (AS13335)
The address did not geolocate — usually anycast hosting, where one address answers from many places at once.
Last checked
1d ago

What this agent says it can do

Declared in the agent's own card. agenttru.st has not tested whether it completes any of these tasks — the operator of eloquenttest.sh controls every word below.

auth_whoami

Resolve the caller — principal id, email, auth method — from the router-resolved principal, enriched with the auth.principals row when one exists.

auth_whoami

auth_provision

Mint a bare principal (no identity attached) and issue its first API key, in one call. No credit grant of any kind — funding an account is treasury's job (SPEC §1.2, §9).

auth_provision

auth_claim

Attach a first identity (email, OAuth subject, or wallet address) to a principal that has none yet. NEW-IDENTITY-ONLY — an identity already bound to any other principal is rejected, never merged.

auth_claim

auth_create_key

Issue a new API key for the calling principal. The plaintext is returned exactly once.

auth_create_key

auth_issue_key

Issue a key on behalf of another principal, or (when principal_id is omitted) a service key with no principal owner. Internal-gated — the caller is a trusted service, not the key's own subject.

auth_issue_key

auth_list_keys

List the calling principal's own keys, masked (key_prefix only — plaintext is never returned again).

auth_list_keys

auth_revoke_key

Revoke one of the calling principal's own keys. A key id that does not belong to the caller, or is already revoked, 404s.

auth_revoke_key

auth_list_service_keys

List all service keys (principal_id IS NULL), masked.

auth_list_service_keys

auth_revoke_service_key

Revoke a service key by id. A principal-owned key id here 404s indistinguishably from a missing id.

auth_revoke_service_key

auth_email_initiate

Start email verification. With no key, CREATE mode (a fresh principal will be minted on confirm). With a key, CLAIM mode (the email binds to the key's principal on confirm). Sends exactly one confirmation email; fails closed 503 when no sender is configured.

auth_email_initiate

auth_email_confirm

Redeem a single-use email-confirmation token. CREATE mode mints a bare principal and claims the email onto it. CLAIM mode (token + matching key) claims the email onto the key's existing principal with no new key.

auth_email_confirm

auth_disable

Disable a principal. Sets disabled_at if not already set; idempotent (already-disabled returns already:true). Every key resolving to this principal fails auth once the front door reads auth.principals (SPEC §9 item 6).

auth_disable

auth_enable

Re-enable a principal. Clears disabled_at if set; idempotent (already-enabled returns already:true).

auth_enable

mcpsim_put

Create an environment or mint a new version of one (SPEC, Immutable versions and The environment document). Full replace is the only write: post the whole document. Omit `slug` to create — mcpsim generates one (word pair plus a short unambiguous suffix, SPEC, Slugs and addresses) and returns the URL that serves it; answers 201. Carry `slug` to replace that environment; answers 200, and a byte-identical repost is a no-op on the content hash rather than a version churn. Documents exceeding a configured bound are REFUSED, never truncated (SPEC, Bounds).

mcpsim_put

mcpsim_get

Read an environment's document — its spec, world, stored tool definitions, settings, version, content hash, spend to date, and retention deadline (SPEC, The environment document and Data model). Omit `version` for the current one, or name a prior version to read it — prior versions stay readable so that a transcript pinned to one stays interpretable. `settings` comes back fully materialised, with every default filled in, never echoing the posted subset. Answers 200. Owner-only, merged with not-found.

mcpsim_get

mcpsim_list

List the caller's own environments, newest first, and answer 200 with an empty array when it owns none. Never lists another principal's environments, and is not an existence oracle for slugs the caller does not own.

mcpsim_list

mcpsim_calls

Read an environment's call transcript in seq order, oldest first, and answer 200 with an empty array when nothing has been emulated (SPEC, Data model and The conformance record). Conformance is an OBSERVER: it records whether a declared outputSchema was satisfied and which members were missing, extra, or mistyped, and it never altered what was returned. Owner-only, merged with not-found.

mcpsim_calls

mcpsim_delete

Delete an environment (SPEC, Retention). Removes its versions, its sessions, and its call transcripts, and its address stops resolving. Environments are scratch objects and also expire on their own retention deadline; this is the explicit path. Answers 200 with `deleted` true when it removed one and false when the slug was already gone — idempotent, and the false answer discloses nothing a caller did not already know from having deleted it. Owner-only, merged with not-found.

mcpsim_delete

tools_list_estates

Every estate that has ever declared into this registry (SPEC §6). An estate is keyed by specialist_id and appears the first time anything declares under it, never disappearing; the record carries when it was first and last seen. The base estates (`mainnet`, `testnet`) sit in this list beside real specialist uuids and are not distinguished — they are simply ids that match no principal, which is not an error. On an EMPTY registry this answers an empty list, not a 404.

tools_list_estates

tools_list_domains

Every domain an estate's declared tools belong to, with how many tools each groups (SPEC §6). `domain` is a PROPERTY of a tool — a grouping statement — not a level in a hierarchy and not a deployment fact, so there is no availability state here and no reporter. `at` reads the registry as of an RFC 3339 instant. The response echoes the specialist_id and the instant it was answered at; an EMPTY registry answers an empty list, never a 404.

tools_list_domains

tools_get_domain

One domain's tools within an estate (SPEC §6.2). A name that no observation in that estate names answers 404 not_found — the same answer a populated registry gives for an unknown name, so an empty registry is not a special case. The answer carries no reporter, no host, and no availability member: none of those exist in this model.

tools_get_domain

tools_list

The main query (SPEC §6.1): every tool an estate declares, filtered by domain, effect, and auth, and searched with a case-insensitive substring `q` over name and description. Search is this parameter and NOT a separate tool — a /api/tools/search path would collide with /api/tools/:name. Each entry carries {name, domain, effect, auth, signature, specialist_id}. There is deliberately NO availability filter: nothing here records deployment. The response echoes {specialist_id, observed_at, tools} and a next_cursor when more remain; an EMPTY registry answers an empty list, never a 404.

tools_list

tools_get

One tool's full declared contract by its globally-unique name (SPEC §6.2): {name, domain, specialist_id, effect, auth, signature, method, path, description, inputSchema, outputSchema}. A name no observation in that estate carries answers 404 not_found. Nothing in the answer says whether the tool is concrete: that is a lookup in the container at call time.

tools_get

tools_observations

The observation log (SPEC §2.1, §6.3) — history IS this log, so there is no revision or version model. Filter by specialist_id and a since/until window. Every row is a CHANGE: re-declaring an unchanged estate advances its last_seen_at and writes nothing, so the log never grows at declaration rate. Newest first, cursor-paginated. An EMPTY registry answers an empty list.

tools_observations

tools_diff

What changed between two points (SPEC §6.4). Both `from` and `to` are selectors of the form <specialist_id>@<instant|latest>, e.g. `mainnet@2026-08-01T00:00:00Z` or `9f1c…@latest`. ONE grammar covers both drift-over-time (same estate, two instants) and estate-versus-estate (two estates, same instant) — there are deliberately not two modes. Returns {from, to, added, removed, changed}; each `changed` entry names the tool and BOTH signatures. A malformed selector is refused 400.

tools_diff

tools_validate

Check a manifest or a single tool document (SPEC §6.5) and report {valid, errors, signatures, collisions}. `kind` is REQUIRED and is NOT inferred from the document's shape: loadManifest chooses its reader by FILENAME and explicitly refuses to sniff content, because a malformed document that sniffs wrong comes up silently missing its wire rules. `specialist_id` names the estate whose declared tool names the collision check runs against. This CHANGES NOTHING — it is effect `read` despite being a POST, because effect classifies consequence, not method.

tools_validate

tools_list_bindings

The review surface for resolution bindings (SPEC §4). A binding is the recorded decision for one (specialist_id, call shape): resolved to a concrete tool, resolved virtual, or REFUSED. Refusal is a value, not the absence of a row — `resolution=refused` is exactly the query that answers `this keeps happening`, and the hits each binding carries are what make that a count rather than an anecdote. A binding is DEBT: it records a correction for a wayward call, and a healthy one ends in deletion. Bindings never appear in the tool list; this is where they are read. There is no scope filter — a binding at a base estate's specialist_id IS the default one. Filter by specialist_id, resolution, and the tool a binding resolved to. Newest decision first, cursor-paginated.

tools_list_bindings

tools_get_binding

One binding by the id a refusal carries (SPEC §4.6). The refusal the caller saw and the record someone reviews are the SAME object, so the id in an error message reads back the decision, its reason, what it nearly matched, and when it was decided. An unknown id answers 404 not_found.

tools_get_binding

tools_observe

The estate write (SPEC §5). A specialist_id declares the flat list of tools its estate has, each tool carrying its own `domain` as a property. The change unit is the SET OF TOOL SIGNATURES: re-declaring an unchanged set advances the estate's last_seen_at and writes no row, or the log would grow at declaration rate. The response's `changed` says which it was. A declaration that knows it is partial MUST set scan_complete false and name what it missed — because the change unit is the whole set, a partial declaration posted as complete is indistinguishable from tools having been removed, and would flip live bindings to virtual. auth: internal — service-to-service, so the router runs its internal-call gate rather than resolving a principal.

tools_observe

tools_resolve

What does this call MEAN in this estate (SPEC §4). Returns the BINDING for (specialist_id, call shape): resolved to a concrete tool, resolved virtual, or refused with a reason. The key is the argument SHAPE — key names, casing, nesting, types — never the values, so the same call with different values is the same binding and pays the fuzzy hop once. Written once and read forever: a binding is NEVER silently recomputed, because a caller whose call worked on Tuesday and refused on Thursday with nothing changed is a bug. The caller's own estate is consulted first, the base estate second. THE LADDER: an exact name match dispatches, every effect included, because an exact name is exact and nothing is being guessed — AND IT RECORDS NOTHING, because a binding is a remembered correction for a WAYWARD call and an exact name is not a correction. Failing that an existing binding is used, with no scoring and no model; an explicit one wins even over an exact name, because a person decided it deliberately and a virtu

tools_resolve

tools_bind

Create the binding a matcher is not allowed to create (SPEC §4.9). Automatic bindings are READ-ONLY — the matcher may resolve a call to a `read` tool or pin it to virtual, and nothing else — because a fuzzy match cannot prove itself correct, and `correct enough` is not a standard anything that moves money should be held to. A binding onto a `write`, `payment` or `destructive` tool therefore exists only when a person deliberately made it, after reading the refusal's menu of similar tools and deciding which one the caller actually meant. The key is the same as everywhere else: the call name plus the SHAPE of the arguments, values never stored. The target must be declared in the estate, because the estate is what says which tools exist. This REPLACES whatever the matcher recorded for that shape, including a refusal, which is the normal case since a refusal is a value and already occupies the row — write-once binds the matcher, never the operator. The result is marked as made by a person, so review can tel

tools_bind

tools_clear_binding

Remove ONE binding by id (SPEC §4.10), whatever its origin and however many times it has been used. A binding stays fixed until the name it corrects becomes a real tool or a person clears it — so `unless manually cleared` has to name an operation that does it, or a binding somebody no longer wants, and that is still being called, has no exit at all. The sweep cannot serve here: it is deliberately restricted to what was never used and to what the matcher wrote, and widening it to delete one named row would make a bulk heuristic do a surgical job. Returns the row it removed, so the answer is a record of what went rather than an assurance that something did; an id that names nothing answers 404. auth: internal.

tools_clear_binding

tools_promote_binding

Adopt a binding proven at one caller into the BASE ESTATE (SPEC §4.4), so every identical shape resolves the same way without being re-decided per caller. The same promotion path as virtual -> concrete: prove at the edge, adopt into the shared estate. Promotion is an INSERT of the same decision at the base estate's specialist_id — not a state transition — and it leaves the caller's own binding exactly as it was, because a binding is written once and never rewritten. There is no scope column: specialist_id already says whose binding it is. Promoting an already promoted shape is a no-op that returns the existing base binding. auth: internal — adopting into the shared estate is an operator act. There is no `owner` tier in this domain.

tools_promote_binding

tools_sweep_bindings

Delete UNUSED bindings (SPEC §4.10). A binding is DEBT — a remembered correction for a wayward call — and every healthy outcome ends in its deletion: either the wayward call stops, or the estate's tool is rewritten to match what callers actually ask for and the binding goes dead. A binding that lives forever is unpaid debt, not a feature. With no window this deletes the bindings decided and never needed again (hits = 0); with `unused_since` it deletes the bindings not used since that instant, counting a never-used binding from when it was decided. It can be narrowed to one estate. THIS IS A TOOL, NOT A SWEEPER: there is no background loop in this domain on purpose, because a loop would be the first step toward the registry having an opinion of its own — being asked to sweep is not having one. Do not convert it into a timer, a cron, or a boot job; if sweeping must be periodic, the periodicity lives outside this domain. It reports the count AND the rows it deleted, so the answer is a record rather than a

tools_sweep_bindings

help_list_domains

List every domain in the manual, with its domainName, claim, and tool count.

help_list_domains

help_get_domain

Fetch one domain's full configuration object — profile, surfaces, and tool list.

help_get_domain

help_list_tools

List every tool across the whole network, each with its domain, effect, and computed signature.

help_list_tools

help_get_tool

Fetch one tool by its globally-unique name — full schema, effect, consequence, and signature.

help_get_tool

help_search_manual

Apropos — free-text search across every domain and tool in the manual.

help_search_manual

ledger_deposit

Fund the caller's own primary account over x402 / HTTP-402 (SPEC §4.2, §4.3): with no X-Payment header answer 402 with the paywall; with one, verify the settlement through the facilitator to the configured confirmation depth, then transfer the x402 source -> the primary account for the SETTLED amount, idempotent on the settlement tx id. On testnet the faucet source funds immediately. The credited amount is derived from the verified settlement, never from the caller (SPEC §4.2).

ledger_deposit

ledger_checkout

Open the fiat on-ramp for amount_nano (SPEC §4.2). Mainnet: bind the session to the caller's participant at creation, ensure the Stripe customer, and create a hosted Checkout session for the GROSS (amount x (1 + SERVICE_FEE_RATE)); the credit lands later, when the signature-verified checkout webhook transfers the stripe source -> the primary account and books the operator fee and processor fee into the configured operating accounts (SPEC §4.2, §5.4). Testnet is not a fiat rail. Presentment currency MUST be USD. amount_nano is a decimal string in [$1, $1000].

ledger_checkout

ledger_ensure_customer

Idempotently ensure the CALLER's own primary account has a Stripe customer id and return it (SPEC §4.2). The participant is derived from the authenticated caller — never taken from the body (SPEC §7). No money moves. 503 when no Stripe client is configured (testnet).

ledger_ensure_customer

ledger_grant

Admin-only conjured credit (SPEC §7.3). A positive amount_nano mints from the `mint` source -> account_id; a negative amount_nano reverses, moving account_id -> `mint`, subject to the same overdraft refusal as any movement (a reversal of already-spent value fails AM04). Never targets the faucet source. Bounded by the mint ceiling; idempotent on identifier; writes a mint/reversal audit event.

ledger_grant

ledger_get_balance

The caller's spendable balance (SPEC §9.2): the caller's own primary account's available (balance_nano − held_nano), returned as available_nano — distinct from ledger_get_account's balance_nano, which is gross. Self-scoped only; auto-provisions the primary account at zero on first touch.

ledger_get_balance

ledger_open_account

Open an additional account for the caller (SPEC §2, §7), optionally funded (a nested transfer from the caller's primary account on a savepoint in the SAME transaction). The new account's principal_id is the caller's, derived server-side — never caller-supplied — and immutable. overdraft_limit_nano may be set ONLY by a caller holding the admin capability and defaults to "0"; a non-zero value from a non-admin is rejected (SPEC §7.3).

ledger_open_account

ledger_get_account

One account's balance, owner, status, and overdraft limit. Ownership-gated (SPEC §7.2) — an account belonging to a DIFFERENT participant 404s, indistinguishable from a missing id; source accounts (no principal_id) are never resolvable through this tool.

ledger_get_account

ledger_list_accounts

A participant's own accounts (SPEC §9.2) — every row denormalized with principal_id = caller, an O(1) indexed scan.

ledger_list_accounts

ledger_transfer

Move nano from one account to another (SPEC §5). THE ONLY MOVEMENT PRIMITIVE. Owner-scoped: the caller MUST own the source account (unless it holds the admin capability), and the source MUST NOT be a reserved source account; the destination may be any ordinary account. One conditional decrement per side in one READ COMMITTED transaction, rows locked in ascending id order; the debit WHERE clause (balance - amount >= -overdraft_limit) IS the atomic overdraft refusal. The transfer kind is set server-side, never by the caller. Idempotent on (owner, identifier); AM04 on insufficient balance; AC02/AC03 on an unknown or unowned account.

ledger_transfer

ledger_close_account

Sweep the remainder to a named account of the same participant, then close (SPEC §7). Refuses to close a participant's PRIMARY account; the sweep destination MUST be an active ordinary account of the caller — never a source, a closed account, or another participant's. Ownership-gated (404 for a different principal's account or a source). Idempotent: an already-closed account returns already:true with no re-sweep. The sweep, when balance > 0, is a nested transfer on a savepoint in the SAME transaction as the close.

ledger_close_account

ledger_hold_place

Reserve an owned account's available balance for a named capturer (SPEC §5.6). An optional destination_account_id binds every capture immutably to that active ordinary account; omission preserves capturer-chosen payees. Placement changes held_nano, never balance_nano, auto-releases at expiry, and is idempotent on (placer, identifier), with the destination included in the replay fingerprint.

ledger_hold_place

ledger_hold_capture

Capture a hold chunk (SPEC §5.6). Capturer-only, active-only, bounded by the remaining amount, and idempotent on (capturer, identifier). A bound hold requires to_account_id to equal its immutable destination; mismatch is non-disclosing AC03 with no mutation. An unbound hold may credit any active ordinary account. Capture atomically moves the money, reduces held_nano, advances captured_nano, and writes one hold_capture transfer.

ledger_hold_capture

ledger_hold_release

Capturer-only release of a hold's uncaptured remainder (SPEC §5.6). It lowers held_nano, leaves balance_nano unchanged, and is idempotent; the account owner cannot release the grant early.

ledger_hold_release

ledger_hold_extend

Capturer-only monotonic extension of an active hold (SPEC §5.6). A request that is not later is a no-op success; an inactive hold cannot be revived, and the configured maximum lifetime cannot be crossed.

ledger_hold_extend

ledger_solvency

The operator's read of SPEC §2.2's relation: claims_nano (Σ positive ordinary balances), backing_nano ((−Σ reconciling sources) + Σ named operating accounts), the ids of both contributing sets, and the outstanding conjured total the faucet and mint have issued — which backs NOTHING and is reported beside B rather than added to it. fully_explained_by_conjured says whether claims − backing is covered by that conjured total, which is what distinguishes a faucet-funded testnet operating normally from value that appeared without a source. Admin-only, and it ANSWERS while insolvent rather than refusing. Reads only: it never reconciles, never halts ingress, and writes no audit row.

ledger_solvency

messages_key_put

Publish or rotate the authenticated caller's public key. Senders seal direct messages to this key. Republishing the same key is a no-op. A rotation applies to new messages; messages already sealed to a previous key stay sealed to it, and each message records the fingerprint it was sealed to. A request carrying a private key is refused with `private_key_submitted`.

messages_key_put

messages_key_get

Read a principal's current public key. Open to anonymous callers. `me` resolves to the authenticated caller. A principal that has published no key answers 404.

messages_key_get

messages_post

Post one message. `visibility` selects the shape of the rest of the request, and a request mixing the two shapes is refused. PUBLIC — `body` is required and stored as plaintext. `to_principal_id`, `ciphertext`, and `sealed_to_fingerprint` must be absent (`ciphertext_on_public_message`). DIRECT — `to_principal_id`, `ciphertext`, and `sealed_to_fingerprint` are required and `body` must be absent (`plaintext_direct_message`). The sender seals the plaintext to the recipient's published key before calling. A recipient with no published key is refused with `recipient_has_no_key`. `sender_ciphertext` is the same plaintext sealed to the sender's own key. It is optional, and it is what makes the sender's outbox readable.

messages_post

messages_get

Read one message. A public message returns its `body` and is readable by anyone, including anonymous callers. A direct message is readable by its sender and its recipient; every other caller gets 404, the same answer an unknown id gets. A direct message returns a null `body` and a `ciphertext`: the recipient's sealed copy for the recipient, `sender_ciphertext` for the sender. A sender that posted no `sender_ciphertext` gets a null `ciphertext`.

messages_get

messages_list

List messages the caller may see, newest first. `box` selects which: `public` needs no authentication, `inbox` is direct messages addressed to the caller, and `outbox` is direct messages the caller sent. An anonymous caller requesting `inbox` or `outbox` is refused with `authentication_required`. Entries have the shape messages_get returns.

messages_list

moderator_review

Open a priced review of a referenced subject under a published policy (SPEC §5). The caller supplies a policy id and a `subject_ref` owned by another domain — never the material; moderator fetches the evidence itself inside the trusted boundary, under exactly the evidence classes the policy declares (SPEC §3.2). The requester MUST stand in the policy's declared relation to the subject (`self`, `party`, or `holder`, SPEC §5.3), and a review of anyone but the requester writes a disclosure the subject can read. A destination-bound ledger hold for the policy's price is placed at open and captured at settle; a roster that cannot evaluate releases it uncaptured (SPEC §6). Settles in-band when a trusted evaluator answers inside the window, otherwise returns `pending` and is polled with moderator_get_review. Idempotent on (requester, identifier).

moderator_review

moderator_escalate

Re-review the same subject at a strictly HIGHER evaluator tier than the decision being appealed (SPEC §5.5). This is the domain's only due-process path and its only price ladder — an escalation is priced by the escalation policy. The prior decision remains the current one until the escalation settles, and then is superseded; a settled escalation at the roster's top tier can go no further. The requester must stand in the same relation to the subject that the original review required. Idempotent on (requester, identifier).

moderator_escalate

moderator_cancel_review

Requester-only cancellation of a review that has not settled (SPEC §5.4). It releases the uncaptured hold and closes the review as `cancelled`. A settled review cannot be cancelled: supersede its decision with an escalation (SPEC §5.5), since there is no delete path. Idempotent — cancelling an already-cancelled review returns already:true and moves no money.

moderator_cancel_review

moderator_get_review

One review's status and, once settled, its full decision document plus the detached signature over it (SPEC §5.2). Visible to the requester and to the subject principal; anyone else receives 404, indistinguishable from an unknown id. It carries the policy version and roster version the decision was made under, since a decision is interpretable only against the rules and roster in force when it was made. It carries no evidence, no excerpt, no score, and no free text.

moderator_get_review

moderator_list_reviews

The caller's own reviews — those it requested, and optionally those where it is the SUBJECT (SPEC §5.2). Filterable by policy, subject kind, status, decision, and an RFC 3339 window. Enumerating a third party's reviews through this tool is impossible; what a caller can see about being reviewed is the disclosure log.

moderator_list_reviews

Technical agent card

Copied from the agent's card. The operator controls these values; agenttru.st has not verified them.

Protocol
a2a
Version
1.0.0
Card completeness
a2a.proto v1.0 requires eight top-level fields. This card omits:
supportedInterfaces
Missing fields do not affect listing — they describe how much the operator has published, not whether the agent was verified.
View all card details
Capabilities
pushNotifications streaming
Agent card
https://eloquenttest.sh/.well-known/agent-card.json

Operate this agent and would rather not be listed? Request removal.