Connection check
verified live · 27h ago
agent-broker
23 MCP tools: compliance, verification, messaging, booking and US contract search. 13 keyless.
Tools
23
GitHub stars
1
Installs / wk
305
Licence
MIT
Transport
streamable-http, stdio
Last checked
27h ago
Tools & capabilities
23 toolsRead from the running server on 27h ago.
call_business
can modify data
smb_idobjective*country_codeon_behalf_ofbusiness_phoneextract_fields
+2
Place a conversational voice-AI phone call to a business on a consumer's behalf and return a structured answer. THE differentiated capability: reach the tens of millions of long-ta… Place a conversational voice-AI phone call to a business on a consumer's behalf and return a structured answer. THE differentiated capability: reach the tens of millions of long-tail SMBs that have NO API and NO booking page — only a phone number. An AI agent cannot pick up a phone and hold a conversation; this tool does. Give a plain-language objective; the voice AI navigates the call and extracts the answer. Business-directed (B2B), far less restricted than calling consumers — but the compliance gate still enforces recording consent per jurisdiction. Async: returns a call handle; poll get_outcome for the transcript + extracted fields. WHEN TO USE: Use when the target business has NO booking URL and NO API — only a phone number — and the consumer asked the agent to reach them (e.g. 'call this plumber and ask if they can come Tuesday', 'ask the salon if they take walk-ins this afternoon'). Also use to confirm details a booking page doesn't expose (real-time availability, custom quotes). WHEN NOT TO USE: Do NOT use when the business has a booking URL — use import_booking_url + schedule_appointment (cheaper, faster, deterministic). Do NOT use for calls to consumers/individuals (this tool is for reaching businesses). Do NOT use for marketing or telemarketing — the compliance gate and the B2B-only framing reject that. COST: $0.2 per_call LATENCY: ~45000ms EXECUTION: async_by_default (use get_outcome to retrieve result)
capture_lead
smb_id*sourceprospect*idempotency_key
Structured intake of a prospect into an SMB's funnel with validation and deduplication on (smb_id, phone or email). Stores the prospect in the SMB's AgentBroker lead funnel — this… Structured intake of a prospect into an SMB's funnel with validation and deduplication on (smb_id, phone or email). Stores the prospect in the SMB's AgentBroker lead funnel — this is AgentBroker's own lead store, NOT a write into the business's own CRM. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Tell smb_xyz I'm interested and want a callback" -> call capture_lead({"smb_id": "smb_xyz", "prospect": {"name": "Jane", "phone": "+15551234567", "email": "[email protected]"}, "source": "agent"}) WHEN TO USE: Use when a potential customer has expressed interest in an SMB's service and you want to ensure they are registered in the SMB's pipeline for follow-up. WHEN NOT TO USE: Do not use for confirmed bookings — use schedule_appointment. Do not use for bulk list imports. COST: $0.05 per_call LATENCY: ~600ms EXECUTION: sync_fast (use get_outcome to retrieve result)
check_booking_link
read-only
url*
Free, instant pre-flight check for a booking URL. Classifies which booking platform a URL belongs to and tells you whether import_booking_url will accept it, WITHOUT fetching the p… Free, instant pre-flight check for a booking URL. Classifies which booking platform a URL belongs to and tells you whether import_booking_url will accept it, WITHOUT fetching the page or spending money. Returns the platform, the exact smb_id import_booking_url would assign, the channels the booking will route through, and the inferred country. Use it to de-risk a paid booking BEFORE calling import_booking_url + schedule_appointment. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Is this a bookable link? https://cal.com/jane" -> call check_booking_link({"url": "https://cal.com/jane"}) -> then import_booking_url({"booking_url": "https://cal.com/jane"}) user: "Can you book me here: https://www.opentable.com/r/acme-bistro" -> call check_booking_link({"url": "https://www.opentable.com/r/acme-bistro"}) WHEN TO USE: Call this the moment a user pastes a URL and you are not sure it is a bookable page, or before you commit to a paid schedule_appointment. It is free and sub-100ms, so run it as a guard: if supported=true, proceed to import_booking_url with confidence; if supported=false, fall back to find_business or call_business instead of wasting a booking attempt. WHEN NOT TO USE: Do not use to confirm the page is currently live/available — this tool does not fetch the URL, it only classifies its shape. It is not a substitute for import_booking_url (which actually registers the business) or verify_business (which confirms an already-imported smb_id). COST: free - no key required LATENCY: ~20ms
check_compliance
read-only
channelcontent*state_codecountry_codemessage_typerecipient_id*
Free, instant pre-flight for the compliance gate. Runs the SAME TCPA / GDPR / CASL / CAN-SPAM / 10DLC gate that send_message and call_business run — but in preview mode, so NO mess… Free, instant pre-flight for the compliance gate. Runs the SAME TCPA / GDPR / CASL / CAN-SPAM / 10DLC gate that send_message and call_business run — but in preview mode, so NO message is sent and NO state changes. Tells you whether a (recipient, channel, message_type, content) send would be permitted BEFORE you pay for it, and if not, names the exact rule and how to remediate. Use it to de-risk a paid send the same way check_booking_link de-risks a paid booking. Attaches a compliance_receipt: an Ed25519-signed, hash-bound record of what was checked, when, against which sources, and what it returned - verifiable OFFLINE against the public key published at https://hatchloop.dev/agents.md, so you can hand it to an auditor as evidence the check really ran. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Is it legal to text this US number a 20%-off promo?" -> call check_compliance({"recipient_id": "+14045550200", "content": "20% off this week only!", "channel": "sms", "message_type": "marketing", "country_code": "US"}) user: "Before you email the dentist, make sure it's allowed" -> call check_compliance({"recipient_id": "[email protected]", "content": "Do you accept Cigna? Following up on my request.", "message_type": "follow_up"}) -> then send_message({"recipient": {"id_type": "email", "id_value": "[email protected]"}, "message_type": "follow_up", "content": {"body": "Do you accept Cigna? Following up on my request."}}) WHEN TO USE: Call this the moment before send_message or call_business when there is any chance the send is regulated — anything tagged marketing, any SMS to a US number (10DLC), any message to an EU/UK (GDPR) or Canadian (CASL) recipient, or any content you are unsure about. It is free and sub-100ms, so run it as a guard: if legal=true, proceed to send_message with confidence; if legal=false, fix the cited blocker instead of burning a paid, rejected send. WHEN NOT TO USE: Do not treat a legal=true as a permanent license — the gate re-runs at send time, so a fresh opt-out between preview and send still blocks. Do not use it to check two-party voice recording consent (that is evaluated at call time in the voice adapter, not here). It is not a substitute for send_message; it never delivers anything. COST: free - no key required LATENCY: ~15ms
check_quota
read-only
Returns the caller's current quota state: how many operations have been used today, how many remain, the daily limit, the tier (free / credits / unlimited), and when the quota rese… Returns the caller's current quota state: how many operations have been used today, how many remain, the daily limit, the tier (free / credits / unlimited), and when the quota resets. Read-only and free. Works with any valid X-Agent-Identity token; returns tier='anonymous' for keyless callers with the anonymous daily limits. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "How many API calls do I have left today?" -> call check_quota({}) user: "Check my quota before sending messages" -> call check_quota({}) user: "When does my rate limit reset?" -> call check_quota({}) WHEN TO USE: Call at session start or before a batch of write operations to confirm you have enough remaining quota. Use when a user asks how many API calls they have left today. Also useful after a rate_limited error to understand when the quota resets. WHEN NOT TO USE: Do not call on every single tool invocation — quota is also injected into every write-tool response in the 'quota' field. Only call proactively when you need the current state without performing an operation. COST: free - no key required LATENCY: ~5ms
escalate_to_human
can modify data
reason*smb_id*context*priorityidempotency_key
Hand off an in-flight task to a human operator with a full context bundle: transcript, prior actions, identifiers, and a recommended next step. EXAMPLE USER QUERIES THAT MATCH THI… Hand off an in-flight task to a human operator with a full context bundle: transcript, prior actions, identifiers, and a recommended next step. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "I'm stuck — get a human at smb_xyz to call me back" -> call escalate_to_human({"smb_id": "smb_xyz", "reason": "automation_failed", "context": {"original_operation": "schedule_appointment", "recommended_next_step": "Call the business directly to confirm the slot"}, "priority": "urgent"}) WHEN TO USE: Use when automated resolution has failed after channel-fallback exhaustion, when the task requires human judgment, or when the customer has explicitly requested human contact. WHEN NOT TO USE: Do not use as a first resort. Escalate only after automated resolution attempts. COST: $0.2 per_call LATENCY: ~2000ms EXECUTION: async_by_default (use get_outcome to retrieve result)
find_business
read-only
location*vertical*capabilityprice_bandmax_resultsavailability_window
Given criteria (vertical, location, capability, price band, availability window), return ranked candidate businesses from our supply network. THE NETWORK IS SMALL AND STILL MOSTLY… Given criteria (vertical, location, capability, price band, availability window), return ranked candidate businesses from our supply network. THE NETWORK IS SMALL AND STILL MOSTLY SAMPLE DATA: entries that are not real are named [DEMO] and flagged is_demo - check that field before acting on a result. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Find me a salon in Tokyo that does color" -> call find_business({"vertical": "personal_services", "location": {"zip_or_city": "Tokyo"}, "capability": "color"}) user: "I need a plumber near 30309" -> call find_business({"vertical": "home_services", "location": {"zip_or_city": "30309"}, "capability": "plumbing"}) user: "Show me dentists in London" -> call find_business({"vertical": "professional_services", "location": {"zip_or_city": "London"}, "capability": "dentist"}) WHEN TO USE: Use when an agent needs to identify which SMBs can fulfill a business task (booking, service, consultation) in a given location and vertical. Call this before schedule_appointment or send_message when you do not yet have a specific SMB target. WHEN NOT TO USE: Do not use as a general directory or browsing surface. Do not use when you already have a specific verified SMB identifier. Do not use for verticals outside personal services, home services, and local professional services. COST: free - no key required LATENCY: ~200ms
get_conversation
read-only
referencebusiness_numberconversation_id
Read a two-way conversation thread you started: its state, every message exchanged, and how many replies the business has sent. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user:… Read a two-way conversation thread you started: its state, every message exchanged, and how many replies the business has sent. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Did the salon reply about Sara's booking?" -> call get_conversation({"conversation_id": "conv_1a2b3c4d"}) user: "Check request 4821 with that barber" -> call get_conversation({"reference": "4821", "business_number": "96890000001"}) WHEN TO USE: After send_message with on_behalf_of returns a conversation_id, poll this to read the business's reply. Replies are matched to the right thread exactly (never guessed), so what you read here belongs to YOUR end-user. WHEN NOT TO USE: Do not poll more often than every 10 seconds. COST: free - no key required LATENCY: ~300ms
get_outcome
read-only
operation_id*
Retrieve the final OutcomeReceipt for a completed operation. WHEN TO USE: Use after get_status returns success/failure/partial to retrieve the full result with cost and reason cod… Retrieve the final OutcomeReceipt for a completed operation. WHEN TO USE: Use after get_status returns success/failure/partial to retrieve the full result with cost and reason codes. WHEN NOT TO USE: Do not use for operations still in pending/executing state — use get_status first. COST: free - no key required LATENCY: ~50ms
get_status
read-only
operation_id*
Query the current state of any in-flight async operation by operation_id. WHEN TO USE: Use to poll the state of a pending_async operation when no webhook callback has arrived or t… Query the current state of any in-flight async operation by operation_id. WHEN TO USE: Use to poll the state of a pending_async operation when no webhook callback has arrived or to check progress. WHEN NOT TO USE: Do not poll more frequently than once per 10 seconds — use webhook delivery for real-time updates instead. COST: free - no key required LATENCY: ~50ms
handle_inbound
sendersmb_id*raw_message*routing_rulesidempotency_keyinbound_channel*
+1
Classify an inbound message on behalf of an SMB and get a recommended next action. Classifies intent (booking request, cancellation, opt-out, inquiry, complaint) and returns a sugg… Classify an inbound message on behalf of an SMB and get a recommended next action. Classifies intent (booking request, cancellation, opt-out, inquiry, complaint) and returns a suggested_action for YOUR agent to act on - opt-outs are recorded durably; nothing else is auto-routed or auto-executed by this tool. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Process this customer reply for me: 'Yes I want to book Tuesday'" -> call handle_inbound({"smb_id": "smb_xyz", "inbound_channel": "sms", "raw_message": "Yes I want to book Tuesday"}) WHEN TO USE: Use when an SMB needs inbound message triage — classifying incoming contact-form submissions, SMS replies, voicemails, or email inquiries. WHEN NOT TO USE: Do not use for outbound communications. Do not use for compliance-flagged recipient lists without verified opt-in records. COST: $0.03 per_call LATENCY: ~3000ms EXECUTION: async_by_default (use get_outcome to retrieve result)
import_booking_url
verticalbooking_url*capabilitiescountry_codebusiness_namecontact_email
+2
Turn ANY public booking URL (Cal.com, Calendly, Doctolib, Booksy, Fresha, OpenTable, Setmore, Square, Acuity, Schedulista, Squarespace, BookMyCity) into a callable smb_id you can i… Turn ANY public booking URL (Cal.com, Calendly, Doctolib, Booksy, Fresha, OpenTable, Setmore, Square, Acuity, Schedulista, Squarespace, BookMyCity) into a callable smb_id you can immediately use with schedule_appointment, send_message, or capture_lead. Idempotent — calling twice returns the same smb_id. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Book me a haircut at https://cal.com/jane-salon" -> call import_booking_url({"booking_url": "https://cal.com/jane-salon", "vertical": "personal_services"}) -> then schedule_appointment({"smb_id": "<from_above>", "action": "book"}) user: "Schedule with this dentist: https://www.doctolib.fr/dentiste/paris/jean-dupont" -> call import_booking_url({"booking_url": "https://www.doctolib.fr/dentiste/paris/jean-dupont"}) user: "Reserve a table at https://www.opentable.com/r/acme-bistro" -> call import_booking_url({"booking_url": "https://www.opentable.com/r/acme-bistro", "vertical": "restaurants"}) WHEN TO USE: Call this FIRST whenever the user provides a specific booking URL (cal.com/handle, calendly.com/handle/event, doctolib.fr/..., booksy.com/..., opentable.com/r/..., etc.). User patterns that match: 'book me at https://cal.com/...', 'schedule with calendly.com/jane/intro', 'reserve a table at opentable.com/r/...', 'I want to book this dentist: https://www.doctolib.fr/...'. After importing, the returned smb_id can be passed straight to schedule_appointment. WHEN NOT TO USE: Do not use if the user only describes a business by name without a URL — call find_business instead. Do not use for arbitrary websites that are not on the supported booking-platform list (use /supply/platforms to see all 12). COST: free (no credits) - but requires a free email-verified key LATENCY: ~600ms
lookup_us_contracts
read-only
max_resultscompany_name*
Search US federal contract awards by company (recipient) name using the free USASpending.gov public API. Returns the top awards sorted by dollar amount: award ID, recipient name, a… Search US federal contract awards by company (recipient) name using the free USASpending.gov public API. Returns the top awards sorted by dollar amount: award ID, recipient name, award amount USD, awarding agency, NAICS code/description, and period of performance. Zero upstream cost, no key required. Data covers 2020-2026 procurement contracts. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Does Palantir have US government contracts?" -> call lookup_us_contracts({"company_name": "Palantir Technologies"}) user: "What federal contracts does Booz Allen Hamilton have?" -> call lookup_us_contracts({"company_name": "Booz Allen Hamilton", "max_results": 5}) user: "Find US import supplier data for Lockheed Martin" -> call lookup_us_contracts({"company_name": "Lockheed Martin"}) user: "Which government agencies are customers of SAIC?" -> call lookup_us_contracts({"company_name": "SAIC", "max_results": 10}) WHEN TO USE: Use when you need to know whether a company is a US federal contractor, which government agencies have awarded it contracts, the dollar value and NAICS sector of those contracts, and the period of performance. Useful for supplier due-diligence, vendor qualification, competitive intelligence, and import/trade research. The target demand: "us import data api", "supplier lookup api", "company trade records", "who has government contracts", "federal contractor search". WHEN NOT TO USE: Do not use for non-US companies (USASpending.gov only covers US federal contracts). Do not use as an exhaustive financial-risk or sanctions screen -- use verify_company_record and screen_sanctions for those. Do not use for state/local government contracts (federal only). COST: free - no key required LATENCY: ~1200ms
map_trade_restriction
read-only
hs_codepartiesproduct*origin_countrydestination_country*
Free cross-border trade screening of the DESTINATION and the PARTIES. IT DOES NOT CLASSIFY THE PRODUCT: the product argument is recorded and echoed back, never checked against any… Free cross-border trade screening of the DESTINATION and the PARTIES. IT DOES NOT CLASSIFY THE PRODUCT: the product argument is recorded and echoed back, never checked against any export-control list, so a controlled item to an unrestricted destination returns no findings and reason_code 'partial' -- never 'clear'. This is not an export-control clearance; classify the item (HS/ECCN) against BIS/EU/UK controls yourself. Given a product and destination country (and optionally an HS code, origin country, and a list of parties to screen), returns: (a) whether the destination or any party hits an export-control or sanctions restriction, (b) the destination risk level (comprehensive_embargo / sectoral_sanctions / elevated_scrutiny / standard), (c) HS code hint if the caller provided one, (d) honest tariff guidance + official links without fabricated rates, and (e) party sanctions screening against OFAC SDN (US Treasury), the EU Consolidated list (European Commission) and the UK Sanctions List (FCDO). Acts as a MIDDLEMAN -- unifies the OFAC comprehensive-embargo map, our own indexed copies of the EU and UK lists, and OFAC SDN into one clean call. Never fabricates a tariff rate, a clear, or a restricted status. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Can we ship laptops to Iran?" -> call map_trade_restriction({"product": "laptop computers", "destination_country": "IR"}) user: "Screen this supplier before we import from them: Mahan Air, Iran" -> call map_trade_restriction({"product": "aircraft parts", "destination_country": "US", "parties": ["Mahan Air"]}) user: "Is exporting hydraulic pumps to Russia restricted?" -> call map_trade_restriction({"product": "hydraulic pumps", "hs_code": "8413.50", "destination_country": "RU"}) user: "Check if we can sell medical devices to Germany, supplier is ACME GmbH" -> call map_trade_restriction({"product": "medical devices", "origin_country": "US", "destination_country": "DE", "parties": ["ACME GmbH"]}) WHEN TO USE: Use before any cross-border trade to flag embargoed destinations, screen exporters/importers/freight forwarders against sanctions lists, and get authoritative links to the applicable tariff databases. Call this as a pre-flight check before quoting, invoicing, or shipping internationally. Covers OFAC comprehensively-embargoed countries (Iran, North Korea, Cuba, Syria) and significant advisory countries (Russia, Belarus, Ukraine Crimea/DNR/LNR regions). WHEN NOT TO USE: Do NOT use as a substitute for a licensed export compliance review. Do NOT use to obtain authoritative tariff rates (this tool returns guidance links, never fabricated rates). Do NOT use for purely domestic shipments where no cross-border movement is involved. COST: free within the daily quota, then $0.02 per call LATENCY: ~3000ms
mint_key
nonce*agent_id*signature*timestamp*
Agent self-serve API key issuance. An autonomous agent that has no email inbox can obtain a free-tier API key by proving it holds the MACHINE_MINT_SECRET via HMAC-SHA256. Returns a… Agent self-serve API key issuance. An autonomous agent that has no email inbox can obtain a free-tier API key by proving it holds the MACHINE_MINT_SECRET via HMAC-SHA256. Returns a usable key immediately with no human action required. If the operator has not activated a mint secret on the server, this returns an honest not_configured failure rather than a key - call it once and branch on that before planning around it. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "I need an API key to call AgentBroker tools" -> call mint_key({"agent_id": "my-agent-abc123", "timestamp": 1725100000, "nonce": "4f8a2c1d", "signature": "<HMAC-SHA256(agent_id+timestamp+nonce, MACHINE_MINT_SECRET)>"}) WHEN TO USE: Use when an AI agent needs to self-provision a write-capable API key without a human email address. The caller must know the MACHINE_MINT_SECRET (available from hatchloop.dev/docs/#machine-mint). WHEN NOT TO USE: Do not use if the agent has a human operator who can complete the email flow at /keys/request. Do not use for paid plans — this endpoint issues free-tier keys (100 ops/day) only. COST: free - no key required LATENCY: ~100ms
preview_cost
read-only
params*operation*
Return an expected cost estimate, latency estimate, and success-probability estimate for a proposed call before execution. Returns the exact price when it is fixed, and a min/max r… Return an expected cost estimate, latency estimate, and success-probability estimate for a proposed call before execution. Returns the exact price when it is fixed, and a min/max range when the cost depends on channel or outcome. It does not promise an accuracy percentage - check cost_range. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "How much will this SMS cost me?" -> call preview_cost({"operation": "send_message", "params": {"preferred_channel": "sms"}}) user: "Estimate the cost of booking via voice fallback" -> call preview_cost({"operation": "schedule_appointment", "params": {"preferred_channel": "voice"}}) WHEN TO USE: Use before any operation when the agent is operating under a budget constraint and needs to decide whether to proceed. WHEN NOT TO USE: Do not use in a hot loop — cache the result for at least 60 seconds if repeating the same preview. COST: free - no key required LATENCY: ~100ms
schedule_appointment
can modify data
notesaction*smb_id*servicecustomerrequested_time
+2
Availability lookup, hold, confirm, reschedule, or cancel appointments with an SMB. Routes through the SMB's native booking system if available, falls back to voice AI or web form.… Availability lookup, hold, confirm, reschedule, or cancel appointments with an SMB. Routes through the SMB's native booking system if available, falls back to voice AI or web form. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Book the haircut for next Tuesday at 3pm" -> call schedule_appointment({"smb_id": "smb_imp_abc", "action": "book", "service": "haircut"}) user: "Cancel my Friday appointment at smb_xyz" -> call schedule_appointment({"smb_id": "smb_xyz", "action": "cancel"}) user: "Reschedule my dental cleaning to next week" -> call schedule_appointment({"smb_id": "smb_imp_xyz", "action": "reschedule"}) WHEN TO USE: Use when an agent needs to book, reschedule, or cancel a specific appointment with a specific SMB. Requires a verified smb_id. WHEN NOT TO USE: Do not use for bulk scheduling. Do not use without a verified SMB — call find_business and verify_business first if needed. COST: from $0.15 per_call_variable (see preview_cost for exact) LATENCY: ~5000ms EXECUTION: async_by_default (use get_outcome to retrieve result)
screen_sanctions
read-only
name*typecountry
Free screening of a name or entity against official sanctions lists, each fetched from the authority that issues it: the OFAC SDN list from the US Treasury (SDN.CSV plus ALT.CSV fo… Free screening of a name or entity against official sanctions lists, each fetched from the authority that issues it: the OFAC SDN list from the US Treasury (SDN.CSV plus ALT.CSV for alternate spellings), the EU consolidated financial sanctions list from the European Commission, and the UK Sanctions List from the FCDO. THE UN CONSOLIDATED LIST IS NOT SCREENED -- it carries no licence permitting commercial redistribution, so we do not claim it. ALWAYS check lists_screened on the response: it names the lists that actually ran ON THAT CALL, and a list that failed to load appears in sources_unavailable instead. reason_code is 'partial_screening' whenever any source was unavailable, never 'clear'. Returns screening_status ('hit' | 'clean' | 'candidates' | 'not_screened' -- branch on THIS, not on matched, because matched:false is also false when nothing could be screened), matched: bool, a list of matches with score, program, and source URL, and which lists were screened. Never fabricates a match or a clear -- if no match is found, explicitly names which lists were checked. Attaches a compliance_receipt: an Ed25519-signed, hash-bound record of what was checked, when, against which sources, and what it returned - verifiable OFFLINE against the public key published at https://hatchloop.dev/agents.md, so you can hand it to an auditor as evidence the check really ran. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Screen this vendor before we pay them: ACME Trading LLC, Russia" -> call screen_sanctions({"name": "ACME Trading LLC", "country": "RU", "type": "entity"}) user: "Is Kim Jong-un on the OFAC list?" -> call screen_sanctions({"name": "Kim Jong-un", "country": "KP", "type": "person"}) user: "Run a sanctions check on this person before onboarding" -> call screen_sanctions({"name": "Ivan Petrov", "country": "RU", "type": "person"}) user: "Do a compliance check -- is this company sanctioned?" -> call screen_sanctions({"name": "Mahan Air", "country": "IR", "type": "entity"}) WHEN TO USE: Use before onboarding a counterparty, processing a payment, engaging a vendor, or doing any due-diligence step that requires knowing whether a person or entity appears on official sanctions lists. Essential for agents doing business formation, vendor qualification, payments onboarding, trade compliance, or any workflow where a sanctioned counterparty is a legal or reputational risk. WHEN NOT TO USE: Do not use as a substitute for full KYC/AML screening -- this covers sanctions lists only, not PEP (Politically Exposed Person) databases, adverse media, or credit risk. Do not treat a negative result as a compliance clearance; it is informational only. Do not use for bulk screening of large lists -- each call is a live API query. COST: free within the daily quota, then $0.02 per call LATENCY: ~2000ms
self_test
read-only
Service health probe: runs 6 internal checks and reports how many passed. Confirms the server is up and responding - it does NOT probe each tool individually. Use to verify connect… Service health probe: runs 6 internal checks and reports how many passed. Confirms the server is up and responding - it does NOT probe each tool individually. Use to verify connectivity before production use. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Run a health check before I send the broadcast" -> call self_test({}) WHEN TO USE: Use at agent startup, before high-stakes task sequences, or after receiving unexpected errors to check if the service is degraded. WHEN NOT TO USE: Do not call more than once per minute in production. COST: free - no key required LATENCY: ~200ms
send_message
can modify data
content*recipient*business_idsend_at_isomessage_type*on_behalf_of
+2
Send a message on behalf of an agent's user or an SMB across WhatsApp (free during launch), SMS, email, or voice. Five message types: transactional, reminder, follow_up, notificati… Send a message on behalf of an agent's user or an SMB across WhatsApp (free during launch), SMS, email, or voice. Five message types: transactional, reminder, follow_up, notification, marketing. Every send routes through a non-bypassable compliance gate (TCPA, GDPR, CASL, PDPL across 26 jurisdictions) that enforces opt-in consent for marketing/promotional content — marketing without recorded consent is rejected at runtime with a structured compliance_violation receipt. Channel is abstracted: specify intent and recipient; the service selects and falls back across channels. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Text the salon I'll be 10 minutes late" -> call send_message({"recipient": {"id_type": "smb_id", "id_value": "smb_xyz"}, "message_type": "notification", "content": {"body": "Running about 10 minutes late for my appointment."}, "preferred_channel": "sms"}) user: "Email the dentist about insurance" -> call send_message({"recipient": {"id_type": "email", "id_value": "[email protected]"}, "message_type": "transactional", "content": {"body": "Do you accept Cigna insurance?"}, "preferred_channel": "email"}) WHEN TO USE: Use to: (a) confirm a booking the agent just made, (b) reply to a customer who messaged the SMB first, (c) follow up on a quote the user requested, (d) send appointment reminders the SMB owes its customer, (e) send marketing messages to recipients who have opted in (with consent_record_id). The gate verifies consent on every send. WHEN NOT TO USE: Do NOT use for OTPs or critical transactional confirmations — use send_transactional_confirmation. Do NOT attempt to send marketing without a consent_record_id pointing at a real opt-in — the gate will reject the send and log a compliance_violation. Do NOT attempt bulk / list-based / drip / cold outreach — those are out of scope and the rate limiter will throttle abuse. COST: from $0.02 per_call_variable (see preview_cost for exact) LATENCY: ~800ms EXECUTION: sync_fast (use get_outcome to retrieve result)
send_transactional_confirmation
can modify data
data*recipient*idempotency_keyconfirmation_type*preferred_channel
Idempotent transactional messages: OTPs, booking confirmations, payment receipts, cancellation notices. Falls back across configured channels; an unconfigured channel fails honestl… Idempotent transactional messages: OTPs, booking confirmations, payment receipts, cancellation notices. Falls back across configured channels; an unconfigured channel fails honestly rather than reporting a delivery that did not happen. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Send the booking confirmation receipt to my email" -> call send_transactional_confirmation({"recipient": {"id_type": "email", "id_value": "[email protected]"}, "confirmation_type": "booking_confirmation", "data": {"appointment_time": "2026-09-03T15:00:00Z", "business_name": "Salon 718"}, "preferred_channel": "email"}) WHEN TO USE: Use for any message that MUST be delivered reliably — OTPs, booking confirmations, receipts. Do not use for marketing. WHEN NOT TO USE: Do not use for marketing or promotional messages. Do not use for conversational messages. COST: $0.02 per_call LATENCY: ~500ms EXECUTION: sync_fast (use get_outcome to retrieve result)
verify_business
read-only
smb_id*capability_to_verify
Look up what we know about a business in our supply network: its contact channels, capabilities, and when the record was last verified. This is a DIRECTORY LOOKUP - it does not con… Look up what we know about a business in our supply network: its contact channels, capabilities, and when the record was last verified. This is a DIRECTORY LOOKUP - it does not contact the business. EXAMPLE USER QUERIES THAT MATCH THIS TOOL: user: "Confirm smb_imp_abc actually does emergency plumbing" -> call verify_business({"smb_id": "smb_imp_abc", "capability_to_verify": "emergency_plumbing"}) WHEN TO USE: Use before sending communications or scheduling if you have an unverified SMB identifier, or if the agent's task requires confirmed capability (e.g., 'I need to be sure they do emergency plumbing'). WHEN NOT TO USE: Do not use if the SMB was returned from find_business within the last 24 hours — those results are already verified. COST: free - no key required LATENCY: ~500ms
verify_company_record
read-only
leiname*country