Skip to main content
Glama

Server Details

Grounded financial research for agents: filings, transcripts, news across US and Asia markets.

Ownership verified
Status
Healthy
Uptime
100.0% over the last 24 hours
OAuth
Works in Glama
Last Tested
Transport
Streamable HTTP · MCP 2025-11-25
URL
ChatGPT
Distilla Investment Research
Claude
–

TDQS

A4.2/5.0

Scored across 10 tools

Disambiguation4/5

The descriptions aggressively disambiguate the risky pairs: aggregate_entity vs query_entity (GROUP BY vs raw rows), screen_drivers vs screen_earnings (durable thesis vs earnings-period commentary), and search_public_library vs get_library_document (search vs read). The main residual overlap is between screen tools, query_entity on company_drivers/ku_cell, and search_public_library vs query_entity on the 'file' entity, where the corpora boundaries (public library research/podcasts vs DB filings) are stated but could still be mistaken.

Naming Consistency5/5

All names are snake_case verb_noun or verb_noun_qualifier: list_queryable_entities, describe_queryable_entities, query_entity, aggregate_entity, screen_drivers, screen_earnings, get_screen_job, get_library_document, search_public_library. The only outlier is the conventional 'ping' health check, which is idiomatic and does not break the pattern.

Tool Count5/5

Ten tools is well within the sweet spot and every tool maps to a real step: catalog list, schema describe, row query, aggregate, two screening entry points, async job polling, library search, document read, and a health ping. Nothing appears redundant or filler.

Completeness4/5

Coverage of the read pipeline is strong: discovery -> describe -> query/aggregate, plus qualitative screening with async job lifecycle (start via screen_* and poll via get_screen_job). The surface is intentionally read-only, but there is no way to list or cancel outstanding screen jobs and no first-class metric/key discovery tool (relies on ilike on financial_metric), which are minor workable gaps.

Publisher details

Operator
Distilla · Publisher source
Vendor relationship
First-party · Publisher source
Restrictions
https://app.distilla.ai · Publisher source

Available Tools

10 tools
aggregate_entityA
Read-onlyIdempotent
Inspect

Read one Queryable Entity as a GROUP BY aggregate. Returns one page of groups. Use this for a count, a per-group min/max/avg, or a threshold screen. Do not page raw rows through query_entity for those. Call list_queryable_entities first, then describe_queryable_entities.

Use cases:

  • Count rows or companies that match filters: COUNT on id, with the same filters as a row query.

  • Range over time: MIN and MAX of a metric, group_by company_id. Example: forward P/E on valuation_multiple, filter type and valuation_date, alias the outputs minPe and maxPe.

  • Threshold screen: MAX(value) as an alias, category and date filters in filters, numeric cut in having on that alias. The number of returned groups is the match count. Then query_entity on company with id in [...] to attach names, tickers, and hq_country.

Allowed entities: company, company_drivers, consensus_data_point, consensus_metric, earnings_calendar, executive_summary, file, financial_data_point, financial_metric, knowledge_unit, ku_cell, price_explanation, product, product_category, sector, standard_event, stock_price, ticker, time_period, valuation_multiple, website_change.

Arguments: entity, aggregates, group_by, filters, filter_logic (AND or OR, default AND), having, sort, joins, limit. Each aggregate has function, field, optional alias, and optional distinct. Functions: COUNT, SUM, AVG, MIN, MAX. AVG is the arithmetic mean, not a median or percentile. filters are WHERE. having is HAVING and may use aggregate aliases. sort may use those aliases. Joins and camelCase aliases work like query_entity. Pass IN lists on filter.value. Do not pass value_path.

valuation_multiple.value, financial_data_point.value, and consensus_data_point.value are text. MIN, MAX, SUM, and AVG cast them to numeric and skip rows that are not decimals. A WHERE filter on those fields stays lexicographic. Put the numeric threshold in having, not in filters.

On financial_data_point, join time_period (alias timePeriod) and financial_metric (alias financialMetric). Group by timePeriod.company_id. Do not join company. Put metric name, provenance, duration, and fiscal_year in filters.

