GYOTAK Fish Market
Sashimi-grade flash-frozen fish from Thailand. Catalog, ordering, and on-chain traceability.
Should I use this
Quality & Safety
Based on automated analysis of tool definitions and protocol compliance.
Context Cost
This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.
Install
One-Click Install
Add this to your `claude_desktop_config.json` file:
{
"mcpServers": {
"fish-market": {
"url": "https://line-harness.gyotak.workers.dev/mcp"
}
}
}Remote endpoints
https://line-harness.gyotak.workers.dev/mcpstreamable-httphttps://mcp.gyotakuprotocol.com/mcpstreamable-httpWhat it can do
Tool inventory
Tools (23)
๐ขget_catalog(lineUserId, customerKey)
Get GYOTAK's full fish catalog with real-time availability, retail prices (THB/kg), freshness tiers, and traceability records. Retail prices are always included. For registered chat customers, pass customerKey (gyotak_cus_...) to show wholesale pricing and enable one-tap checkout. For LINE VIP customers, pass lineUserId. Delivery is available within Thailand only. International addresses are not accepted.
Input Schema
{
"type": "object",
"properties": {
"lineUserId": {
"type": "string",
"description": "LINE user ID for VIP pricing (optional)"
},
"customerKey": {
"type": "string",
"description": "GYOTAK customerKey (gyotak_cus_...) for registered chat customers โ enables identification, wholesale pricing, and one-tap checkout (optional)"
}
},
"required": []
}Output Schema
{
"type": "object",
"properties": {
"items": {
"type": "array",
"description": "Catalog lines in the order shown (empty when no stock)",
"items": {
"type": "object",
"description": "One line of the catalog text",
"properties": {
"section": {
"type": "string",
"description": "Section heading (LINE VIP order-page catalog only)"
},
"fishName": {
"type": "string"
},
"thaiName": {
"type": "string"
},
"label": {
"type": "string",
"description": "Card label shown in parentheses (LINE VIP order-page catalog only)"
},
"preferred": {
"type": "boolean",
"description": "true when marked โ
(preferred fish)"
},
"status": {
"type": "string",
"description": "Cut / preparation as shown"
},
"tier": {
"type": "string",
"description": "Fresh / Tier1 / Tier2, or \"all\" for lines listed as [all tiers]"
},
"days": {
"type": "integer",
"description": "Days tier shown next to the tier (LINE VIP order-page catalog only)"
},
"weightKg": {
"type": "number",
"description": "Stock weight as shown (kg, one decimal)"
},
"packs": {
"type": "integer",
"description": "Stock packs as shown"
},
"priceThbPerKg": {
"type": "number",
"description": "Price shown for this line (THB/kg). Retail for anonymous callers, the customer's own price when vip is present"
},
"priceOnRequest": {
"type": "boolean",
"description": "true when the line shows \"price on request\""
},
"orderUpToKg": {
"type": "number",
"description": "Shown as \"order up to โฆkg\"; 0 when shown as \"cannot be ordered by kg right now\""
},
"orderAs": {
"type": "object",
"description": "Status and tier to pass to place_order, as shown after โ",
"properties": {
"status": {
"type": "string"
},
"tier": {
"type": "string"
}
},
"required": [
"status",
"tier"
]
},
"bands": {
"type": "object",
"description": "Packs per weight band, as listed under ๐ฆ",
"additionalProperties": {
"type": "integer"
}
},
"catchRecordCount": {
"type": "integer",
"description": "Number of catch records in the traceability line"
},
"catchRecords": {
"type": "array",
"description": "Up to 3 catch records as listed",
"items": {
"type": "object",
"properties": {
"photoAt": {
"type": "string"
},
"location": {
"type": "string"
},
"blogUrl": {
"type": "string"
}
},
"required": [
"photoAt"
]
}
},
"onchain": {
"type": "array",
"description": "Midnight on-chain links as listed",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string"
},
"tier": {
"type": "string"
},
"url": {
"type": "string"
},
"moreRecords": {
"type": "integer"
}
},
"required": [
"network",
"url"
]
}
}
},
"required": [
"fishName",
"weightKg"
]
}
},
"vip": {
"type": "object",
"description": "Customer line shown for a registered customer",
"properties": {
"companyName": {
"type": "string"
},
"tierPricing": {
"type": "boolean",
"description": "true when shown as \"tier pricing applied\""
},
"orderMode": {
"type": "string",
"enum": [
"view_only",
"line_order_page",
"chat"
],
"description": "LINE VIP order-page catalog: catalog browsing only / order from the LINE VIP order page / order in this chat"
},
"shippingZone": {
"type": "string",
"description": "\"0\" = local (free), otherwise the zone number shown"
},
"cashbackRemainingThb": {
"type": "number"
},
"cashbackLimitThb": {
"type": "number"
}
},
"required": [
"companyName"
]
},
"customerContext": {
"type": "object",
"description": "Used by the catalog widget"
},
"catalog": {
"type": "array",
"description": "Used by the catalog widget (on-chain provenance per item)",
"items": {
"type": "object"
}
},
"nextActions": {
"type": "array",
"description": "Used by the catalog widget (buttons)"
}
},
"required": [
"items"
]
}๐ขsearch_fish(query, lineUserId)
Search fish by name (Japanese, Thai, or English). Provide lineUserId to include VIP tier pricing.
Input Schema
{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Fish name to search for"
},
"lineUserId": {
"type": "string",
"description": "LINE user ID for VIP pricing (optional)"
}
},
"required": [
"query"
]
}Output Schema
{
"type": "object",
"properties": {
"query": {
"type": "string"
},
"vipCompanyName": {
"type": "string",
"description": "Shown as (VIP: โฆ) when VIP pricing is applied"
},
"results": {
"type": "array",
"items": {
"type": "object",
"properties": {
"fishName": {
"type": "string"
},
"thaiName": {
"type": "string"
},
"tier": {
"type": "string"
},
"status": {
"type": "string"
},
"weightKg": {
"type": "number"
},
"packs": {
"type": "integer"
},
"priceThbPerKg": {
"type": "number",
"description": "VIP price (only shown for VIP callers)"
}
},
"required": [
"fishName",
"tier",
"status",
"weightKg",
"packs"
]
}
}
},
"required": [
"query",
"results"
]
}๐ขget_contact_info
Get the two ways to buy from GYOTAK, with the contact details for each: retail (order here through place_order, or browse the web shop) and B2B wholesale for restaurants and businesses (LINE @284ezjvm, tier pricing, application required). Call this when the user asks how to buy, how to open a wholesale account, or how to reach GYOTAK. Takes no arguments and returns static text โ for product availability or prices use get_catalog, and for other questions use ask_gyotak.
Input Schema
{
"type": "object",
"properties": {},
"required": []
}๐ขget_catch_reports(date, tier)
Get catch records by date or freshness tier. Returns the catch date, the region (district name), the blog post URL when published and, for records registered on the Midnight blockchain, a verify link per batch. Exact GPS coordinates are never returned: on v3 records the exact position is not on the chain (only a commitment to it); the district name is a label set by GYOTAK. GYOTAK checks the region range when recording, but the range used is not part of the record, so a third party cannot confirm it from the chain; GYOTAK can disclose the position of a record individually. In-stock products reference these records by date. To check a record on-chain without trusting GYOTAK, open its verify link, or call verify_catch with network "mainnet", the v3 contract address given in the response and the batch ID.
Input Schema
{
"type": "object",
"properties": {
"date": {
"type": "string",
"description": "YYYY-MM-DD format. Returns records for that specific date."
},
"tier": {
"type": "string",
"enum": [
"fresh",
"tier1",
"tier2"
],
"description": "Freshness tier: fresh=last 30 days, tier1=31-60 days, tier2=61-90 days"
}
},
"required": []
}Output Schema
{
"type": "object",
"properties": {
"count": {
"type": "integer"
},
"limit": {
"type": "integer",
"description": "Present when only the most recent records are shown"
},
"verifyCatchContract": {
"type": "object",
"description": "Arguments for verify_catch on v3 records",
"properties": {
"network": {
"type": "string"
},
"contractAddress": {
"type": "string"
}
},
"required": [
"network",
"contractAddress"
]
},
"reports": {
"type": "array",
"items": {
"type": "object",
"properties": {
"date": {
"type": "string"
},
"createdAt": {
"type": "string"
},
"location": {
"type": "string",
"description": "District name (or \"Unknown\")"
},
"blogUrl": {
"type": "string"
},
"onchain": {
"type": "array",
"items": {
"type": "object",
"properties": {
"batchId": {
"type": "string"
},
"scheme": {
"type": "string",
"enum": [
"v3",
"legacy",
"out_of_scope"
]
},
"verifyUrl": {
"type": "string"
}
},
"required": [
"batchId",
"scheme"
]
}
}
},
"required": [
"date",
"createdAt",
"location",
"onchain"
]
}
}
},
"required": [
"count",
"reports"
]
}๐กplace_order(lineUserId, customerKey, fishName, requestedKg, totalThb, ...)
Place an order. Two modes: (A) VIP wholesale: provide lineUserId of a registered VIP customer. (B) Guest retail: provide customerName, phone, items array, and a delivery address โ shippingAddress, shippingProvince and email are all required, and an order missing any of them is rejected. Guest orders are priced at tier-linked retail rates (server-calculated) and the total is final at this point; a confirmation email with a PromptPay QR follows. Without customerKey or a personal token URL connection, every order creates a new customer with a new customerKey, even when the email was used before (orders are never linked to an existing customer by email); the new key is returned in the response and the confirmation email โ tell the user to save it. Inventory is NOT deducted โ orders go to the pick queue for staff fulfillment. Delivery is available within Thailand only, so the province must be a Thai one. International addresses are not accepted. (C) LINE VIP customer connected through a personal token URL (get_catalog says ordering is available in this chat): send vipItems only โ one entry per item, with fishName, status and tier exactly as get_catalog shows them and the quantity in the form get_catalog gives for that item (bands, packs or kg). The server calculates prices, shipping and the total; the total is an estimate, billing is by invoice after picking, and no payment is taken now. Call with dryRun: true first, show the user the lines and the estimate, and place the order only after the user confirms.
Input Schema
{
"type": "object",
"properties": {
"lineUserId": {
"type": "string",
"description": "LINE user ID of VIP customer (VIP mode). Omit for guest mode."
},
"customerKey": {
"type": "string",
"description": "(Guest mode) Registered customer key (from register_customer). Resolves name/phone/shipping automatically. If you are connected through a personal token URL the customer is already resolved: send items[] alone and omit this, customerName, phone and lineUserId."
},
"fishName": {
"type": "string",
"description": "(VIP mode) Fish name (romaji)"
},
"requestedKg": {
"type": "number",
"description": "(VIP mode) Requested weight in kg"
},
"totalThb": {
"type": "number",
"description": "(VIP mode) Total amount in THB"
},
"customerName": {
"type": "string",
"description": "(Guest mode) Customer name"
},
"phone": {
"type": "string",
"description": "(Guest mode) Contact phone number"
},
"items": {
"type": "array",
"description": "(Guest mode) Order items",
"items": {
"type": "object",
"properties": {
"fishName": {
"type": "string"
},
"status": {
"type": "string",
"description": "Cut / preparation of the fish (e.g. \"sashimi fillet\"). Pass the status shown for this fish in get_catalog, verbatim. Optional: when omitted the server fills it in from stock, and asks which one if more than one cut is available."
},
"tier": {
"type": "string",
"enum": [
"Fresh",
"Tier1",
"Tier2"
]
},
"band": {
"type": "string",
"description": "Weight band (e.g. \"140-180g\")"
},
"qty": {
"type": "number",
"description": "Number of packs"
}
},
"required": [
"fishName",
"tier",
"band",
"qty"
]
}
},
"shippingAddress": {
"type": "string",
"description": "(Guest mode) Street address and building name โ required for guest orders"
},
"shippingProvince": {
"type": "string",
"description": "(Guest mode) Thai province name, used for shipping cost โ required for guest orders. Thailand only."
},
"shippingDistrict": {
"type": "string",
"description": "(Guest mode) Hua Hin / Pranburi ็ญใฎๅฐๅ
้
้ๅคๅฎใซๅฟ
้ ใไฝๆใซๅซใพใใฆใใใฐ่ชๅๅคๅฎใใใใๆ็คบๆจๅฅจ / District name. Required to detect local (free) delivery for Hua Hin / Pranburi. Auto-detected from shippingAddress when present, but explicit value recommended."
},
"email": {
"type": "string",
"description": "(Guest mode) Email address for the order confirmation โ required for guest orders"
},
"lang": {
"type": "string",
"enum": [
"ja",
"en",
"th"
],
"description": "(Guest mode, optional) Language of the confirmation email. Defaults to en."
},
"referrerId": {
"type": "string",
"description": "(Optional) Referrer ID for tracking"
},
"memo": {
"type": "string",
"description": "(Optional) Order notes"
},
"vipItems": {
"type": "array",
"description": "(LINE VIP mode only) Order lines for a LINE VIP customer connected through a personal token URL. Ignored in other modes.",
"items": {
"type": "object",
"properties": {
"fishName": {
"type": "string"
},
"status": {
"type": "string",
"description": "As shown in get_catalog for this item"
},
"tier": {
"type": "string",
"enum": [
"Fresh",
"Tier1",
"Tier2",
"All"
],
"description": "As shown in get_catalog (All for cooking, prepared and whole cooking items)"
},
"bands": {
"type": "object",
"description": "Packs per weight band, e.g. {\"140-180g\": 3} โ only for items get_catalog marks as ordered by bands",
"additionalProperties": {
"type": "number"
}
},
"packs": {
"type": "number",
"description": "Total packs โ only for items ordered by packs"
},
"kg": {
"type": "number",
"description": "Kilograms in steps of 0.5, or exactly the stock shown โ only for items ordered by kg"
}
},
"required": [
"fishName",
"status",
"tier"
]
}
},
"dryRun": {
"type": "boolean",
"description": "(LINE VIP mode only) true = return the lines and the estimated total without placing the order"
}
}
}๐ขget_order_history(lineUserId)
Get B2B order history (last 20 orders). Requires lineUserId of a registered VIP customer.
Input Schema
{
"type": "object",
"properties": {
"lineUserId": {
"type": "string",
"description": "LINE user ID of the VIP customer"
}
},
"required": [
"lineUserId"
]
}๐ขmy_orders(document, ref)
Order history of a LINE VIP customer connected through their personal token URL (gyk_โฆ). No arguments needed โ the customer is the owner of this connection. Lists each order (and each invoice not tied to an order) with its date, status (paid / unpaid / overdue / cancelled / awaiting picking / awaiting invoice), the invoice total and due date when an invoice exists, and the items with requested kg โ actual kg from the invoice. Invoices and receipts are not linked in the text: the user opens them from the buttons in the catalog widget (Orders tab). Chat-registered customers cannot list orders here; the Receipt button in their widget calls this tool with document=receipt and ref=<order id> to get a 15-minute receipt link for a paid order. Not for guests.
Input Schema
{
"type": "object",
"properties": {
"document": {
"type": "string",
"enum": [
"invoice",
"receipt"
],
"description": "Used only by the widget buttons. Do not set it when the user asks for their orders."
},
"ref": {
"type": "string",
"description": "Used only by the widget buttons (an order or invoice id from this tool's result)."
}
}
}๐ขverify_catch(contractAddress, batchId, network)
Verify a GYOTAK catch record DIRECTLY from the Midnight blockchain. Reads on-chain state and returns the raw hex plus decoded fields for independent verification. Unlike get_catch_reports (GYOTAK's own list of records: date, district and verify links, never GPS), this lets you verify without trusting GYOTAK. The exact position is not on the chain (only a commitment to it). The region name is a label set by GYOTAK. GYOTAK checks the region range when recording, but the range used is not part of the record, so a third party cannot confirm it from the chain. Supports both preprod and mainnet. batchId also accepts several IDs separated by commas: they are all checked against a single fetch of the contract state, and the response lists found/not-found per ID.
Input Schema
{
"type": "object",
"properties": {
"contractAddress": {
"type": "string",
"description": "Midnight contract address (64-char hex). Example: bc33d8c05852decd4ef183201a8a9f3c25eabaa46a81786f306b95397ed118ab"
},
"batchId": {
"type": "string",
"description": "Filter to a specific catch record by batchId (e.g. \"CR-20261021-37b2b7be\"). Omit to return all records in the contract."
},
"network": {
"type": "string",
"enum": [
"preprod",
"mainnet"
],
"description": "Midnight network (default: mainnet)"
}
},
"required": [
"contractAddress"
]
}Output Schema
{
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Same text as content when the input or the lookup failed"
},
"message": {
"type": "string",
"description": "Same text as content when there is nothing to show"
},
"customer_summary": {
"type": "string"
},
"presentation_guidance": {
"type": "string"
},
"verify_urls": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"source": {
"type": "object",
"description": "Where the on-chain state was read from",
"properties": {
"indexer_url": {
"type": "string"
},
"contract_address": {
"type": "string"
},
"network": {
"type": "string"
},
"block_height": {
"type": "integer"
},
"tx_hash": {
"type": "string"
}
},
"required": [
"indexer_url",
"contract_address",
"network"
]
},
"raw_state": {
"type": "string"
},
"raw_state_sha256": {
"type": "string"
},
"raw_state_length_bytes": {
"type": "integer"
},
"results": {
"type": "array",
"description": "Several batch IDs",
"items": {
"type": "object",
"properties": {
"batch_id": {
"type": "string"
},
"found": {
"type": "boolean"
},
"offsets": {
"type": "array",
"items": {
"type": "integer"
}
},
"window_hex": {
"type": "string"
},
"decoded": {
"type": "object"
}
},
"required": [
"batch_id",
"found"
]
}
},
"found": {
"type": "boolean"
},
"match_type": {
"type": "string"
},
"batchId_queried": {
"type": "string"
},
"occurrences": {
"type": "integer"
},
"match_offsets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"offset": {
"type": "integer"
},
"window_hex": {
"type": "string"
},
"window_start": {
"type": "integer"
}
}
}
},
"tentative_records": {
"type": "array",
"items": {
"type": "object"
}
},
"tentative_records_note": {
"type": "string"
},
"records": {
"type": "array",
"description": "All catch records (no batchId given)",
"items": {
"type": "object"
}
},
"gps_recoverable": {
"type": "boolean"
},
"verification_note": {
"type": "string"
}
}
}๐ขverify_temp(contractAddress, freezerId, hourStartUtc, network)
Verify GYOTAK cold-chain storage temperatures DIRECTLY from the Midnight blockchain. Reads on-chain state and returns decoded hourly temperature records per freezer for independent verification. Unlike the dashboard (which reads from GYOTAK's D1 database), this lets you verify without trusting GYOTAK. Each value is the HOURLY AVERAGE committed on-chain; it does not prove the temperature stayed within any limit at every moment in that hour. Supports both preprod and mainnet.
Input Schema
{
"type": "object",
"properties": {
"contractAddress": {
"type": "string",
"description": "Midnight temp-log contract address (64-char hex). Default: mainnet production contract."
},
"freezerId": {
"type": "number",
"description": "Filter to a specific freezer by ID. Omit to return all freezers."
},
"hourStartUtc": {
"type": "string",
"description": "Filter to a specific hour (e.g. \"2026-07-09 11:00:00\"). Omit to return all hours."
},
"network": {
"type": "string",
"enum": [
"preprod",
"mainnet"
],
"description": "Midnight network (default: mainnet)"
}
}
}Output Schema
{
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Same text as content when the input or the lookup failed"
},
"message": {
"type": "string",
"description": "Same text as content when there is nothing to show"
},
"availableFreezerIds": {
"type": "array",
"description": "Listed when the filter matched nothing",
"items": {
"type": "integer"
}
},
"source": {
"type": "object",
"description": "Where the on-chain state was read from",
"properties": {
"indexer_url": {
"type": "string"
},
"contract_address": {
"type": "string"
},
"network": {
"type": "string"
},
"block_height": {
"type": "integer"
},
"tx_hash": {
"type": "string"
}
},
"required": [
"indexer_url",
"contract_address",
"network"
]
},
"total_records": {
"type": "integer"
},
"freezers": {
"type": "array",
"items": {
"type": "object",
"properties": {
"freezerId": {
"type": "integer"
},
"records": {
"type": "array",
"items": {
"type": "object",
"properties": {
"hourStartUtc": {
"type": "string"
},
"avgTempC": {
"type": "number"
}
},
"required": [
"hourStartUtc",
"avgTempC"
]
}
}
},
"required": [
"freezerId",
"records"
]
}
},
"verification_note": {
"type": "string"
}
}
}๐ขget_komon_records(status)
Get GYOTAK KOMON physical authentication records from the database. Each record represents a PUF (physically unclonable function) registration with minutiae extraction and on-chain commitment. Shielded records do not expose GPS.
Input Schema
{
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"pending",
"live"
],
"description": "Filter by status (default: all non-test)"
}
},
"required": []
}๐ขverify_komon(contractAddress, komonId, network)
Verify a GYOTAK KOMON record directly from the Midnight blockchain. Reads on-chain state and returns the raw hex plus decoded fields for independent verification. Unlike get_komon_records (which returns GYOTAK's database), this reads directly from the chain. Shielded records do not put the GPS coordinates on the chain, only a hash of them (gpsHash); the region is a label set by GYOTAK. GYOTAK checks the region range when recording, but the range used is not stored in the record, so the region cannot be confirmed from the chain. Currently preprod only.
Input Schema
{
"type": "object",
"properties": {
"contractAddress": {
"type": "string",
"description": "Midnight komon contract address (64-char hex)"
},
"komonId": {
"type": "string",
"description": "Filter to a specific komon record by ID. Omit to return all records."
},
"network": {
"type": "string",
"enum": [
"preprod",
"mainnet"
],
"description": "Midnight network (default: preprod)"
}
},
"required": []
}Output Schema
{
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Same text as content when the input or the lookup failed"
},
"message": {
"type": "string",
"description": "Same text as content when there is nothing to show"
},
"availableKomonIds": {
"type": "array",
"description": "Listed when no record matched komonId",
"items": {
"type": "string"
}
},
"source": {
"type": "object",
"description": "Where the on-chain state was read from",
"properties": {
"indexer_url": {
"type": "string"
},
"contract_address": {
"type": "string"
},
"network": {
"type": "string"
},
"block_height": {
"type": "integer"
},
"tx_hash": {
"type": "string"
}
},
"required": [
"indexer_url",
"contract_address",
"network"
]
},
"raw_state": {
"type": "string"
},
"records": {
"type": "array",
"items": {
"type": "object",
"properties": {
"komonId": {
"type": "string"
},
"region": {
"type": "string"
},
"privacyMode": {
"type": "string"
},
"photoHash": {
"type": "string"
},
"komonCommit": {
"type": "string"
},
"gpsHash": {
"type": "string"
},
"lat": {
"type": "number"
},
"lng": {
"type": "number"
},
"committedAt": {
"type": "number"
}
},
"required": [
"komonId"
]
}
},
"gps_recoverable": {
"type": "boolean"
},
"verification_note": {
"type": "string"
}
}
}๐ขask_gyotak(question)
Search GYOTAK FAQ for answers about shipping, payment, products, defrosting, traceability, B2B registration, etc. Returns top matching FAQ entries. If no match, suggest using contact_gyotak to escalate.
Input Schema
{
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "Question text (any language)"
}
},
"required": [
"question"
]
}๐กcontact_gyotak(question, name)
Submit a question to GYOTAK staff when FAQ does not have the answer. Staff will reply via Discord. Use check_reply to retrieve the response later.
Input Schema
{
"type": "object",
"properties": {
"question": {
"type": "string",
"description": "Question to ask GYOTAK staff"
},
"name": {
"type": "string",
"description": "Your name (optional)"
}
},
"required": [
"question"
]
}๐ขcheck_reply(inquiryId)
Check if GYOTAK staff has replied to a previously submitted inquiry.
Input Schema
{
"type": "object",
"properties": {
"inquiryId": {
"type": "string",
"description": "Inquiry ID (e.g. \"INQ-042\")"
}
},
"required": [
"inquiryId"
]
}๐กregister_customer(name, phone, address, email, customerType)
Register as a GYOTAK customer. Collect name, phone, address, email, and customer type (Retail or Wholesale) via conversation BEFORE calling this tool. Returns a customerKey for future orders. Save the key in your AI memory.
Input Schema
{
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Full name (English)"
},
"phone": {
"type": "string",
"description": "Contact phone number"
},
"address": {
"type": "string",
"description": "Shipping address"
},
"email": {
"type": "string",
"description": "Email address (optional)"
},
"customerType": {
"type": "string",
"enum": [
"Retail",
"Wholesale"
],
"description": "Customer type: Retail (consumer) or Wholesale (business)"
}
},
"required": [
"name",
"phone",
"address",
"customerType"
]
}๐ขrecover_customer_key(phone)
Explains where a lost customerKey can be found: a key issued with an order is written in the order confirmation email sent to the registered address (each order placed without a key has its own key). For keys that cannot be found there, it points to contact_gyotak. This tool does not look up, verify or send anything.
Input Schema
{
"type": "object",
"properties": {
"phone": {
"type": "string",
"description": "Phone number used at registration"
}
},
"required": [
"phone"
]
}โชapply_referrer(customerKey, name, contact)
Look up your GYOTAK referral MCP URL. The URL is issued automatically when the payment for your first chat order is confirmed and is included in the payment confirmation email; call this to see it again. If you have a paid order but no URL yet, one is issued now. Referrers earn 5% of the product subtotal on paid orders placed through their URL. If you are connected through a personal token URL, omit customerKey.
Input Schema
{
"type": "object",
"properties": {
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
},
"name": {
"type": "string",
"description": "Referrer display name โ optional, defaults to your registered name"
},
"contact": {
"type": "string",
"description": "Contact (email, LINE ID, etc.) โ optional"
}
},
"required": []
}๐ขmy_referrals(customerKey)
Show your referral summary as a GYOTAK referrer: your referral URL, number of referred orders (paid / unpaid), this month's estimated commission, unpaid balance, payout destination status, and the last 5 paid referred orders (order number, date, subtotal, commission โ no buyer details). Only works for the customer of this connection; if you are connected through a personal token URL, omit customerKey.
Input Schema
{
"type": "object",
"properties": {
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
}
},
"required": []
}๐กget_share_kit(customerKey, includePhotos)
Get the facts and constraints for writing a social media post about GYOTAK with the caller's referral URL: order facts, fish photo URLs, verification page URLs of the caller's stamped purchase proofs, allowed and forbidden claims, and the required referral disclosure. The wording is up to the user and their assistant. Call this again each time the user asks for a post; do not reuse a previous result.
Input Schema
{
"type": "object",
"properties": {
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
},
"includePhotos": {
"type": "boolean",
"description": "Set true only if the user wants to attach a photo they take themselves with a blockchain capture record. Returns photo_capture_url and the list of recorded photos."
}
},
"required": []
}๐ขverify_purchase(purchaseId, customerKey)
Show a purchase proof and trace it: purchase โ catch โ storage temperature. Use this when the customer asks to see what they bought, where it was caught or how it was stored. Pass the customerKey from this conversation, or a purchase ID (PB-โฆ). Read-only; returns only stamped (on-chain) proofs, with the arguments for verify_catch and verify_temp.
Input Schema
{
"type": "object",
"properties": {
"purchaseId": {
"type": "string",
"description": "Purchase ID (PB-YYYYMMDD-xxxxxxxx). Takes precedence over customerKey."
},
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
}
},
"required": []
}Output Schema
{
"type": "object",
"properties": {
"error": {
"type": "string",
"description": "Same text as content when the input or the lookup failed"
},
"message": {
"type": "string",
"description": "Same text as content when there is nothing to show"
},
"purchase_proofs": {
"type": "array",
"items": {
"type": "object",
"description": "Purchase proof traced to catch and storage",
"properties": {
"purchase_id": {
"type": "string"
},
"network": {
"type": "string"
},
"order_date": {
"type": [
"string",
"null"
]
},
"verify_url": {
"type": "string"
},
"contract_address": {
"type": "string"
},
"test_customer_order": {
"type": "boolean"
},
"corrected": {
"type": "boolean"
},
"items": {
"type": "array",
"items": {
"type": "string"
}
},
"lots": {
"type": "array",
"items": {
"type": "object",
"properties": {
"catch_report_id": {
"type": [
"string",
"null"
]
},
"catch_date": {
"type": [
"string",
"null"
]
},
"area": {
"type": [
"string",
"null"
]
},
"fish": {
"type": "array",
"items": {
"type": "string"
}
},
"fish_of_the_day": {
"type": "array",
"items": {
"type": "string"
}
},
"catch_batches": {
"type": "array",
"items": {
"type": "object",
"properties": {
"batch_id": {
"type": "string"
},
"verify_url": {
"type": "string"
},
"verify_catch": {
"type": [
"object",
"null"
],
"properties": {
"contractAddress": {
"type": "string"
},
"batchId": {
"type": "string"
},
"network": {
"type": "string"
}
}
}
},
"required": [
"batch_id",
"verify_url"
]
}
},
"missing_reason": {
"type": [
"string",
"null"
]
},
"storage_average_c": {
"type": [
"number",
"null"
]
}
}
}
},
"storage": {
"type": "object",
"properties": {
"average_c": {
"type": [
"number",
"null"
]
},
"missing_reason": {
"type": [
"string",
"null"
]
},
"stays": {
"type": "array",
"items": {
"type": "object",
"properties": {
"freezer_id": {
"type": "integer"
},
"from": {
"type": "string"
},
"to": {
"type": "string"
}
}
}
},
"verify_temp": {
"type": "array",
"items": {
"type": "object",
"properties": {
"network": {
"type": "string"
},
"freezerId": {
"type": "integer"
},
"hourStartUtc": {
"type": "string"
}
}
}
},
"note": {
"type": "string"
}
}
},
"notes": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"purchase_id",
"network",
"verify_url",
"items",
"lots",
"storage"
]
}
},
"pending_stamp": {
"type": "integer",
"description": "Proofs of this customer still waiting to be stamped"
},
"older_not_shown": {
"type": "integer",
"description": "Older proofs not shown"
}
}
}๐กreport_share(platform, post_url, customerKey)
Report a social media post you published that recommends GYOTAK with your referral URL. Call this right after posting, with the platform and the public URL of the post. GYOTAK records it and later verifies that the post is public and contains the referral URL.
Input Schema
{
"type": "object",
"properties": {
"platform": {
"type": "string",
"enum": [
"x",
"instagram",
"facebook",
"threads",
"line",
"other"
],
"description": "Platform the post was published on"
},
"post_url": {
"type": "string",
"description": "Public https URL of the published post"
},
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
}
},
"required": [
"platform",
"post_url"
]
}๐ดclaim_purchase_proof(handle, purchase_id, auto_bind, consent)
Link your own purchasesโ on-chain purchase proofs to your X (Twitter) account, so a post of yours can be checked against the chain. Buyerโs X account (self-declared): the buyer linked this purchase to their own X account; GYOTAK has not checked that the account belongs to the buyer. Each stamped purchase comes with the URL of its public verification page. Only works through a personal token URL connector โ there is no customerKey argument. Called with no arguments it only lists the purchases that can be linked and links nothing, every time โ pass handle to actually link. A link is stamped on chain and cannot be undone, so let the user pick the handle before you pass one. Automatic binding of future purchases is off by default: to turn it on, pass handle with auto_bind "on" โ the first such call returns the consent text; show it to the user word for word (the text is in Japanese and English; show both), and only if they agree call again with consent true. Pass auto_bind "off" to stop it (no handle needed); only later purchases stop, anything already recorded stays.
Input Schema
{
"type": "object",
"properties": {
"handle": {
"type": "string",
"description": "Your X handle without the leading @ (letters, digits and underscore, 1-15 characters). Required to link: a call without it only lists your purchases and links nothing, even if you linked before. Pass it on every link."
},
"purchase_id": {
"type": "string",
"description": "Link only this purchase (e.g. \"PB-20260917-a97953d3\"). Omit to link every purchase of yours that is not linked yet."
},
"auto_bind": {
"type": "string",
"enum": [
"on",
"off"
],
"description": "Turn automatic binding of future purchases to your X handle on or off. \"on\" needs handle and consent. \"off\" needs nothing else. Omit to leave the setting as it is."
},
"consent": {
"type": "boolean",
"description": "Set true only when the user has read the consent text returned by an earlier auto_bind \"on\" call and agreed to it. Never set it on your own."
}
},
"required": []
}๐ดregister_payout(customerKey)
Email the GYOTAK referrer a link to the form where they register where their commission should be sent: a Thai PromptPay QR (read inside the form, the image is never uploaded) or a stablecoin address (USDC on Base, or USDM on Cardano). Call this when the user wants to register, see, or change their payout destination. Returns the destination currently on file, masked, and the masked address the link was sent to. For security the form URL is never shown in the chat โ the link goes only to the email address on file, so tell the user to open it from their email. Never ask the user to type the number or the wallet address into the chat.
Input Schema
{
"type": "object",
"properties": {
"customerKey": {
"type": "string",
"description": "Your customerKey (gyotak_cus_...). Omit when connected through a personal token URL."
}
},
"required": []
}Community
Evidence