Sugra API gateway - unified operation_id access across the bundled endpoint catalog. Use search_endpoints to find operations, describe_endpoint to inspect parameters, and call_endpoint to call by operation_id.
Protocol
Pass100/10020 / 20 pts
Connection, authentication, and protocol compatibility.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Screen a person or organization name against the Sugra sanctions corpus.
Returns a SCREENING SIGNAL, not a compliance determination. Sugra is a
technology provider, not a sanctions authority or consumer reporting agency.
PEP and adverse-media coverage is supplementary and non-comprehensive - a
`clear` result is not proof of absence, and a `hit` is a candidate match to
review, not a finding.
Output is COMPACT to protect the agent context budget:
`{status, matches:[{name, score, list, type}], disclaimer}`. The verdict
`status` is one of `clear`, `review`, or `hit`. The heavy raw fields
(match rationale, source ids, publish dates) are dropped; use the Sugra API
directly when the full screening envelope is needed.
Args:
name: The person or organization name to screen (required).
country: Optional ISO 3166-1 alpha-2 country to narrow the match.
dob: Optional date of birth (YYYY-MM-DD) for a person.
nationality: Optional nationality to narrow the match.
The description explains the capability, when to use it, and what to expect.
Inputs81/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name
Person or organization name to screen (required).
Clear enough to supply this argument.
country
Optional ISO 3166-1 alpha-2 country to narrow the match.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
dob
Optional date of birth for a person, YYYY-MM-DD.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
nationality
Optional nationality to narrow the match.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "sugra_entity_screen",
"description": "Screen a person or organization name against the Sugra sanctions corpus.\n\nReturns a SCREENING SIGNAL, not a compliance determination. Sugra is a\ntechnology provider, not a sanctions authority or consumer reporting agency.\nPEP and adverse-media coverage is supplementary and non-comprehensive - a\n`clear` result is not proof of absence, and a `hit` is a candidate match to\nreview, not a finding.\n\nOutput is COMPACT to protect the agent context budget:\n`{status, matches:[{name, score, list, type}], disclaimer}`. The verdict\n`status` is one of `clear`, `review`, or `hit`. The heavy raw fields\n(match rationale, source ids, publish dates) are dropped; use the Sugra API\ndirectly when the full screening envelope is needed.\n\nArgs:\n name: The person or organization name to screen (required).\n country: Optional ISO 3166-1 alpha-2 country to narrow the match.\n dob: Optional date of birth (YYYY-MM-DD) for a person.\n nationality: Optional nationality to narrow the match.\n",
"inputSchema": {
"type": "object",
"title": "sugra_entity_screenArguments",
"required": [
"name"
],
"properties": {
"dob": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Dob",
"default": null,
"description": "Optional date of birth for a person, YYYY-MM-DD."
},
"name": {
"type": "string",
"title": "Name",
"description": "Person or organization name to screen (required)."
},
"country": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Country",
"default": null,
"description": "Optional ISO 3166-1 alpha-2 country to narrow the match."
},
"nationality": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Nationality",
"default": null,
"description": "Optional nationality to narrow the match."
}
}
},
"outputSchema": {
"type": "object",
"title": "sugra_entity_screenDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Sugra Entity screen",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Resolve an entity by identifier and return its composed KYB envelope.
`anchor` is `lei` (Legal Entity Identifier, resolved via the GLEIF registry)
or `vat` (EU VAT number, validated via the EU VIES service). The result
weaves identity, a sanctions screening signal, and - on request - ownership
and adverse-media slices.
The screening verdict is a SCREENING SIGNAL, not a compliance determination,
and any PEP / adverse-media content is supplementary and non-comprehensive.
The `disclaimer` field carries this and is always present.
Output is COMPACT by default to protect the agent context budget:
`{entity:{name, anchor, value, status, country}, screening:{status,
top_matches:[...3], hit_count}, ids:{...}, disclaimer}`. Pass `include` to
opt INTO fuller per-slice detail, e.g.
`include=["ownership","adverse_media"]` adds those slices in full form.
On a bad anchor or an API error this returns a clean `{error, detail}` dict
rather than raising, so the agent can branch on `result.get("error")`.
Args:
anchor: Identifier type, one of `lei` or `vat`.
value: The identifier value (the 20-char LEI code or the VAT number).
include: Optional list of fuller slices to add, e.g.
`["ownership", "adverse_media"]`. Omit for the compact default.
The description explains the capability, when to use it, and what to expect.
Inputs67/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
anchor
Identifier type: lei (GLEIF) or vat (EU VIES).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
value
The identifier value: 20-character LEI or the VAT number.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
include
Optional fuller slices to add, e.g. ownership, adverse_media. Omit for the compact default. profile and screening are already in the compact core and are not extra slices.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
{
"name": "sugra_entity_lookup",
"description": "Resolve an entity by identifier and return its composed KYB envelope.\n\n`anchor` is `lei` (Legal Entity Identifier, resolved via the GLEIF registry)\nor `vat` (EU VAT number, validated via the EU VIES service). The result\nweaves identity, a sanctions screening signal, and - on request - ownership\nand adverse-media slices.\n\nThe screening verdict is a SCREENING SIGNAL, not a compliance determination,\nand any PEP / adverse-media content is supplementary and non-comprehensive.\nThe `disclaimer` field carries this and is always present.\n\nOutput is COMPACT by default to protect the agent context budget:\n`{entity:{name, anchor, value, status, country}, screening:{status,\ntop_matches:[...3], hit_count}, ids:{...}, disclaimer}`. Pass `include` to\nopt INTO fuller per-slice detail, e.g.\n`include=[\"ownership\",\"adverse_media\"]` adds those slices in full form.\n\nOn a bad anchor or an API error this returns a clean `{error, detail}` dict\nrather than raising, so the agent can branch on `result.get(\"error\")`.\n\nArgs:\n anchor: Identifier type, one of `lei` or `vat`.\n value: The identifier value (the 20-char LEI code or the VAT number).\n include: Optional list of fuller slices to add, e.g.\n `[\"ownership\", \"adverse_media\"]`. Omit for the compact default.\n",
"inputSchema": {
"type": "object",
"title": "sugra_entity_lookupArguments",
"required": [
"anchor",
"value"
],
"properties": {
"value": {
"type": "string",
"title": "Value",
"description": "The identifier value: 20-character LEI or the VAT number."
},
"anchor": {
"enum": [
"lei",
"vat"
],
"type": "string",
"title": "Anchor",
"description": "Identifier type: lei (GLEIF) or vat (EU VIES)."
},
"include": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Include",
"default": null,
"description": "Optional fuller slices to add, e.g. ownership, adverse_media. Omit for the compact default. profile and screening are already in the compact core and are not extra slices."
}
}
},
"outputSchema": {
"type": "object",
"title": "sugra_entity_lookupDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Sugra Entity lookup",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Search the bundled Sugra endpoint catalog by natural-language query.
Use this to pick an operation_id. It does not fetch data. Typical loop:
1. search_endpoints(query) -> ranked hits with required_parameters
2. describe_endpoint(operation_id) -> params, request_body_schema, agent_hints
3. call_endpoint(operation_id, params=..., body=...) or fetch_data(query, params=...)
Filter with toolset or source only after list_toolsets / list_sources;
a misspelled filter is an error, not a silent empty result.
Examples:
- search_endpoints("US CPI inflation")
- search_endpoints("AAPL price", toolset="markets")
- search_endpoints("container ship AIS", toolset="network")
The description explains the capability, when to use it, and what to expect.
Inputs99/100
Input documentation gives an agent enough context to populate the arguments.
query
Natural-language search over the bundled catalog. Name the instrument, series, place, or task (examples: 'US CPI', 'AAPL quote', 'North Sea AIS'). Returns ranked operation_id hits with required_parameters. Then call describe_endpoint on a hit before call_endpoint.
Clear enough to supply this argument.
toolset
Optional catalog group filter (markets, macro, news, network, ...). Call list_toolsets for the live names. An unknown value returns error unknown_toolset with known_toolsets rather than an empty hit list.
Clear enough to supply this argument.
source
Optional source-family filter as listed by list_sources (macro, markets, ...). An unknown value returns error unknown_source with known_sources.
Clear enough to supply this argument.
limit
Maximum ranked hits to return. Default 10. Does not call the Sugra API; this only bounds the catalog search list.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description91/100
Describe one Sugra API endpoint by operation_id.
Includes agent_hints (duration_class fast/slow/heavy, max_concurrency,
bulk billing) so you can budget timeouts and parallelism before calling.
POST endpoints with a JSON body also carry request_body_schema (the
resolved JSON schema) - construct the `body` argument from it instead
of guessing key names. Call this after search_endpoints and before
call_endpoint when you need the exact parameter names and examples.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
operation_id
Catalog operation_id from search_endpoints (or from list_toolsets drill-down). Unknown ids return error unknown_operation_id.
{
"name": "describe_endpoint",
"description": "Describe one Sugra API endpoint by operation_id.\n\nIncludes agent_hints (duration_class fast/slow/heavy, max_concurrency,\nbulk billing) so you can budget timeouts and parallelism before calling.\nPOST endpoints with a JSON body also carry request_body_schema (the\nresolved JSON schema) - construct the `body` argument from it instead\nof guessing key names. Call this after search_endpoints and before\ncall_endpoint when you need the exact parameter names and examples.\n",
"inputSchema": {
"type": "object",
"title": "describe_endpointArguments",
"required": [
"operation_id"
],
"properties": {
"operation_id": {
"type": "string",
"title": "Operation Id",
"description": "Catalog operation_id from search_endpoints (or from list_toolsets drill-down). Unknown ids return error unknown_operation_id."
}
}
},
"outputSchema": {
"type": "object",
"title": "describe_endpointDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Describe endpoint",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description82/100
Call a Sugra API endpoint by operation_id from the bundled catalog.
Plan calls with describe_endpoint's agent_hints: duration_class "fast"
usually responds in under ~2s, "slow" usually 1-5s and occasionally 15s+
on a cold upstream, "heavy" can exceed the gateway timeout - keep parallel
calls within max_concurrency and prefer small batches. Bulk endpoints bill
1 request credit per body item. Failures return structured errors {error,
reason, status_code, elapsed_ms, retry_hint}; after "upstream_timeout" a
single retry often succeeds because the aborted attempt warms upstream
caches.
The description explains the capability, when to use it, and what to expect.
Inputs97/100
Input documentation gives an agent enough context to populate the arguments.
operation_id
Catalog operation_id to call, from search_endpoints (or from list_toolsets drill-down). Call describe_endpoint on it first for the parameter names. Unknown ids return error unknown_operation_id before any request is made.
Clear enough to supply this argument.
params
Query and path parameters for this operation_id. Keys and types are operation-specific - call describe_endpoint(operation_id) first to get the exact parameter names, types, and examples. Omit if the operation takes none. A key the operation does not declare returns error unknown_parameters with the accepted names and did_you_mean, before any request is made.
Clear enough to supply this argument.
body
JSON request body for a POST operation, matching the request_body_schema returned by describe_endpoint(operation_id): a JSON object for most operations, or a JSON array when that schema's top-level type is array. Omit for GET operations.
Clear enough to supply this argument.
limit
Bounds ONLY the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). When data has no such single list but every one of its values is an object holding exactly one list named observations, limit bounds each data.<key>.observations list on its own (records_path data.*.observations); fields there still names keys of data. Otherwise, no such list, or several, means the limit does not apply. Keys beside the list such as total and count are not rewritten, and lists nested inside records are never truncated. limit keeps the newest N records when every record carries one date or period key in one format and the list runs one way by it, else the first N, and meta.shaped reports limit_applied, records_path and, for a bounded records list, order (asc, desc or unknown) and kept_end (newest or first), as maps by name for sibling sub-series.
Clear enough to supply this argument.
fields
Optional projection of keys to keep on each record of the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). Keys beside that list such as total and count stay. If a field names a key of data itself, or of a payload without data, that object is projected instead; an object data without such a list is otherwise kept whole. Dotted paths (geo.city) walk nested objects. If no field matches, nothing is removed. meta.shaped reports fields_applied, fields_unmatched and records_path. Omit to keep every key.
Clear enough to supply this argument.
include_raw
If true, attach the original unshaped payload under raw when it fits the size cap; otherwise meta.raw_omitted explains why. Default false.
{
"name": "call_endpoint",
"description": "Call a Sugra API endpoint by operation_id from the bundled catalog.\n\nPlan calls with describe_endpoint's agent_hints: duration_class \"fast\"\nusually responds in under ~2s, \"slow\" usually 1-5s and occasionally 15s+\non a cold upstream, \"heavy\" can exceed the gateway timeout - keep parallel\ncalls within max_concurrency and prefer small batches. Bulk endpoints bill\n1 request credit per body item. Failures return structured errors {error,\nreason, status_code, elapsed_ms, retry_hint}; after \"upstream_timeout\" a\nsingle retry often succeeds because the aborted attempt warms upstream\ncaches.\n",
"inputSchema": {
"type": "object",
"title": "call_endpointArguments",
"required": [
"operation_id"
],
"properties": {
"body": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Body",
"default": null,
"description": "JSON request body for a POST operation, matching the request_body_schema returned by describe_endpoint(operation_id): a JSON object for most operations, or a JSON array when that schema's top-level type is array. Omit for GET operations."
},
"limit": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Limit",
"default": null,
"description": "Bounds ONLY the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). When data has no such single list but every one of its values is an object holding exactly one list named observations, limit bounds each data.<key>.observations list on its own (records_path data.*.observations); fields there still names keys of data. Otherwise, no such list, or several, means the limit does not apply. Keys beside the list such as total and count are not rewritten, and lists nested inside records are never truncated. limit keeps the newest N records when every record carries one date or period key in one format and the list runs one way by it, else the first N, and meta.shaped reports limit_applied, records_path and, for a bounded records list, order (asc, desc or unknown) and kept_end (newest or first), as maps by name for sibling sub-series."
},
"fields": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Fields",
"default": null,
"description": "Optional projection of keys to keep on each record of the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). Keys beside that list such as total and count stay. If a field names a key of data itself, or of a payload without data, that object is projected instead; an object data without such a list is otherwise kept whole. Dotted paths (geo.city) walk nested objects. If no field matches, nothing is removed. meta.shaped reports fields_applied, fields_unmatched and records_path. Omit to keep every key."
},
"params": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Params",
"default": null,
"description": "Query and path parameters for this operation_id. Keys and types are operation-specific - call describe_endpoint(operation_id) first to get the exact parameter names, types, and examples. Omit if the operation takes none. A key the operation does not declare returns error unknown_parameters with the accepted names and did_you_mean, before any request is made."
},
"include_raw": {
"type": "boolean",
"title": "Include Raw",
"default": false,
"description": "If true, attach the original unshaped payload under raw when it fits the size cap; otherwise meta.raw_omitted explains why. Default false."
},
"operation_id": {
"type": "string",
"title": "Operation Id",
"description": "Catalog operation_id to call, from search_endpoints (or from list_toolsets drill-down). Call describe_endpoint on it first for the parameter names. Unknown ids return error unknown_operation_id before any request is made."
}
}
},
"outputSchema": {
"type": "object",
"title": "call_endpointDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Call endpoint",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description84/100
List catalog groups with endpoint counts and short descriptions.
Use the group names as the toolset filter on search_endpoints. This
does not call the Sugra API; it reads the bundled catalog.
Describe the returned information so the agent knows whether it will answer the request.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
One-step fetch: find the best Sugra endpoint for the query and call it.
Combines search_endpoints + call_endpoint into a single round trip. Use
this when you want data without manually picking an operation_id. The
full search_endpoints + describe_endpoint + call_endpoint dance is still
available when you need explicit control, but for most natural-language
queries this tool is enough.
Behavior:
1. Search the bundled catalog for the query. Top match wins.
2. If the matched endpoint has required parameters and they are all
provided in `params`, call it and return the response.
3. If required parameters are missing, return the candidate endpoints
and the missing-params list so the LLM can retry with the correct
`params` dict on the next call.
4. If the query names a country and the match takes a `country` or
`countries` param that `params` leaves unset, return needs_params
for it with query_countries (ISO2) instead of running the match
without that filter.
Examples:
- `fetch_data("US CPI inflation", params={"series_id": "CPIAUCSL"})`
runs fred_series_series_id (/api/v1/fred/series/CPIAUCSL) and returns
observations.
- `fetch_data("Bitcoin price")`
runs onchain_bitcoin_price, which takes no params.
- `fetch_data("Latest financial news")`
runs news_latest, which has no required params.
Only the top match runs, and a param it does not declare returns error
unknown_parameters. For one coin's price, name the operation:
`call_endpoint("crypto_coin_id_price", params={"coin_id": "bitcoin"})`.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Natural-language request for data (examples: 'US CPI', 'Bitcoin price', 'latest news'). The tool picks the top catalog match and calls it. If required params are missing it returns needs_params instead of guessing.
Clear enough to supply this argument.
params
Parameters for the auto-selected endpoint. If omitted and the best-match endpoint has required parameters, the tool returns that endpoint's required_parameters and examples so you can retry with them filled in.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
body
JSON body for an auto-selected POST operation; the tool returns the request_body_schema to fill when the match needs one. Pass a JSON object or a JSON array as that schema's top-level type dictates.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Bounds ONLY the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). When data has no such single list but every one of its values is an object holding exactly one list named observations, limit bounds each data.<key>.observations list on its own (records_path data.*.observations); fields there still names keys of data. Otherwise, no such list, or several, means the limit does not apply. Keys beside the list such as total and count are not rewritten, and lists nested inside records are never truncated. limit keeps the newest N records when every record carries one date or period key in one format and the list runs one way by it, else the first N, and meta.shaped reports limit_applied, records_path and, for a bounded records list, order (asc, desc or unknown) and kept_end (newest or first), as maps by name for sibling sub-series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
fields
Optional projection of keys to keep on each record of the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). Keys beside that list such as total and count stay. If a field names a key of data itself, or of a payload without data, that object is projected instead; an object data without such a list is otherwise kept whole. Dotted paths (geo.city) walk nested objects. If no field matches, nothing is removed. meta.shaped reports fields_applied, fields_unmatched and records_path. Omit to keep every key.
Clear enough to supply this argument.
include_raw
If true, attach the original unshaped payload under raw when it fits the size cap; otherwise meta.raw_omitted explains why. Default false.
{
"name": "fetch_data",
"description": "One-step fetch: find the best Sugra endpoint for the query and call it.\n\nCombines search_endpoints + call_endpoint into a single round trip. Use\nthis when you want data without manually picking an operation_id. The\nfull search_endpoints + describe_endpoint + call_endpoint dance is still\navailable when you need explicit control, but for most natural-language\nqueries this tool is enough.\n\nBehavior:\n1. Search the bundled catalog for the query. Top match wins.\n2. If the matched endpoint has required parameters and they are all\n provided in `params`, call it and return the response.\n3. If required parameters are missing, return the candidate endpoints\n and the missing-params list so the LLM can retry with the correct\n `params` dict on the next call.\n4. If the query names a country and the match takes a `country` or\n `countries` param that `params` leaves unset, return needs_params\n for it with query_countries (ISO2) instead of running the match\n without that filter.\n\nExamples:\n- `fetch_data(\"US CPI inflation\", params={\"series_id\": \"CPIAUCSL\"})`\n runs fred_series_series_id (/api/v1/fred/series/CPIAUCSL) and returns\n observations.\n- `fetch_data(\"Bitcoin price\")`\n runs onchain_bitcoin_price, which takes no params.\n- `fetch_data(\"Latest financial news\")`\n runs news_latest, which has no required params.\nOnly the top match runs, and a param it does not declare returns error\nunknown_parameters. For one coin's price, name the operation:\n`call_endpoint(\"crypto_coin_id_price\", params={\"coin_id\": \"bitcoin\"})`.\n",
"inputSchema": {
"type": "object",
"title": "fetch_dataArguments",
"required": [
"query"
],
"properties": {
"body": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
{
"type": "null"
}
],
"title": "Body",
"default": null,
"description": "JSON body for an auto-selected POST operation; the tool returns the request_body_schema to fill when the match needs one. Pass a JSON object or a JSON array as that schema's top-level type dictates."
},
"limit": {
"anyOf": [
{
"type": "integer"
},
{
"type": "null"
}
],
"title": "Limit",
"default": null,
"description": "Bounds ONLY the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). When data has no such single list but every one of its values is an object holding exactly one list named observations, limit bounds each data.<key>.observations list on its own (records_path data.*.observations); fields there still names keys of data. Otherwise, no such list, or several, means the limit does not apply. Keys beside the list such as total and count are not rewritten, and lists nested inside records are never truncated. limit keeps the newest N records when every record carries one date or period key in one format and the list runs one way by it, else the first N, and meta.shaped reports limit_applied, records_path and, for a bounded records list, order (asc, desc or unknown) and kept_end (newest or first), as maps by name for sibling sub-series."
},
"query": {
"type": "string",
"title": "Query",
"description": "Natural-language request for data (examples: 'US CPI', 'Bitcoin price', 'latest news'). The tool picks the top catalog match and calls it. If required params are missing it returns needs_params instead of guessing."
},
"fields": {
"anyOf": [
{
"type": "array",
"items": {
"type": "string"
}
},
{
"type": "null"
}
],
"title": "Fields",
"default": null,
"description": "Optional projection of keys to keep on each record of the records list: the data list, a bare top-level array, or the list inside an object data when exactly one of these keys holds a list: data, entries, events, history, items, observations, points, records, results, rows, series, timeseries (for example data.items). Keys beside that list such as total and count stay. If a field names a key of data itself, or of a payload without data, that object is projected instead; an object data without such a list is otherwise kept whole. Dotted paths (geo.city) walk nested objects. If no field matches, nothing is removed. meta.shaped reports fields_applied, fields_unmatched and records_path. Omit to keep every key."
},
"params": {
"anyOf": [
{
"type": "object",
"additionalProperties": true
},
{
"type": "null"
}
],
"title": "Params",
"default": null,
"description": "Parameters for the auto-selected endpoint. If omitted and the best-match endpoint has required parameters, the tool returns that endpoint's required_parameters and examples so you can retry with them filled in."
},
"include_raw": {
"type": "boolean",
"title": "Include Raw",
"default": false,
"description": "If true, attach the original unshaped payload under raw when it fits the size cap; otherwise meta.raw_omitted explains why. Default false."
}
}
},
"outputSchema": {
"type": "object",
"title": "fetch_dataDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Fetch data",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description83/100
List source families in the bundled catalog with endpoint counts.
Use the family names as the source filter on search_endpoints. This
does not call the Sugra API.
Describe the returned information so the agent knows whether it will answer the request.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Resolve free text to a canonical market or macro entity.
Turns a ticker, company name, macro indicator, coin, or currency pair into
the agent plane's ``{namespace, ids}`` entity for use with get_snapshot and
get_timeseries. A cross-namespace collision (e.g. a ticker that is both an
equity and a coin) returns status "ambiguous" with ranked candidates and
NEVER silently picks one; pass type_hint (e.g. "equity", "etf", "coin") to
narrow the universe. Crypto aliases resolve too (e.g. "bitcoin" -> the
BTC coin entity). Status "low_confidence" means the best match cleared
resolution but scored weakly - verify the returned entity before
building on it, or re-query with a more specific name or type_hint. For compliance KYB lookups by LEI/VAT or sanctions
screening use sugra_entity_lookup / sugra_entity_screen instead - this tool
is for market-data entities.
Args:
query: Free-form text - ticker, company, indicator, coin, or pair.
type_hint: Optional namespace hint narrowing resolution.
The description explains the capability, when to use it, and what to expect.
Inputs0/100
0 of 2 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
query
Not provided
Missing description. Explain what this value means and how to supply it.
type_hint
Not provided
Missing description. Explain what this value means and how to supply it.
{
"name": "resolve_entity",
"description": "Resolve free text to a canonical market or macro entity.\n\nTurns a ticker, company name, macro indicator, coin, or currency pair into\nthe agent plane's ``{namespace, ids}`` entity for use with get_snapshot and\nget_timeseries. A cross-namespace collision (e.g. a ticker that is both an\nequity and a coin) returns status \"ambiguous\" with ranked candidates and\nNEVER silently picks one; pass type_hint (e.g. \"equity\", \"etf\", \"coin\") to\nnarrow the universe. Crypto aliases resolve too (e.g. \"bitcoin\" -> the\nBTC coin entity). Status \"low_confidence\" means the best match cleared\nresolution but scored weakly - verify the returned entity before\nbuilding on it, or re-query with a more specific name or type_hint. For compliance KYB lookups by LEI/VAT or sanctions\nscreening use sugra_entity_lookup / sugra_entity_screen instead - this tool\nis for market-data entities.\n\nArgs:\n query: Free-form text - ticker, company, indicator, coin, or pair.\n type_hint: Optional namespace hint narrowing resolution.\n",
"inputSchema": {
"type": "object",
"title": "resolve_entityArguments",
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"title": "Query"
},
"type_hint": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Type Hint",
"default": null
}
}
},
"outputSchema": {
"type": "object",
"title": "resolve_entityDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Resolve entity",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Composed current view of an entity via a named recipe.
Executes a fixed server-side recipe (company_snapshot, etf_snapshot,
quote_snapshot, macro_indicator_snapshot, macro_calendar,
earnings_snapshot, debt_snapshot) and returns one envelope with freshness,
provenance, per-component coverage, and billing. Composed calls charge the
recipe's fixed cost (1-2 units) from the daily quota. status "partial"
means an optional component was unavailable - the present components are
still trustworthy; honor the freshness block (stale=true means the data
aged past its budget); for macro_calendar, entity is accepted but does
not filter the calendar.
Args:
recipe: Recipe name from the fixed manifest.
entity: Entity dict from resolve_entity ({"namespace": ..., "ids": ...}).
The description explains the capability, when to use it, and what to expect.
Inputs42/100
2 of 3 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
recipe
Not provided
Missing description. Explain what this value means and how to supply it.
entity › namespace
Entity namespace from resolve_entity.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entity › ids
Identifier map from resolve_entity.
Explain the meaning of this value, not just its name.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Bounded timeseries for an entity: price, macro_series, etf_flows or
etf_monthly_flows.
Returns points oldest-first with an explicit downsampling flag when the
raw series exceeded max_points. Times are UTC. Costs 1 unit per call.
Read the step from ``served_granularity``, not ``granularity``. The
latter echoes the request; the former is the step the source built the
points at, and the two can differ (a long price range can come back as
monthly bars under a "1d" request). It reads ``mixed`` when the points do
not share one step, ``unknown`` when the source does not say, and null
when no point came back. It describes how each point was built, not how
far apart the returned points are: a thinned daily series still reads
``1d``, and ``downsampled`` is what says points were dropped.
The two ETF flow metrics answer different questions and are not
interchangeable. ``etf_flows`` is an ESTIMATE at filing cadence: one point
per SEC filing refresh, so ``t`` is a filing date and even a wide window
yields a handful of points. ``etf_monthly_flows`` is the fund's own
creations and redemptions from its NPORT-P filing, so ``t`` is a calendar
month (``YYYY-MM``) and each point carries the three filed components -
sales, reinvestment, redemption - beside the net.
Two things to read before quoting etf_monthly_flows. NPORT-P is filed per
SERIES, so for a fund with more than one share class the figures cover
every class and the payload says so in ``multi_class_series``; where the
class count is unknown it says ``class_scope`` instead of staying silent.
And a fund that files no NPORT-P at all, such as a commodity trust, is not
an error: the call returns status ``partial`` with an empty point list and
a ``reason``.
Args:
metric: One of price / macro_series / etf_flows / etf_monthly_flows.
entity: Entity dict from resolve_entity ({"namespace": ..., "ids": ...}).
granularity: Requested point granularity (default "1d").
max_points: Hard cap on returned points (default 500).
The description explains the capability, when to use it, and what to expect.
Inputs25/100
2 of 5 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values.
metric
Not provided
Missing description. Explain what this value means and how to supply it.
entity › namespace
Entity namespace from resolve_entity.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
entity › ids
Identifier map from resolve_entity.
Explain the meaning of this value, not just its name.
granularity
Not provided
Missing description. Explain what this value means and how to supply it.
max_points
Not provided
Missing description. Explain what this value means and how to supply it.
{
"name": "get_timeseries",
"description": "Bounded timeseries for an entity: price, macro_series, etf_flows or\netf_monthly_flows.\n\nReturns points oldest-first with an explicit downsampling flag when the\nraw series exceeded max_points. Times are UTC. Costs 1 unit per call.\n\nRead the step from ``served_granularity``, not ``granularity``. The\nlatter echoes the request; the former is the step the source built the\npoints at, and the two can differ (a long price range can come back as\nmonthly bars under a \"1d\" request). It reads ``mixed`` when the points do\nnot share one step, ``unknown`` when the source does not say, and null\nwhen no point came back. It describes how each point was built, not how\nfar apart the returned points are: a thinned daily series still reads\n``1d``, and ``downsampled`` is what says points were dropped.\n\nThe two ETF flow metrics answer different questions and are not\ninterchangeable. ``etf_flows`` is an ESTIMATE at filing cadence: one point\nper SEC filing refresh, so ``t`` is a filing date and even a wide window\nyields a handful of points. ``etf_monthly_flows`` is the fund's own\ncreations and redemptions from its NPORT-P filing, so ``t`` is a calendar\nmonth (``YYYY-MM``) and each point carries the three filed components -\nsales, reinvestment, redemption - beside the net.\n\nTwo things to read before quoting etf_monthly_flows. NPORT-P is filed per\nSERIES, so for a fund with more than one share class the figures cover\nevery class and the payload says so in ``multi_class_series``; where the\nclass count is unknown it says ``class_scope`` instead of staying silent.\nAnd a fund that files no NPORT-P at all, such as a commodity trust, is not\nan error: the call returns status ``partial`` with an empty point list and\na ``reason``.\n\nArgs:\n metric: One of price / macro_series / etf_flows / etf_monthly_flows.\n entity: Entity dict from resolve_entity ({\"namespace\": ..., \"ids\": ...}).\n granularity: Requested point granularity (default \"1d\").\n max_points: Hard cap on returned points (default 500).\n",
"inputSchema": {
"type": "object",
"title": "get_timeseriesArguments",
"required": [
"metric",
"entity"
],
"properties": {
"entity": {
"type": "object",
"required": [
"namespace",
"ids"
],
"properties": {
"ids": {
"type": "object",
"description": "Identifier map from resolve_entity.",
"additionalProperties": true
},
"namespace": {
"type": "string",
"description": "Entity namespace from resolve_entity."
}
},
"description": "Entity dict from resolve_entity ({namespace, ids}). Extra keys are ignored.",
"additionalProperties": true
},
"metric": {
"enum": [
"price",
"macro_series",
"etf_flows",
"etf_monthly_flows"
],
"type": "string",
"title": "Metric"
},
"max_points": {
"type": "integer",
"title": "Max Points",
"default": 500
},
"granularity": {
"type": "string",
"title": "Granularity",
"default": "1d"
}
}
},
"outputSchema": {
"type": "object",
"title": "get_timeseriesDictOutput",
"additionalProperties": true
},
"annotations": {
"title": "Get timeseries",
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Fetch dataOne-step fetch: find the best Sugra endpoint for the query and call it.
02Search endpointsSearch the bundled Sugra endpoint catalog by natural-language query.
03Resolve entityResolve free text to a canonical market or macro entity.
04List toolsetsList catalog groups with endpoint counts and short descriptions.
05Sugra Entity screenScreen a person or organization name against the Sugra sanctions corpus.
Want to run these tasks against your MCP server with us?
sugra-api setup, tools, quality score, publishing readiness, and alternatives.
How do I add sugra-api to Claude, ChatGPT, or Cursor?
Add sugra-api to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://app.sugra.ai/mcp.
Is sugra-api MCP ready for ChatGPT and Claude?
As of October 16, 2026, sugra-api scores 100/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is sugra-api's MCP tool documentation?
As of October 16, 2026, sugra-api scores 80/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 11 of 11 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to sugra-api?
As of October 16, 2026, alternatives to sugra-api in financial-services on the Manufact MCP catalog include Contract-Factory — Sociétés & SIREN, Kavara Kirk, CeylonCharts, Netzo, and Ramp Data.
How can sugra-api improve its MCP documentation?
resolve_entity is the lowest-scoring reviewed tool at 62/100. 0 of 2 inputs have descriptions. Add descriptions to the missing inputs, including where to obtain IDs and how to supply values. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.