A full page sets truncated=true. This call does not scan the full universe. There is no next_hint. If truncated, tighten filters, drop a group_by column, or split an id list into smaller IN batches that each stay under max_limit. limit is capped at max_limit.

Inputs: entity (required), aggregates (required), sort, joins, +5 more.

describe_queryable_entitiesA
Read-onlyIdempotent
Inspect

Describe the schema of one or more Queryable Entities. Call list_queryable_entities first. Call this before query_entity and aggregate_entity. Pass one comma-separated list of the base entity and every join target you will use (for example financial_data_point,time_period,financial_metric). Prefer suggested_describe_entities from the catalog. Returns field names, types, descriptions, operators, select/filter/sort flags, join_target, join_relation when it differs from join_target, max_limit, and notes. An unknown name returns known_entities. Use only fields and operators from this response.

Inputs: entity (required).

get_library_documentA
Read-onlyIdempotent
Inspect

Read one Public Library document by document_id from search_public_library sources. Returns metadata, summary, and tags. Pass with_contents=true to include raw text in contents for non-Research documents. For a YouTube document that is the full video transcript, and the payload also has the video url and channel_name. Research documents omit full text (provider terms) and set contents_omitted. Omit with_contents to keep the payload small. This tool does not search. Call search_public_library first.

Inputs: document_id (required), with_contents.

get_screen_jobA
Read-onlyIdempotent
Inspect

Read one screen job that you started with screen_drivers or screen_earnings. Pass the job_id from the start call. This tool only reads GCS; it does not run the screen. Poll until status is "done" or "error". When status is "done", the payload includes result with the same JSON shape as a finished screen: summary, matches, ranked, and coverage. When status is queued or running, result is absent. When status is error, the payload includes error.

Inputs: job_id (required).

list_queryable_entitiesA
Read-onlyIdempotent
Inspect

List Queryable Entities this MCP may read. Call this before describe_queryable_entities, query_entity, and aggregate_entity. The catalog is the source of truth: names, descriptions, aliases, one-hop join_targets, and suggested_describe_entities. Pass suggested_describe_entities into one describe_queryable_entities call. Coverage is the public catalog: companies, prices, fundamentals, valuation, consensus, events, filings, and filings-derived knowledge-unit cells. There is no private watchlist, portfolio, or user profile.

Inputs: no named parameters.

pingB
Read-onlyIdempotent
Inspect

Return pong plus the input message.

Inputs: message. Returns: result

query_entityA
Read-onlyIdempotent
Inspect

Read one page of rows from one Queryable Entity. Use this for a point lookup, a multi-period history, or a filtered list. Call list_queryable_entities first, then describe_queryable_entities.

What you can read:

  • company: name, ticker, sector, HQ country. Screen tools need these integer ids.

  • stock_price: daily prices, volume, dividends, and splits. price_explanation: why a significant price move happened.

  • financial_data_point: one row per statement line or ratio per fiscal period. Join time_period and financial_metric. Discover metric keys on financial_metric (name ilike '%net_debt%' finds pre-computed ratios).

  • valuation_multiple: multiples such as P/E and EV/EBITDA, by company and date.

  • consensus_data_point: analyst estimates. Join time_period and consensus_metric. The fiscal period is on time_period (fiscal_year, fiscal_quarter, end_date). consensus_date is the estimate snapshot date, not the fiscal period.

  • earnings_calendar: earnings dates. standard_event: corporate events; for earnings, filter type to "Earnings announcement". file: filings, transcripts, and news. Join company and filter company.symbol.

  • ku_cell: filings-derived knowledge-unit cells. Filter ku.name. An unfiltered read is a short slice of ids. knowledge_unit holds the definitions. company_drivers and executive_summary are per-company narratives. For a qualitative screen across many companies, use screen_drivers or screen_earnings.

  • sector, product, product_category (companies that share a category are peers), and ticker: catalogs. List sector in full. Do not resolve a sector with a single-word ilike filter.

