Broker- and provider-agnostic MCP tool suite for market data, trading, and financial analysis
Agora demonstrates solid fundamentals: all 10 tools have clear verb-noun naming (get_*, cancel_*, flatten_*), detailed descriptions (avg 180 chars, well within 10-1024 range), and complete JSON Schema input definitions with typed parameters. However, critical gaps prevent a higher score: (1) NO output schemas documented anywhere, LLMs cannot plan downstream calls or extract fields; (2) tool annotations (readOnlyHint, destructiveHint) are declared in metadata but NOT visible in the actual tool registration code; (3) error handling descriptions are present but lack recovery guidance (e.g., 'rejectCode NOT_FOUND' mentioned but no 'try X instead'); (4) parameter descriptions are good but some lack format/range constraints (e.g., 'fraction' has no bounds stated in description, only in schema 0 < fraction <= 1). Composition is strong, tools are single-responsibility and chain well (e.g., list_connections → cancel_order). Security is sound, no secrets in params, write operations properly gated.
Cancel an open order by broker order id. An unknown order id is reported as a result, not an outage: accepted=false with rejectCode NOT_FOUND (the order may already be cancelled, expired or filled) -- do not retry it.
Close (flatten) a position for a given symbol via market order on the named connection. By default closes the entire position; pass fraction or qty for a partial close. A partial close restores the protective orders sized to the remainder and returns their new ids under protective_legs, keyed by the id each replaces. No open position for the symbol is reported as a result, not an outage: accepted=false with rejectCode NO_POSITION -- do not retry it.
Retrieve account summary: equity, buying power, cash balance, and account status for the named connection.
Analyst RECOMMENDATION counts for a symbol — buy/hold/sell trend by period (strongBuy/buy/hold/sell/strongSell counts), not EPS or revenue estimates. For EPS/revenue estimates use get_earnings_estimates.
List closed (already-settled) positions on the named connection, with real broker fill prices/P&L — for reconciling a position that closed at the broker (e.g. stopped out) between reconcile cycles.
No output schemas documented. LLMs cannot infer response structure, field names, or types. Prevents downstream tool chaining and forces agents to guess at field extraction.
Error handling descriptions mention rejection codes (NOT_FOUND, NO_POSITION) but lack recovery guidance. 'Do not retry it' is stated but no alternative action suggested (e.g., 'try list_connections to verify the connection exists').
Parameter 'fraction' in flatten tool has constraint (0 < fraction <= 1) in schema but description does not state bounds. LLMs cannot read JSON Schema constraints, they rely on description text.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 59 | 2026-07-28+ | v2 |
Full reported history of any XBRL company-concept (e.g. us-gaap/Assets) for a company by symbol or CIK, with the reporting unit and per-period datapoints.
Reported history of several XBRL us-gaap company-concepts for a company (by symbol or CIK) in one fetch. Input `tags` selects the concepts (e.g. Assets, LiabilitiesCurrent). Returns per requested tag its reporting unit and per-period datapoints — same shape as get_company_concept — under `facts`. Cheaper than N get_company_concept calls for one company.
Recent company news headlines for a symbol, merged from multiple sources. Each item carries sourceType (news|social) and domain (lowercase url host without www., null when the url is missing or unparsable); partial provider failures are reported in a top-level warnings array.
Company profile (name, industry, exchange, market cap) for a symbol.
Recent and upcoming earnings events for a symbol.
Tool annotations (readOnlyHint, destructiveHint) declared in feature metadata but not visible in McpToolAdapter.java tool registration. Verify annotations are actually passed to SyncToolSpecification.builder().
get_company_concept requires 'tag' but accepts optional 'symbol' or 'cik'. Dependency not documented: 'Either symbol or cik is required; if both omitted, tag alone is insufficient.' LLMs may pass tag without a company identifier.