Emercoin swap
OfficialThis server is a cashier service for exchanging USDT (TRC20/TRON) for Emercoin (EMC) at a fixed rate, designed for agent-based interactions via MCP — no account or API key required.
Get swap configuration (
get_swap_config): Retrieve the fixed exchange rate (1 USDT = 10 EMC), minimum/maximum order amounts, and operator support email.Open a buy order (
buy_emc): Create an order by specifying a USDT amount (fixed denominations: 5 or 10 USDT) and your destination EMC address. Returns a unique TRON deposit address, the exact USDT amount to send (used as a matching tag), and an order token for tracking. Supports an optional idempotency key to prevent duplicate orders on retries.Poll order status (
get_order_status): Track an order using its token through the full lifecycle:awaiting_payment → confirmed → emc_delivered → notified. Returns the EMC transaction ID once delivered.Cancel an unpaid order (
cancel_order): Abort an order before payment is made, freeing its slot ahead of TTL expiry. Cannot be used once payment is in flight or confirmed.
Key constraints:
Only 5 or 10 USDT orders accepted
Payment must be the exact returned amount — wrong amounts are not refunded
One-way exchange: no refunds
USDT must be sent via TRC20 (TRON network)
AML screening (OFAC SDN + Tether blacklist) is applied to all deposits, which may result in an
aml_holdstatus
Allows buying EMC with USDT (Tether) on the TRON network via TRC20 deposits.
swap — EMC cashier (USDT → EMC)
A minimal cashier exposing one primitive. All business logic stays in the calling services; swap knows nothing about NVS/DNS/subscriptions.
buy_emc(amount_usdt, destination_emc_address, callback_url, ref)
→ collect USDT on a unique deposit address
→ on confirmation, deliver EMC (fixed rate ×10) to destination
→ notify the caller with a SIGNED callbackdestination is opaque to swap: it can be a service's address (the service
then renders its own product on that EMC — the user only ever pays USDT and
never touches a wallet) or the user's own address (raw on-ramp).
Use via MCP
An AI agent with USDT can buy EMC directly — no account, no API key, no callback. swap exposes a keyless MCP exchanger over Streamable HTTP at:
https://swap.emercoin.com/mcpAdd it to a client:
# Claude Code
claude mcp add --transport http swap https://swap.emercoin.com/mcpClaude Desktop — Settings → Connectors → Add custom connector → the URL above.
MCP Inspector —
npx @modelcontextprotocol/inspector→ Streamable HTTP → the URL.
Tools:
Tool | What it does |
| min/max USDT per order + the fixed EMC-per-USDT rate |
| open an order → returns a deposit address + the exact USDT amount to send (+ optional |
| poll an order by its token until delivered |
| drop an unpaid order early |
Flow: get_swap_config → buy_emc(amount, your_emc_address) → send the exact
returned amount (TRC20) to the deposit address → poll get_order_status by token
until notified. One-way, exact-amount, no refunds. The same primitive is also
available as keyed REST (for services, with a signed callback) and a keyless
web page at swap.emercoin.com.
This server is not self-contained — use the hosted endpoint above. Running an order needs deployed infrastructure: an Emercoin node + adapter (the EMC payout rail,
/wallet/send), a TronGrid USDT watcher, a funded EMC reserve, and a configured TRON deposit address. An image built from this repo in isolation — e.g. by a registry/sandbox like Glama — is therefore an introspection target only:tools/list(for tool-definition quality scoring) works with zero config, but execution tools likebuy_emccannot complete without that backing infra (no deposit address → "deposit address not configured"; no adapter → reserve pre-flight fails). That's correct isolation, not a defect. To actually buy EMC, call the hostedhttps://swap.emercoin.com/mcp. The repo never ships the adapter key or any wallet secret — those live only on the deployed host.
Related MCP server: TRON Energy/Bandwidth MCP Server
Locked decisions
Topic | Decision |
Rate | static 1 USDT = 10 EMC |
Amounts | fixed denominations: 5 or 10 USDT (not a free range; floor 5: below it TRON gas dominates). REST/MCP/web validate the input against this exact set |
USDT rail | TRC20 (TRON) |
Payment match | one shared deposit address + unique per-order amount tag |
EMC delivery | via emercoin adapter |
Callback signature | HMAC-SHA256 over canonical body, per-service secret |
KYC | none (amounts far below threshold) |
AML | minimal but mandatory — OFAC SDN + Tether freeze blacklist |
Terms | exact amount, single transfer, one-way (no refunds) — state in the offer |
Layout
swap/
config.py env-driven settings (pydantic-settings)
models.py OrderStatus enum + request/response schemas
states.py order state machine (allowed transitions)
schema.sql DDL: services/orders/deposits/aml_checks/sweeps/callbacks
db.py SQLite connection + init
repository.py DB access layer
auth.py caller auth by API key
orders.py buy_emc business logic (shared by REST + MCP)
main.py FastAPI app (REST: POST /buy_emc, GET /order/{id})
mcp_app.py keyless MCP exchanger at /mcp (agent tools, mirrors /web)
web.py public keyless /web/* channel (raw on-ramp for humans)
site/ static exchanger page + offer (index.html, oferta.html)
clients/
adapter.py EMC delivery + balance via emercoin adapter
trongrid.py TRC20 deposit watcher source (TronGrid)
tron/
hd.py HD derivation of deposit addresses (BIP44, coin 195)
services/
aml.py OFAC + Tether blacklist screening
delivery.py deliver EMC from reserve (idempotent)
callback.py signed callback notifier + retries
watcher.py background loop: deposits → confirm → AML → deliver → notify
sweep.py USDT consolidation from deposit addressesState machine
created → awaiting_payment → confirmed → emc_delivered → notified (done)
↘ underpaid (top-up or partial refund)
↘ overpaid (refund excess)
↘ aml_hold (sender blacklisted → manual)
↘ deliver_failed (retry; else refund USDT)
expired — no payment before TTLDev
uv sync --extra dev
cp .env.example .env # fill secrets
uv run uvicorn swap.main:app --reload --port 8002EMC delivery and the TRON watcher need the emercoin adapter and TronGrid creds;
for local end-to-end you can bring up the node+adapter from emercoin_docker
(docker compose --profile dev up). TRON parts are verified in a test
environment before they are wired into the watcher.
Schema changes have no migrations.
db.pyappliesschema.sqlwithCREATE TABLE IF NOT EXISTS, which does not alter an existing table. After editingschema.sqlin dev, reset the database:rm swap.db(then restart — it recreates the schema — and re-runscripts/register_servicesince theservicestable is wiped too).swap.dbholds only local/test data.
Status: full happy path verified live end-to-end (+ 41 unit tests). On 2026-06-14 a real run took a TRC20 USDT deposit on TRON Nile testnet →
confirmed→ delivered real EMC on Emercoin mainnet (via the adapter/wallet/send) → signed callback verified by the receiver against the service's HMAC secret:awaiting_payment → confirmed → emc_delivered → notified. Seedocs/TESTNET.mdfor the runbook (scripts/testnet/).AML is live: OFAC SDN addresses (TRON) loaded into memory + refreshed, and a per-deposit live Tether
isBlackListedcheck; a hit →aml_hold(no delivery).Payment matching: pivoted from a unique HD address per order to one shared deposit address + a unique per-order amount tag (matched by exact amount). This removes per-order sweeping and the fresh-address gas penalty; the trade-off is exact-amount, single-transfer payments (no auto under/overpaid). Collected USDT is moved to treasury / off-ramp manually at low volume. MCP exchanger: the keyless web on-ramp is also exposed as MCP tools (
buy_emc,get_order_status,cancel_order,get_swap_config) over Streamable HTTP at/mcp, so an AI agent buys EMC with USDT directly — no key, no callback, same anti-spam as the web channel. No auth by design: it's a public "pay for a service" on-ramp, not an account. Tool definitions pass a pre-publication TDQS review (all tier A); seedocs/TDQS.md.Deferred: USDT sweep / TRON tx signing (
services/sweep.py, kept off the hot path).
License
MIT — see LICENSE.
Available Tools
4 toolsbuy_emcBuy EMC with USDT (open an order)A
Open an order to buy EMC with USDT (TRC20) and get back a shared TRON
deposit_address plus the EXACT amount_usdt to send. This does NOT move funds:
you then transfer that exact figure (it is your order's matching tag) to the
deposit address; on confirmed payment, EMC (amount_usdt × rate) is delivered to
your address automatically. Keep the returned token and poll get_order_status
until 'notified'; to abandon before paying, call cancel_order. One-way — a wrong
amount cannot be matched and is NOT refunded. By default each call opens a NEW
order; pass a stable idempotency_key to make retries return the same order. Use
get_swap_config first to pick a valid amount.
| Name | Required | Description | Default |
|---|---|---|---|
| amount_usdt | Yes | USDT to pay; must be one of the allowed denominations from get_swap_config (currently 5 or 10) | |
| destination_emc_address | Yes | your EMC address to receive EMC (legacy 'E…' or bech32 'em1…') | |
| idempotency_key | No | optional: a stable string you choose; retrying buy_emc with the same key + address + amount returns the SAME order instead of opening a new one (use it so a retry after a timeout doesn't create a duplicate) |
Output Schema
| Name | Required | Description |
|---|---|---|
| token | Yes | opaque handle to poll this order |
| order_id | Yes | |
| deposit_address | Yes | |
| amount_usdt | Yes | EXACT amount to send — pay this figure |
| emc_amount | Yes | |
| status | Yes | |
| expires_at | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description clarifies that the tool does NOT move funds, describes the payment flow, and idempotency behavior. It does not contradict annotations (readOnlyHint=false, etc.) and adds beyond them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and process. It is somewhat lengthy but each sentence adds value. Could be slightly more concise, but well-structured.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complexity (financial transaction, multiple steps), the description covers the flow, safety warnings, idempotency, and ties to siblings. Output schema exists but is not shown; still fairly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaning: amount_usdt must be from allowed denominations, idempotency_key explanation for retries, destination_emc_address format examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Open an order to buy EMC with USDT' and outlines the complete process, distinguishing it from sibling tools like cancel_order, get_order_status, and get_swap_config.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It advises to use get_swap_config first to pick a valid amount, explains idempotency for retries, and warns that wrong amounts are not refunded. It covers when to use but could be more explicit about when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cancel_orderCancel an unpaid EMC orderADestructive
Cancel a still-unpaid buy_emc order by its token, expiring it now and freeing
its slot ahead of the TTL. Use this only before you pay; once a payment is in
flight or confirmed it is too late and this errors. A payment sent after
cancellation matches nothing and is NOT refunded. To only inspect an order without
changing it, use get_order_status.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | opaque order handle returned by buy_emc; pass it back unchanged |
Output Schema
| Name | Required | Description |
|---|---|---|
| order_id | Yes | human-quotable order number (DB id) |
| status | Yes | |
| amount_usdt | Yes | |
| emc_amount | Yes | |
| destination_emc_address | Yes | |
| deposit_address | Yes | |
| emc_txid | No | |
| expires_at | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate destructiveHint=true. Description adds that it errors if payment is in flight/confirmed and that payments after cancellation are not refunded. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, front-loaded with the core action and effect. Every sentence is essential and free of fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the simple one-parameter input and the presence of annotations and output schema, the description fully covers usage context, prerequisites, consequences, and error scenarios.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (token) with 100% schema coverage. The description does not add new detail beyond what the schema provides (opaque handle, from buy_emc). Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it cancels an unpaid buy_emc order by token, expiring it and freeing its slot. Distinguishes from sibling get_order_status for inspection.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says use only before payment, warns against using after payment is in flight/confirmed, and notes that post-cancellation payments are not refunded. Provides alternative tool get_order_status for inspection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_order_statusGet EMC order statusARead-onlyIdempotent
Return the current status of a buy_emc order by its token: the status, the
exact amount, the EMC amount and destination address, and the emc_txid once
delivered. Use this to poll after buy_emc — status progresses awaiting_payment →
confirmed → emc_delivered → notified (done). Read-only; to cancel an unpaid order
use cancel_order instead.
| Name | Required | Description | Default |
|---|---|---|---|
| token | Yes | opaque order handle returned by buy_emc; pass it back unchanged |
Output Schema
| Name | Required | Description |
|---|---|---|
| order_id | Yes | human-quotable order number (DB id) |
| status | Yes | |
| amount_usdt | Yes | |
| emc_amount | Yes | |
| destination_emc_address | Yes | |
| deposit_address | Yes | |
| emc_txid | No | |
| expires_at | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and idempotentHint=true. The description adds the status lifecycle, the specific returned fields (amount, EMC amount, destination address, emc_txid), and that it is used for polling. This adds meaningful context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two dense sentences plus a brief note after a dash. The first sentence covers purpose and return values, the second explains usage and status progression. No superfluous words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter, high schema coverage, existing annotations, and an output schema, the description fully explains when to use (polling after buy_emc), what it returns, and how statuses evolve. It also provides cancellation guidance. Completeness is excellent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with a clear description for the token parameter. The tool description echoes the schema's 'by its token' but adds no new meaning. Baseline 3 is appropriate as the schema already documents it well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Return the current status of a buy_emc order by its token', specifying the verb (return), resource (buy_emc order), and key parameter (token). It distinguishes from siblings by mentioning cancel_order for cancellation and implies buy_emc as preceding step.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this to poll after buy_emc' and describes the status progression (awaiting_payment → confirmed → emc_delivered → notified). Also states 'to cancel an unpaid order use cancel_order instead', providing clear context and alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_swap_configGet EMC swap limits and rateARead-onlyIdempotent
Return the current order denominations and fixed rate for buying EMC with USDT.
allowed_amounts is the exact set of USDT values buy_emc accepts (fixed
denominations, not a free range) — pick one of these; min_usdt/max_usdt are its
bounds and emc_per_usdt is the rate (EMC you receive = amount_usdt × emc_per_usdt).
Call this first to choose a valid amount for buy_emc. Read-only — it neither creates
nor changes an order. support_email is the operator contact for manual cases
(e.g. an order on aml_hold or a late/mismatched payment).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| min_usdt | Yes | |
| max_usdt | Yes | |
| allowed_amounts | No | the fixed USDT denominations a buyer may pick |
| emc_per_usdt | Yes | |
| support_email | No | operator contact for manual cases |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and idempotentHint. Description adds that it 'neither creates nor changes an order' and explains the support_email for manual cases, going beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence adds value. Well-structured: purpose, field explanations, usage guidance, read-only note, support contact. No fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters, rich annotations, and low complexity, the description fully covers what the tool does and how to use it. Output schema exists but description complements it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
No parameters, so baseline is 4. Description adds value by explaining output fields, which helps in understanding the tool's result.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it returns current order denominations and fixed rate for buying EMC with USDT. It distinguishes itself from sibling buy_emc by implying it's a prerequisite.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Call this first to choose a valid amount for buy_emc.' Provides clear context for when to use it relative to siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Changed
buy_emc1 field changed- changed
Input schema / properties / amount_usdt / descriptionPrevious value: -"USDT to pay; must be within min/max from get_swap_config"New value: +"USDT to pay; must be one of the allowed denominations from get_swap_config (currently 5 or 10)"
- Changed
get_swap_config1 field changed- added
Output schema / properties / allowed_amountsAdded value: +{ + "description": "the fixed USDT denominations a buyer may pick", + "items": { + "type": "number" + }, + "title": "Allowed Amounts", + "type": "array" +}
4 tool updates
v0.1.0- First observed
buy_emc - First observed
cancel_order - First observed
get_order_status - First observed
get_swap_config
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: initiating an order, canceling unpaid orders, checking status, and retrieving configuration. No functional overlap.
All tool names follow a consistent verb_noun snake_case pattern (buy_emc, cancel_order, get_order_status, get_swap_config), making it easy to predict functionality.
With 4 tools covering the core swap workflow, the count is well-scoped and each tool earns its place without excess or deficiency.
The set covers order creation, cancellation, status polling, and configuration retrieval. Minor gap: no tool for listing a user's full order history, but the core lifecycle is complete.
Maintenance
Related MCP Connectors
On-chain identity and durable memory for AI agents on the Emercoin blockchain (NVS).
TRON Energy marketplace + DEX swap aggregator for AI agents. 27 MCP tools.
No-KYC crypto VPS AI agents rent & run over MCP — 57 tools, pay USDC/USDT on Base/Eth/Polygon/Solana
Non-custodial cross-chain crypto swap MCP — 1288+ assets, no KYC. Solana/EVM/Monero, RPC, oracle.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides complete HTTP/JSON access to all 100+ Emercoin RPC endpoints with integrated formatting utilities. Enables blockchain operations, name system management, wallet functions, and mining operations through a comprehensive REST API interface.MIT
- AlicenseAqualityDmaintenanceTRON Energy & Bandwidth marketplace for AI agents — 27 MCP tools for buying/selling resources, DEX swaps, and automated energy management via Streamable HTTP.272MIT
- AlicenseNot gradedqualityCmaintenanceAI-to-AI marketplace MCP server with 46 tools — swap 65+ crypto tokens on 7 chains, rent GPUs, trade 25 tokenized stocks, on-chain escrow (Solana + Base), DeFi yields, sentiment analysis, wallet monitoring, and image generation. Supports USDC payments across 14 blockchains.MIT

Emercoin Agentofficial
AlicenseNot gradedqualityCmaintenanceIdentity + memory layer for AI agents on the Emercoin blockchain — read open, write via GitHub OAuth8MIT