Allowed entities: company, company_drivers, consensus_data_point, consensus_metric, earnings_calendar, executive_summary, file, financial_data_point, financial_metric, knowledge_unit, ku_cell, price_explanation, product, product_category, sector, standard_event, stock_price, ticker, time_period, valuation_multiple, website_change.

Arguments: entity, select, filters, filter_logic (AND or OR, default AND), sort, joins, limit. Filter operators: =, !=, >, >=, <, <=, in, ilike, between, isNull, isNotNull. ilike is a case-insensitive pattern match. Use it to search text such as company names, metric names, and valuation types (stored as NTM_Pe_Med_W). Text search uses ilike with '%x%'. Do not use contains on text fields. For date ranges, use between with [start, end] or >= and <=. Do not use like or ilike on dates. There is no "not in". Use one != filter per value with filter_logic AND. For null checks, use isNull or isNotNull and omit value. Pass IN lists on filter.value. in takes one list item per value, for example ["AAPL","MSFT"]. Do not pass one comma-joined string such as ["AAPL,MSFT"]. Do not pass value_path.

Joins: when a field has join_target, join that table and use alias.field in select, filters, and sort. Many tickers in one query: company.symbol in ["AAPL","MSFT"]. Use a camelCase alias (timePeriod, financialMetric). joins.relation is join_relation when describe shows it, otherwise join_target. On ku_cell, describe knowledge_unit but join relation ku. Other ku_cell relations: groupCompany, cellTimePeriod, cellStandardEvent, groupProductCategory, cellProductCategory. The name product_category matches two ku_cell relations, so it is rejected.

financial_data_point accepts only time_period and financial_metric joins. Do not join company. Filter timePeriod.company_id. Reported actuals use timePeriod.provenance = financials and timePeriod.duration = year. This table has no geographic revenue, segment mix, customer geography, or tariff exposure.

valuation_multiple.value, financial_data_point.value, and consensus_data_point.value are stored as text. A filter on them compares lexicographically ("100" < "99"). For a numeric threshold, use aggregate_entity and put the cut in having.

company.hq_country stores codes and full names. Filter both, for example in ["JP","Japan"]. HK is Hong Kong. CN is mainland China. They do not overlap. Other codes: US, KR.

limit is capped at the entity max_limit (from describe); a larger value returns one capped page with limit_note. A full page sets truncated=true and may include next_hint {field:"id", op:">", value:}. Add that filter, sort by id asc, include id in select, and repeat. There is no offset. For COUNT, SUM, AVG, MIN, MAX, or a threshold screen, use aggregate_entity.

Inputs: entity (required), sort, joins, limit, +3 more.

screen_driversAInspect

Screen each company's fundamental drivers profile against a qualitative criterion such as "depends on AI hyperscaler capex as a primary growth driver", "sensitive to long-end interest rates via mortgage origination", or "tied to Chinese consumer recovery via outbound tourism". Backed by company_drivers — one synthesized profile per company (Type / Topic / Causal Relationship / Support / Current vs. Past). This is durable thesis-level structure, not a recent event.

Pass exactly ONE of:

  • company_ids: explicit DB integer IDs (obtain via query_entity on company).

  • universe: region scopes from all, us, cn, jp, hk, kr. Use ["all"] to scan every company; combine codes (e.g. ["us", "jp"]) to scan those HQ regions. If both are set, company_ids wins and universe is ignored.

No per-call upper bound on N. Large universes including universe=["all"] run in 100-company chunks. No lookback_days — drivers are continuously updated, one row per company.

This tool starts a screen job and returns at once. It does not run the screen in this request. The first response is { "job_id": "...", "status": "queued" }. Then call get_screen_job(job_id) until status is "done" or "error". When status is "done", get_screen_job returns result with summary, matches (the top_n rows), ranked (the full ranked list), and coverage counts. There is no VFS path.

Use this tool for what drives a company over time. Do not use it for a discrete dated event, earnings-period commentary, or a price move attributed to a driver. For exact field filters on company_drivers, use query_entity.

