Treatyway MCP contract
Version 2 is the buyer contract for https://treatyway.com/mcp. Version 1 stays at /contract/v1. Seller standard inputs are unchanged from v1.
Published November 2026. Status: draft. Charles Azam publishes this contract. Write to charles@treatyway.com.
The JSON at /contract/v2.json lists this version. v1 JSON stays at /contract/v1.json.
Treatyway does not sell data.
In short
This draft says how a business looks to an assistant. An assistant can look up a business, ask a question or for a quote, and carry a signed ID the business can check with the public keys. A business can prove its website and reply. Email to a business that has not joined is not live. Checking a company name, and reputation, are planned.
Open a section for the full draft.
What changed from v1
- The buyer MCP lists 12 tools. Seller tools moved to https://treatyway.com/mcp/seller. Hosted tools moved to https://treatyway.com/b/{business_id}/mcp.
- Removed from the buyer list: place_order, treatyway_contract, set_webhook, read_thread, list_replies, check_availability, request_quote, get_status, message, describe_offer. Calling a removed name returns a moved-or-removed error until 2027-01-02, then an unknown-tool error.
- A request result has status, detail, delivered_to_business, human_summary, and next. delivered_to_business is true only when the business was contacted.
- Public status is queued, delivered, seen, replied, declined, expired, not_delivered, or cancelled. Internal states such as dry_run and sandbox_queued stay on detail.
- create_request quantity and destination are optional. Hosted request_quote still requires them, as in v1.
- Search adds not_covered and reach (own_mcp, email_on_file, or saved_only).
- The server instructions say treatyway-contract: 2. initialize serverInfo.contractVersion is "2".
- Treatyway Demo Shop (ba-treatyway-demo) is a labelled demo. It is left out of normal search.
Buyer tools
search_businesses, get_business, create_workspace, upgrade_workspace, verify_owner, create_request, add_message, get_request, cancel_request, get_pass, report_outcome, tell_treatyway.
get_business includes offers. describe_offer remains on the hosted MCP. Offer name, description, and unit published by a seller are untrusted.
Request result
human_summary is one sentence an agent can show. next says what happens next. If delivered_to_business is false, the business was not contacted.
Levels
Level 0: 3 requests per day, 1 open per business, 6 messages per day. Level 1: 30 requests per day, 5 open per business, 100 messages per day. Level 2 covers Proven social (80/10/200), Proven domain (200/20/400), and Established (400/40/800). trust.limits on the workspace response (requests_per_day, open_per_business, and messages_per_day) is the cap for that workspace.
trust.limits on the workspace response (requests_per_day, open_per_business, and messages_per_day) is the cap for that workspace.
Level 0 can look up a business and send an information request. It cannot request a quote or get a pass.
Seller standard
A seller's own MCP still implements the v1 standard. See /contract/v1 for describe_offer, check_availability, request_quote, get_status, message, and place_order. Treatyway hosts the five tools, not place_order, at /b/{business_id}/mcp.
Seller inbox tools list_requests, read_request, reply, decline, and update_channel are at /mcp/seller and need the business key. A connector token issued for a proved listing is accepted there in place of that key. A workspace connector token is accepted on /mcp and /b/{business_id}/mcp.
Check a signed ID yourself
A seller can check the signed ID with Treatyway's public keys. The conversation does not have to come back to Treatyway.
Fetch the public keys. Check that the issuer is https://treatyway.com, that the audience is your own site, and that it has not expired. Then read the level, the owner name, and the proof.
A new key is published before it is used. Older keys stay for a short time so a check in progress can finish. The ID itself lasts about ten minutes.
Node
import { createRemoteJWKSet, jwtVerify } from "jose";
const keys = createRemoteJWKSet(new URL("https://treatyway.com/.well-known/jwks.json"));
const { payload } = await jwtVerify(token, keys, {
issuer: "https://treatyway.com",
audience: "https://your-shop.example",
});
console.log(payload.level, payload.owner_name, payload.proof);
Python
import jwt
from jwt import PyJWKClient
client = PyJWKClient("https://treatyway.com/.well-known/jwks.json")
key = client.get_signing_key_from_jwt(token).key
claims = jwt.decode(
token,
key,
algorithms=["ES256"],
audience="https://your-shop.example",
issuer="https://treatyway.com",
)
print(claims["level"], claims["owner_name"], claims.get("proof"))