Pagination and limits
Agents can be surprisingly enthusiastic with broad queries. Your server should be less enthusiastic.
Use:
- deterministic sorting, for example
filed_at desc, filing_id desc
- cursor-based pagination where possible
- sensible page-size caps
- explicit
has_more and next_cursor
This is not merely operational hygiene. It also keeps the agent from summarising a partial result set as if it were complete.
Example MCP tool calls for Claude, Cursor, and Windsurf
The protocol client differs by environment, but the conceptual flow is similar. The agent discovers tools, resolves entities, calls a retrieval tool, then optionally calls an aggregation tool.
Below are examples in a generic JSON-RPC style. The exact wrapper will vary by client implementation.
Example 1, resolve an issuer from a vague prompt
User prompt:
Find the latest insider purchases for LVMH.
First, the agent should resolve the issuer.
Tool call
{
"tool": "resolve_issuer",
"arguments": {
"query": "LVMH",
"market": "FR",
"limit": 5
}
}
Tool response
{
"query": "LVMH",
"matches": [
{
"issuer_id": "fr_issuer_12345",
"name": "LVMH Moet Hennessy Louis Vuitton SE",
"ticker": "MC",
"isin": "FR0000121014",
"lei": "969500S6OI5FOBDZ2J08",
"market": "FR",
"confidence": 0.98
}
],
"schema_version": "2026-01"
}
Then retrieve recent acquisitions.
Tool call
{
"tool": "get_filings",
"arguments": {
"filters": {
"market": "FR",
"issuer_id": "fr_issuer_12345",
"transaction_type": ["ACQUISITION"],
"filing_date_from": "2026-01-01",
"limit_to_primary_disclosures": true
},
"sort": [
{"field": "filed_at", "direction": "desc"}
],
"page_size": 20
}
}
Tool response
{
"rows": [
{
"filing_id": "fr_filing_998877",
"transaction_id": "fr_tx_112233",
"issuer_id": "fr_issuer_12345",
"issuer_name": "LVMH Moet Hennessy Louis Vuitton SE",
"insider_id": "fr_insider_456",
"insider_name": "n/a",
"role_normalized": "DIRECTOR",
"transaction_date": "2026-02-14",
"filed_at": "2026-02-17T08:12:00Z",
"transaction_type": "ACQUISITION",
"security_type": "EQUITY",
"quantity": 1000,
"price": 712.5,
"currency": "EUR",
"gross_value": 712500,
"ownership_nature": "DIRECT",
"source_url": "https://..."
}
],
"page_info": {
"has_more": false,
"next_cursor": null
}
}
The agent can now answer with evidence, dates, and source links.
Example 2, screen for cluster buying
User prompt:
Show me French issuers with cluster buying in the last 90 days.
This should not force the agent to reinvent the definition in prose. Give it a tool.
Tool call
{
"tool": "screen_cluster_buying",
"arguments": {
"filters": {
"market": "FR",
"transaction_date_from": "2026-02-16",
"transaction_date_to": "2026-05-17",
"transaction_type": ["ACQUISITION"],
"security_type": ["EQUITY"]
},
"min_insiders": 3,
"window_days": 30,
"min_total_value": null
}
}
Tool response
{
"definition": {
"transaction_type": "ACQUISITION",
"security_type": "EQUITY",
"min_distinct_insiders": 3,
"window_days": 30
},
"results": [
{
"issuer_id": "fr_issuer_222",
"issuer_name": "Example SA",
"window_start": "2026-03-10",
"window_end": "2026-04-08",
"distinct_insiders": 4,
"transaction_count": 5,
"total_gross_value": 1850000,
"currency": "EUR"
}
],
"as_of": "2026-05-17T00:00:00Z"
}
That response is machine-readable and self-documenting. Which is more than can be said for many investor presentations.
Example 3, ask for a summary rather than rows
User prompt:
Summarise director selling in France this quarter by sector.
Tool call
{
"tool": "summarize_activity",
"arguments": {
"filters": {
"market": "FR",
"transaction_type": ["DISPOSAL"],
"insider_role": ["DIRECTOR"],
"transaction_date_from": "2026-04-01",
"transaction_date_to": "2026-06-30"
},
"group_by": ["sector"],
"metrics": ["filing_count", "transaction_count", "distinct_issuers", "gross_value_sum"]
}
}
Tool response
{
"rows": [
{
"sector": "Consumer Discretionary",
"filing_count": 12,
"transaction_count": 15,
"distinct_issuers": 7,
"gross_value_sum": 9400000,
"currency": "EUR"
},
{
"sector": "Financials",
"filing_count": 9,
"transaction_count": 11,
"distinct_issuers": 5,
"gross_value_sum": 6100000,
"currency": "EUR"
}
],
"methodology": {
"group_by": ["sector"],
"metrics": ["filing_count", "transaction_count", "distinct_issuers", "gross_value_sum"],
"normalization_notes": "Sector classification based on issuer master as of query date"
}
}
Again, the point is not just to answer the question. It is to answer it in a way that can survive a follow-up.
Regulatory context the schema should respect
If your MCP server covers more than one market, a comparative layer is useful. Not because every user asks for it, but because the server should know what world it is operating in.