Do not split one thematic question into parallel sector-narrowed calls. Issue one call at the full universe scope, raise top_n if you need more breadth, and group sectors from ranked.

Inputs: criteria (required), top_n, universe, score_all, +1 more.

screen_earningsAInspect

Screen each company's earnings-document cells (10-K, 10-Q, 8-K, 20-F, 6-K, earnings-call transcripts, and related filings extracted into the Earnings Database) against a qualitative criterion such as "explicitly mentioned tariff exposure as a near-term margin headwind" or "called out AI-driven cost savings as a guidance lever". Backed by ku_cell — LLM-extracted structured content from each company's most recent composite earnings filings per fiscal reporting period.

Pass exactly ONE of:

  • company_ids: explicit DB integer IDs (obtain via query_entity on company).

  • universe: region scopes from all, us, cn, jp, hk, kr. Use ["all"] to scan every company; combine codes (e.g. ["us", "jp"]) to scan those HQ regions. If both are set, company_ids wins and universe is ignored.

No per-call upper bound on N. Large universes including universe=["all"] run in 100-company chunks. periods is the number of recent reporting periods per company (default 4).

This tool starts a screen job and returns at once. It does not run the screen in this request. The first response is { "job_id": "...", "status": "queued" }. Then call get_screen_job(job_id) until status is "done" or "error". When status is "done", get_screen_job returns result with summary, matches (the top_n rows), ranked (the full ranked list), and coverage counts. There is no VFS path.

Use this tool for qualitative earnings-period commentary. Do not use it for durable thesis-level drivers (use screen_drivers) or for exact field filters on ku_cell (use query_entity).

Do not split one thematic question into parallel sector-narrowed calls. Issue one call at the full universe scope, raise top_n if you need more breadth, and group sectors from ranked.

Inputs: criteria (required), top_n, periods, universe, +1 more.

search_public_libraryA
Read-onlyIdempotent
Inspect

Search the Public Library. The corpus is the public library, not the caller's private uploads. It holds sell-side research summaries, investor podcast episodes, YouTube video transcripts from finance channels, and industry newsletters. This is the same Agent2 public-library search: an LLM scope planner plus semantic retrieval. query is required and is a natural-language question or topic (for example "Acquired NVDA episode" or "tariff exposure"). Optional doc_types restrict Type tags: "Research", "Podcast", "YouTube", "Newsletter". Pass ["YouTube"] when the user asks for videos, a YouTube channel, or what was said on camera. Optional tickers scopes to Company tags. Optional date_range is one lookback bucket: 7d, 30d, 60d, 90d, 180d, 200d, 1y. Optional brokers hard-filters by research firm. sole_company=true keeps only single-Company-tag docs and needs exactly one ticker. mode is synthesize (default) or list. synthesize returns a narrative answer from semantic passages (a sample, not an exhaustive sweep). list returns a catalog of matching documents. Unknown mode values become synthesize, as in Agent2. The JSON has mode, answer, and sources. Each source has document_id plus title, type, and publication_date when present. This tool does not return full document text. Call get_library_document with one document_id for tags or raw text. Research documents never include full text.

Inputs: query (required), mode, brokers, tickers, +3 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      B
      maintenance
      Financial data and research MCP for AI agents: filings with full-text and fact search, statements as reported, earnings, insider and institutional ownership, corporate events, executives, analyst data, company discovery and research signals for US, China and Japan equities. Every figure traced to its filing. Browser sign-in.
      10
      MIT
    • F
      license
      Not graded
      quality
      A
      maintenance
      Enables natural-language research and structured, source-backed answers across SEC filings, earnings transcripts, company financials, stock and crypto market data, and prediction markets news and research.
      -
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables natural-language questions and structured, source-backed answers across SEC filings, earnings transcripts, company financials, stock and crypto market data, and prediction markets news and research, with orchestration, deep-research agents, and live documentation access.
      MIT
    Try in Browser

    Glama MCP Gateway

    Add one secure layer between your agents and this server.

    Resources