Global B2B trade: verified manufacturers, product search, sanctions screening, HS codes.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Add a message to an existing feedback ticket of the current visitor — when they remember a detail ("only in Chrome") after the ticket was created. Do NOT create a second ticket for the same problem. Identity comes from the visitor pass; a ticket that is not theirs is simply not found.
What the person wants to add
ticket_id returned by create_feedback_ticket
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Add a message to an existing feedback ticket of the current visitor — when they remember a detail ("only in Chrome") after the ticket was created. Do NOT create a second ticket for the same problem. Identity comes from the visitor pass; a ticket that is not theirs is simply not found.
| Argument | Type | Description |
|---|---|---|
| message* | string | What the person wants to add |
| ticket_id* | string | ticket_id returned by create_feedback_ticket |
{
"type": "object",
"required": [
"ticket_id",
"message"
],
"properties": {
"message": {
"type": "string",
"maxLength": 4000,
"description": "What the person wants to add"
},
"ticket_id": {
"type": "string",
"description": "ticket_id returned by create_feedback_ticket"
}
},
"additionalProperties": false
}Check whether an HS customs code falls under EU dual-use export controls (Regulation 2021/821 and equivalents), optionally for a specific destination country. A match means the goods may need an export licence. Use it after lookup_hs_code, before the person commits to a shipment.
| Argument | Type | Description |
|---|---|---|
| locale | string | |
| hs_code* | string | HS code from lookup_hs_code. |
| destination | string | Destination country (ISO-2). |
{
"type": "object",
"required": [
"hs_code"
],
"properties": {
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string"
},
"hs_code": {
"type": "string",
"pattern": "^[0-9]{2,10}$",
"description": "HS code from lookup_hs_code."
},
"destination": {
"type": "string",
"pattern": "^[A-Z]{2}$",
"description": "Destination country (ISO-2)."
}
},
"additionalProperties": false
}Screen a company or a person against consolidated sanctions, politically-exposed-person and law-enforcement lists (EU, US, UK, UN, Ukraine), sourced from OpenSanctions. Returns possible matches with a similarity score. Use it before the person commits to a counterparty. Treat a match as a reason to verify further, not as proof.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Defaults to 10. |
| query* | string | Name, alias, or company string to screen. |
| topic | string | |
| country | string | ISO 3166-1 alpha-2. |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Defaults to 10."
},
"query": {
"type": "string",
"maxLength": 200,
"minLength": 2,
"description": "Name, alias, or company string to screen."
},
"topic": {
"enum": [
"sanction",
"pep",
"crime",
"export",
"other"
],
"type": "string"
},
"country": {
"type": "string",
"pattern": "^[A-Z]{2}$",
"description": "ISO 3166-1 alpha-2."
}
},
"additionalProperties": false
}Close a feedback ticket of the current visitor when they say it is no longer relevant or they worked it out. A ticket the team already finished (fixed or declined) is NOT closed — say so instead. Identity comes from the visitor pass.
| Argument | Type | Description |
|---|---|---|
| reason | string | Optional: why they close it |
| ticket_id* | string | ticket_id returned by create_feedback_ticket |
{
"type": "object",
"required": [
"ticket_id"
],
"properties": {
"reason": {
"type": "string",
"maxLength": 500,
"description": "Optional: why they close it"
},
"ticket_id": {
"type": "string",
"description": "ticket_id returned by create_feedback_ticket"
}
},
"additionalProperties": false
}Record a feedback ticket for the Gemalli team: a question, a problem or a suggestion. Call it ONCE, only after the person confirmed the wording you read back to them. Identity is taken from the visitor pass — never pass a user id. For a visitor who is not signed in, contact_email is required: without it there is no way to tell them it was fixed.
| Argument | Type | Description |
|---|---|---|
| kind* | string | question = asks something · bug = something is broken · idea = suggestion |
| locale* | string | Language to answer in, e.g. ru / uk / en |
| message* | string | The request in the person’s own words |
| subject* | string | Short summary as you understood it |
| page_url | string | Platform page the person was on |
| transcript | array | Last turns of the conversation (max 20 turns / 8000 chars; longer is trimmed, not rejected) |
| contact_email | string | Required when the visitor is not signed in |
{
"type": "object",
"required": [
"kind",
"subject",
"message",
"locale"
],
"properties": {
"kind": {
"enum": [
"question",
"bug",
"idea"
],
"type": "string",
"description": "question = asks something · bug = something is broken · idea = suggestion"
},
"locale": {
"type": "string",
"description": "Language to answer in, e.g. ru / uk / en"
},
"message": {
"type": "string",
"maxLength": 4000,
"description": "The request in the person’s own words"
},
"subject": {
"type": "string",
"maxLength": 200,
"description": "Short summary as you understood it"
},
"page_url": {
"type": "string",
"description": "Platform page the person was on"
},
"transcript": {
"type": "array",
"items": {
"type": "object",
"required": [
"role",
"text"
],
"properties": {
"at": {
"type": "string",
"description": "ISO timestamp of the turn. Send it: without timestamps we cannot tell this topic from an earlier conversation and simply take the last turns."
},
"role": {
"enum": [
"user",
"agent"
],
"type": "string"
},
"text": {
"type": "string"
}
},
"additionalProperties": false
},
"description": "Last turns of the conversation (max 20 turns / 8000 chars; longer is trimmed, not rejected)"
},
"contact_email": {
"type": "string",
"description": "Required when the visitor is not signed in"
}
},
"additionalProperties": false
}Read the buyer-search package offer — what the person buys in the «find buyers» order window: plans with prices in USD, company quotas, country limits, top-up rules, roles, the order stages and — for an HS code — the clarifying question and the buyer segments that fit each answer. These are prices of the BUYER-SEARCH PACKAGE, shown openly in the order window; they are not Gemalli subscription plans, so the get_subscription_plans rule about never stating prices does not apply here. Use it in the sales chat to answer questions and to suggest a plan and segments. You only suggest: the person chooses and pays in the order window, never through you. Right now it is a demo — payment is a test with no charge, company search and emails are switched off — say so plainly and never promise buyers: a company becomes a buyer only by answering. Texts come in the call locale (uk, ru, en; others fall back to en).
| Argument | Type | Description |
|---|---|---|
| locale | string | Language of the texts: uk, ru or en (others fall back to en). |
| hs_code | string | HS code of the product from the page context (2 to 10 digits) — picks the clarifying question and the segments. |
{
"type": "object",
"properties": {
"locale": {
"type": "string",
"description": "Language of the texts: uk, ru or en (others fall back to en)."
},
"hs_code": {
"type": "string",
"description": "HS code of the product from the page context (2 to 10 digits) — picks the clarifying question and the segments."
}
},
"additionalProperties": false
}Reasons a person can pick after rating the agent, already translated into their language. Call it once when the widget opens and cache it; re-read when the platform says the dictionary changed, or lazily by the `rev` value. Two lists: `reasons` are the live ones to draw in the window, `retired` are switched off and are only there so old feedback stays readable. If this door is silent, show the free-text field anyway and still count the thumb — never drop a rating.
| Argument | Type | Description |
|---|---|---|
| locale | string | Language of the person, e.g. ru / uk / de-AT. Falls back exact → base → English, never Russian. |
{
"type": "object",
"required": [],
"properties": {
"locale": {
"type": "string",
"description": "Language of the person, e.g. ru / uk / de-AT. Falls back exact → base → English, never Russian."
}
},
"additionalProperties": false
}Read one feedback ticket of the current visitor with its whole conversation: the original request, what they added later and what the team answered. Use it to SHOW the ticket, not to decide anything — the team answers, the agent does not answer on their behalf. Identity comes from the visitor pass.
| Argument | Type | Description |
|---|---|---|
| ticket_id* | string | ticket_id returned by create_feedback_ticket |
{
"type": "object",
"required": [
"ticket_id"
],
"properties": {
"ticket_id": {
"type": "string",
"description": "ticket_id returned by create_feedback_ticket"
}
},
"additionalProperties": false
}Fetch one manufacturer's full profile: company description, country, certifications, and the identifiers of the same profile in other languages. Use it after list_manufacturers or search_products, when the person wants to know who the supplier is.
| Argument | Type | Description |
|---|---|---|
| slug* | string | Manufacturer slug (per-locale or base). |
| locale | string | Locale for the returned translation. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "Manufacturer slug (per-locale or base)."
},
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string",
"description": "Locale for the returned translation."
}
},
"additionalProperties": false
}Fetch one product's trade terms: minimum order quantity, lead time, Incoterms, HS code, packaging, price range, photos and the supplier it belongs to. `delivery_terms` lists the delivery bases the seller confirmed as {incoterm, place_kind, place_city}: place_kind is seller_site | port | border | buyer_site (null when not stated), place_city is the city name in the requested language (English fallback) or null; an empty list means Incoterms on request. Use it once the person has picked a product from search_products and wants the terms.
| Argument | Type | Description |
|---|---|---|
| slug* | string | Product slug (per-locale or base). |
| locale | string | Locale for the returned translation. |
{
"type": "object",
"required": [
"slug"
],
"properties": {
"slug": {
"type": "string",
"description": "Product slug (per-locale or base)."
},
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string",
"description": "Locale for the returned translation."
}
},
"additionalProperties": false
}Explain how to get Gemalli pricing. Gemalli does NOT publish plan prices through this API: quotes are given by the sales desk, because what a manufacturer pays depends on their catalogue, languages and markets. Call this when the person asks what Gemalli costs, then give them the contacts you get back and offer to introduce them. Do NOT state, estimate, guess or recall any price, plan tier, discount or limit for Gemalli itself — you do not have that information, and inventing it misleads the person. Prices of goods listed BY manufacturers are a different thing and stay available through the catalogue tools.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}Report who the person is currently acting for on Gemalli: role, interface language and, when signed in, the company they represent and their plan. An anonymous person is a valid answer and comes back as a guest, not an error. If the person signed in after talking to you anonymously, previous_guest carries the identifier of that earlier conversation so you can carry the history over, and linked_at separates a link you have not seen before from one you have already handled. credits tells whether platform credits are on (enabled), the balance and total granted when signed in, buy_url (null means no payment page yet: send the person to Office Live) and action_costs, the only map from a tool to its action and price: call something free only when its credits is 0, never offer an action whose credits is null. wallets carries one entry per credit kind with its balance and low: low true means that kind is running out and the panel should show the remaining-credits note. Every paid answer carries the same wallets, freshly counted after the charge — prefer those over this first reading. Never returns another party's data and never returns secrets.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}List the product categories on Gemalli with their names in the requested language. Use it to offer the person a choice of category before searching, or to turn a category name into the identifier search_products expects.
| Argument | Type | Description |
|---|---|---|
| locale | string | Locale for the returned names. |
{
"type": "object",
"properties": {
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string",
"description": "Locale for the returned names."
}
},
"additionalProperties": false
}List verified manufacturers published on Gemalli. Returns each producer's name, country, certifications and profile identifier in the requested language, newest first. Use it to show what the platform carries; to find a specific product or filter by country, use search_products.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Max results (1–50). Defaults to 12. |
| locale | string | Preferred locale for returned text. Defaults to "en". |
{
"type": "object",
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Max results (1–50). Defaults to 12."
},
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string",
"description": "Preferred locale for returned text. Defaults to \"en\"."
}
},
"additionalProperties": false
}List the feedback tickets of the current visitor for the Workspace tab. Identity comes from the visitor pass; a guest is matched by the conversation label, so the same person on another device sees nothing — that is expected, not a fault.
No arguments.
{
"type": "object",
"properties": {},
"additionalProperties": false
}List the pages of gemalli.com you can direct this person to, with the label in their language and the address. Use it before offering a link, so you point at a page that exists rather than guessing. Which pages appear depends on whether the person is signed in.
| Argument | Type | Description |
|---|---|---|
| locale | string | Language for the labels. Defaults to English. |
{
"type": "object",
"properties": {
"locale": {
"enum": [
"en",
"uk",
"ru",
"de",
"pl",
"tr",
"ar",
"fr",
"es",
"it",
"ro",
"zh",
"pt"
],
"type": "string",
"description": "Language for the labels. Defaults to English."
}
},
"additionalProperties": false
}Find the Harmonised System (HS) customs code for a product, by description or by code prefix. Returns matching codes with their official names in the requested language, the chapter they belong to, and a similarity score. Use it when the person needs a customs classification for an import, an export or a quote, then pass the code to check_dual_use.
| Argument | Type | Description |
|---|---|---|
| limit | integer | Defaults to 10. |
| query* | string | Product description or HS code prefix. |
| locale | string |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Defaults to 10."
},
"query": {
"type": "string",
"maxLength": 120,
"minLength": 2,
"description": "Product description or HS code prefix."
},
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string"
}
},
"additionalProperties": false
}Return Gemalli's partnership and investment terms and the founder's direct contact. Use it when the person represents a company that would work with a trade platform rather than buy on it — for example logistics, customs, trade finance, insurance, inspection, an ERP vendor or an investor. It returns information only and sends nothing.
| Argument | Type | Description |
|---|---|---|
| from | string | Company or platform the person represents, if known. |
{
"type": "object",
"properties": {
"from": {
"type": "string",
"maxLength": 200,
"description": "Company or platform the person represents, if known."
}
},
"additionalProperties": false
}Send a request for prices, samples or terms to a manufacturer on the person's behalf. Requires the person's own name and email — ask them and pass exactly what they give you, never invent an address. The manufacturer receives the request; the person receives an email with a sign-in link where the reply and the supplier's contacts appear. No account is needed beforehand. Use it once they have chosen a supplier.
| Argument | Type | Description |
|---|---|---|
| locale | string | |
| message* | string | What they need: specs, volumes, target price, delivery terms. |
| quantity | integer | Desired quantity. |
| agent_name | string | Name of the agent or platform sending this, e.g. "Claude" — recorded as the source. |
| buyer_name* | string | The person's name, as they gave it. |
| product_id | string | Product the request is about, if one was chosen. |
| buyer_email* | string | The person's real email — the reply and the sign-in link go there. |
| variant_key | string | Version of that product the person chose, when get_product lists `variants` (e.g. "400v"). Requires product_id. The manufacturer sees the version and its model code in the request. |
Search wholesale products published on Gemalli. Narrow by free text, category, manufacturer, country of origin, maximum minimum-order quantity, maximum price or delivery basis (Incoterms 2020 codes the seller confirmed). Returns product cards in the requested language with price range, minimum order and the supplier. Use it when the person is looking for goods to buy or source.
| Argument | Type | Description |
|---|---|---|
| q | string | Free-text search across name + description (FTS via migration 0016 with ILIKE fallback). |
| limit | integer | Max results (1–50). Defaults to 12. |
| locale | string | Preferred locale for returned text. |
| moqMax | integer | Max minimum-order-quantity threshold (inclusive). |
| offset | integer | Pagination offset. |
| country | string | ISO 3166-1 alpha-2 country code (e.g. "UA"). |
| category | string | Category slug filter (categories.slug). |
| priceMax | number | Max `price_from` threshold (inclusive). |
Send the platform team a request to join Gemalli — for a manufacturer, trader, sales agent, logistics or customs operator, broker or finance provider who wants to work with the platform rather than buy on it. Requires their name, email and phone: the team follows up by phone, so a number is needed. Ask them and pass exactly what they give you, never invent contact details. Use it only when the person has asked to be contacted, never to record someone you are merely discussing.
| Argument | Type | Description |
|---|---|---|
| name* | string | The person's name, as they gave it. |
| email* | string | Their real email. Required. |
| phone* | string | Their phone in international format. Required. |
| locale | string | Two-letter language the person speaks, for the follow-up. |
| source | string | Where this lead came from, e.g. your agent name — recorded for the sales team. |
| company | string | Their company, if known. |
| country | string | ISO 3166-1 alpha-2 country of the person. |
| message | string | What they are looking for, in their own words where possible. |
| operation_id | string | Optional idempotency key for this attempt. Retrying with the SAME operation_id returns the original result instead of creating a second RFQ — send one if your transport can retry. No token needed: an anonymous person is scoped by the buyer_email you pass. |
| buyer_company | string | Their company name, if known. |
| buyer_country | string | ISO 3166-1 alpha-2 country of the buyer. |
| manufacturer_slug* | string | Target manufacturer slug, from search_products or list_manufacturers. |
{
"type": "object",
"required": [
"manufacturer_slug",
"buyer_name",
"buyer_email",
"message"
],
"properties": {
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string"
},
"message": {
"type": "string",
"maxLength": 8192,
"minLength": 1,
"description": "What they need: specs, volumes, target price, delivery terms."
},
"quantity": {
"type": "integer",
"minimum": 1,
"description": "Desired quantity."
},
"agent_name": {
"type": "string",
"description": "Name of the agent or platform sending this, e.g. \"Claude\" — recorded as the source."
},
"buyer_name": {
"type": "string",
"maxLength": 120,
"minLength": 2,
"description": "The person's name, as they gave it."
},
"product_id": {
"type": "string",
"format": "uuid",
"description": "Product the request is about, if one was chosen."
},
"buyer_email": {
"type": "string",
"format": "email",
"description": "The person's real email — the reply and the sign-in link go there."
},
"variant_key": {
"type": "string",
"pattern": "^[a-z0-9][a-z0-9-]{0,39}$",
"maxLength": 40,
"description": "Version of that product the person chose, when get_product lists `variants` (e.g. \"400v\"). Requires product_id. The manufacturer sees the version and its model code in the request."
},
"operation_id": {
"type": "string",
"description": "Optional idempotency key for this attempt. Retrying with the SAME operation_id returns the original result instead of creating a second RFQ — send one if your transport can retry. No token needed: an anonymous person is scoped by the buyer_email you pass."
},
"buyer_company": {
"type": "string",
"description": "Their company name, if known."
},
"buyer_country": {
"type": "string",
"pattern": "^[A-Z]{2}$",
"description": "ISO 3166-1 alpha-2 country of the buyer."
},
"manufacturer_slug": {
"type": "string",
"description": "Target manufacturer slug, from search_products or list_manufacturers."
}
},
"additionalProperties": false
}| incoterms |
| array |
| Delivery basis filter, Incoterms 2020 codes (e.g. ["FCA","DAP"]). A product matches when the seller confirmed ANY of the listed codes. Products without confirmed terms ("Incoterms on request") never match. |
| manufacturer | string | Manufacturer slug filter (manufacturers.slug). |
{
"type": "object",
"properties": {
"q": {
"type": "string",
"description": "Free-text search across name + description (FTS via migration 0016 with ILIKE fallback)."
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1,
"description": "Max results (1–50). Defaults to 12."
},
"locale": {
"enum": [
"en",
"uk",
"ru"
],
"type": "string",
"description": "Preferred locale for returned text."
},
"moqMax": {
"type": "integer",
"description": "Max minimum-order-quantity threshold (inclusive)."
},
"offset": {
"type": "integer",
"minimum": 0,
"description": "Pagination offset."
},
"country": {
"type": "string",
"description": "ISO 3166-1 alpha-2 country code (e.g. \"UA\")."
},
"category": {
"type": "string",
"description": "Category slug filter (categories.slug)."
},
"priceMax": {
"type": "number",
"description": "Max `price_from` threshold (inclusive)."
},
"incoterms": {
"type": "array",
"items": {
"enum": [
"EXW",
"FCA",
"FAS",
"FOB",
"CFR",
"CIF",
"CPT",
"CIP",
"DAP",
"DPU",
"DDP"
],
"type": "string"
},
"maxItems": 11,
"minItems": 1,
"description": "Delivery basis filter, Incoterms 2020 codes (e.g. [\"FCA\",\"DAP\"]). A product matches when the seller confirmed ANY of the listed codes. Products without confirmed terms (\"Incoterms on request\") never match."
},
"manufacturer": {
"type": "string",
"description": "Manufacturer slug filter (manufacturers.slug)."
}
},
"additionalProperties": false
}| operation_id | string | Optional idempotency key. Retrying with the SAME operation_id returns the original lead instead of creating a duplicate. |
| applicant_role | string | What they do: producer, trader, sales_agent, logistics, broker or finance. |
| trade_direction | string | What they buy or sell, short free text. |
{
"type": "object",
"required": [
"name",
"email",
"phone"
],
"properties": {
"name": {
"type": "string",
"description": "The person's name, as they gave it."
},
"email": {
"type": "string",
"format": "email",
"description": "Their real email. Required."
},
"phone": {
"type": "string",
"description": "Their phone in international format. Required."
},
"locale": {
"type": "string",
"description": "Two-letter language the person speaks, for the follow-up."
},
"source": {
"type": "string",
"description": "Where this lead came from, e.g. your agent name — recorded for the sales team."
},
"company": {
"type": "string",
"description": "Their company, if known."
},
"country": {
"type": "string",
"description": "ISO 3166-1 alpha-2 country of the person."
},
"message": {
"type": "string",
"description": "What they are looking for, in their own words where possible."
},
"operation_id": {
"type": "string",
"description": "Optional idempotency key. Retrying with the SAME operation_id returns the original lead instead of creating a duplicate."
},
"applicant_role": {
"enum": [
"producer",
"trader",
"sales_agent",
"logistics",
"broker",
"finance"
],
"type": "string",
"description": "What they do: producer, trader, sales_agent, logistics, broker or finance."
},
"trade_direction": {
"type": "string",
"description": "What they buy or sell, short free text."
}
},
"additionalProperties": false
}