Finance MCP Aggregator
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Finance MCP AggregatorAnalyze my portfolio's risk and suggest rebalancing trades."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Finance MCP Aggregator
A Scoped Aggregator pattern MCP server: 43 real finance tools, but the model only ever sees the 4–7 that matter for the current turn.
Built to solve a real, measured problem: MCP servers that statically register every tool up front degrade as the tool count grows past ~15. This project implements the fix — dynamic, intent-routed tool exposure — for a domain (personal finance / investing analytics) where 40+ tools is the realistic end state, not a contrived example.
1. The problem, with numbers
Give an LLM 40+ tool schemas in its system prompt on every single turn and four failure modes compound:
Failure mode | Mechanism | Effect |
Attention dilution | Tool definitions in the middle of a long prompt get less attention ("lost in the middle") | Wrong tool picked, or the right tool picked with the wrong arguments |
Name/description collisions |
| Coin-flip tool selection |
Parameter hallucination | Model has 40+ schemas competing for context; it blends fields from one schema into a call to another | Invalid API calls, retries, silent wrong answers |
Context/cost bloat | Every tool schema is JSON sent on every turn, whether used or not | Fewer tokens left for actual conversation, higher per-call cost |
This project measures — not just claims — the first and last of those for its
own tool catalog. Run benchmarks/benchmark_routing.py yourself; here's what
it produced on this repo's 43-tool registry:
TOKEN COST: static merge (43 tools) vs scoped aggregator
Architecture Tokens/turn Tokens/10 turns
Static merge (all 43) 1754 17540
Scoped aggregator 338 3380
Reduction in tool-schema tokens per turn: 80.7%
ROUTING ACCURACY: expected tool in top-6 results
Top-6 accuracy: 25/26 (96.2%) on a 26-query evaluation set spanning all 6 domains(Token counts are a ~4-chars/token estimate, order-of-magnitude accurate —
swap in tiktoken or Anthropic's tokenizer for exact figures. The
methodology is transparent in the script, not a black box.)
What this means in practice: at $3/M input tokens and 500 tool-augmented
turns/day, the static-merge architecture spends roughly $0.79/day on tool
schemas alone that never get called; the scoped aggregator spends about
$0.15/day for the same volume — and, more importantly, the accuracy numbers
above are what actually protects you from a misrouted execute_trade-style
call in a finance context, where a wrong tool call isn't just an annoyance.
Related MCP server: mcp-compressor
2. Why finance, specifically
Personal finance / investing assistants are one of the few domains where 40+ distinct tools is the honest requirement, not an artificially inflated demo:
Market data (quotes, history, news, earnings dates, dividends, splits)
Portfolio analytics (value, returns, Sharpe ratio, diversification, rebalancing, CAGR, drawdown, benchmarking)
Risk analytics (VaR, beta, volatility, stress testing, correlation, Monte Carlo simulation)
Technical analysis (SMA, EMA, RSI, MACD, Bollinger Bands, support/resistance, ATR, Fibonacci)
Fundamental analysis (P/E, EPS, balance sheet, income statement, cash flow, DCF valuation)
Currency & crypto (FX conversion, live rates, crypto pricing, gas fees)
A real product covering all six domains genuinely needs on the order of 40+ tools. Trying to force that into a single flat MCP tool list is exactly the scenario the Scoped Aggregator pattern is meant for — this repo is that pattern applied to a domain where it's load-bearing, not decorative.
3. Architecture
┌─────────────────────────┐
│ LLM / MCP Client │
│ (Claude Desktop, etc.) │
└────────────┬─────────────┘
│ sees only 4 meta-tools,
│ not all 43
┌───────────────────▼────────────────────┐
│ finance_mcp/server.py │
│ list_finance_categories() │
│ search_finance_tools(query, top_k) ────┼──┐
│ get_tool_schema(tool_name) │ │ 1. TF-IDF cosine
│ execute_finance_tool(tool_name, params) │ │ similarity ranks
└───────────────────┬────────────────────┘ │ query against all
│ │ 43 tool docs
┌────────────▼────────────┐ ◄────────┘
│ router.py (IntentRouter)│
│ ranks registry.py's │
│ 43 ToolSpecs by relevance │
└────────────┬────────────┘
│ 2. top-k names resolved
┌────────────▼────────────┐
│ executor.py │
│ lazily imports + calls │
│ the winning tool │
└────────────┬────────────┘
│
┌───────────────────▼────────────────────┐
│ tools/market_data.py │
│ tools/portfolio_analysis.py │
│ tools/risk_analysis.py │ ← 43 tools total,
│ tools/technical_analysis.py │ only imported when
│ tools/fundamental_analysis.py │ actually called
│ tools/currency_crypto.py │
└──────────────────────────────────────────┘The flow an LLM actually follows:
search_finance_tools("what's my portfolio's Sharpe ratio")→ returns the 5–6 relevant tools (not all 43), each with its exact parameter schema.execute_finance_tool("calculate_sharpe_ratio", {...})→ runs it.
No dependence on MCP clients supporting tools/list_changed notifications
(many don't, reliably) — the narrowing happens inside a normal tool call,
which every MCP client already supports. This is the same "search then act"
shape you'll recognize from how large codebases expose tool search to
coding agents, applied here to a finance tool catalog.
Why TF-IDF instead of an LLM router or embeddings model
No extra LLM call — a router that itself needs GPT-4 to pick a tool defeats the purpose (latency + cost on every turn).
No heavyweight download —
scikit-learninstalls in seconds on a plain Windows Python 3.12 environment; notorch, no model weights.Deterministic and debuggable — you can inspect exactly which words matched.
Swappable —
router.pyincludes anEmbeddingRouterwith the same interface for when a catalog grows past a few hundred tools and paraphrase-level matching starts to matter more than raw token overlap. See Scaling further below.
4. Project structure
finance-mcp-aggregator/
├── README.md
├── requirements.txt
├── pyproject.toml
├── .env.example
├── .gitignore
├── LICENSE
├── src/finance_mcp/
│ ├── server.py # MCP server: 4 meta-tools only
│ ├── router.py # IntentRouter (TF-IDF) + EmbeddingRouter
│ ├── registry.py # Metadata for all 43 tools (no imports of impls)
│ ├── executor.py # Lazy resolve + call by dotted path
│ └── tools/
│ ├── _data_source.py # yfinance wrapper w/ offline synthetic fallback
│ ├── market_data.py # 8 tools
│ ├── portfolio_analysis.py # 8 tools
│ ├── risk_analysis.py # 7 tools
│ ├── technical_analysis.py # 8 tools
│ ├── fundamental_analysis.py # 6 tools
│ └── currency_crypto.py # 6 tools
├── benchmarks/
│ └── benchmark_routing.py # Token-cost + routing-accuracy measurements
├── tests/
│ └── test_router.py
└── examples/
└── demo_client.py # Runs the search→execute flow with no LLM/API key5. Setup (Windows, Python 3.12.4)
git clone https://github.com/<you>/finance-mcp-aggregator.git
cd finance-mcp-aggregator
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
copy .env.example .envRun the demo (no MCP client, no API key needed)
python examples\demo_client.py "what's my portfolio's value at risk"Run the benchmark yourself
python benchmarks\benchmark_routing.pyRun tests
pytest tests\ -vRun the actual MCP server
Built on the standalone fastmcp
package (not the trimmed-down mcp.server.fastmcp bundled inside the
official mcp SDK) — it tracks the MCP spec closer to real-time and adds a
dev inspector, auth providers, and an HTTP transport out of the box.
# stdio (default) -- what Claude Desktop and most MCP clients expect
python -m finance_mcp.server
# or run it as a standalone HTTP server instead
$env:MCP_TRANSPORT="http"; $env:MCP_PORT="8000"; python -m finance_mcp.serverTo use it from Claude Desktop, add to your MCP config
(%APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"finance-aggregator": {
"command": "C:\\path\\to\\finance-mcp-aggregator\\.venv\\Scripts\\python.exe",
"args": ["-m", "finance_mcp.server"]
}
}
}You can also inspect it live with FastMCP's built-in dev tool before wiring it into any client:
fastmcp dev src\finance_mcp\server.pyNote on live data: every tool falls back to deterministic synthetic
data when yfinance has no network access, so the whole test/benchmark
suite runs fully offline. With network access, get_stock_price,
get_historical_prices, get_pe_ratio, etc. pull real data via yfinance
(no API key required).
6. Scaling further than this repo
This repo's registry (43 tools, TF-IDF router) is sized to be genuinely runnable end-to-end without any paid API or heavy install. If you fork this for a catalog of hundreds of tools across many MCP servers, the pattern extends cleanly:
Categorization → Intent routing → Dynamic ingestion, exactly as described in the architecture above, generalizes past one server: put an aggregator server in front of multiple downstream MCP servers (each exposing its native tools), and have the aggregator's
search_toolsfan out across all of them.Swap
IntentRouterfor the includedEmbeddingRouter(pip install sentence-transformers) once paraphrase matching ("how risky is my portfolio" ≈ "what's my VaR") starts mattering more than keyword overlap — this repo's benchmark script is the harness to validate that swap actually improves top-k accuracy before you ship it.For MCP clients that do support
notifications/tools/list_changed, you can go further and only ever expose the narrowed tool list itself (not meta-tools) — trading universal compatibility for a marginally smaller prompt.
7. What this is not
Not investment advice, and not wired to a brokerage — every calculation tool is a standalone analytics function you'd still validate before acting on.
The offline synthetic price fallback exists so tests/CI/demos don't require network or an API key; it is clearly labeled
"source": "synthetic-offline"in every response so it's never confused with real market data.The DCF, Monte Carlo, and VaR implementations are standard textbook formulations for demonstration; a production system would want a reviewed quant library and real-world backtesting before being trusted with real allocation decisions.
Repository health and contribution model
This repository is structured so it can be pushed and maintained as a clean, open-source Python package:
Source code lives under
src/finance_mcp/and is buildable throughpyproject.toml.Tool metadata lives in a registry rather than scattered implementation details.
The public API is exposed through the server entry point and a stable set of search/execute tools.
Contribution docs are available in
CONTRIBUTING.md,SECURITY.md, andCHANGELOG.md.CI automation, issue templates, and pull request templates are available under
.github/.
If you are preparing a public repository push, keep the branch history small and the release artifacts explicit.
License
MIT — see LICENSE.
Available Tools
4 toolsexecute_finance_toolA
Execute a specific finance tool by name with the given parameters. Always call search_finance_tools or get_tool_schema first to confirm the correct tool name and parameter shape -- this avoids parameter hallucination from guessing at an unseen schema.
| Name | Required | Description | Default |
|---|---|---|---|
| params | Yes | ||
| tool_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the full burden of behavioral disclosure. It fails to state whether execution is read-only or mutating, what side effects may occur, or how results are returned. The only non-obvious context is the warning about hallucination, which is more usage guidance than behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the core purpose, and includes a highly relevant usage directive. Every sentence adds value, with no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity as a dynamic dispatcher, the description adequately covers the key context: how to invoke it and the prerequisite discovery steps. The presence of an output schema means return values need not be explained. However, it does not address error handling or invalid inputs, which would make it fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description provides minimal added meaning. It implicitly acknowledges tool_name and params ('by name with the given parameters') but does not elaborate on their formats, constraints, or the expected structure of the params object. The description does not compensate for the lack of schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific action: 'Execute a specific finance tool by name with the given parameters.' This distinguishes the tool from its siblings (list_finance_categories, search_finance_tools, get_tool_schema) by identifying it as the executor, not a discovery or schema tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit directive: 'Always call search_finance_tools or get_tool_schema first to confirm the correct tool name and parameter shape.' This clearly indicates when and how to use the tool (only after confirmation) and explains the rationale for avoiding parameter hallucination, thereby differentiating it from the discovery tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tool_schemaA
Get the exact parameter schema for a single named finance tool (use after search_finance_tools has told you the tool name).
| Name | Required | Description | Default |
|---|---|---|---|
| tool_name | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It suggests a read-only operation via 'Get' and adds the prerequisite that the tool name comes from search_finance_tools. However, it does not explicitly state error behavior or confirm non-mutating status, leaving some opacity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the main action and integrates the usage guidance efficiently. Every word contributes to understanding the tool's purpose and workflow.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple one-parameter tool with an output schema, the description adequately covers purpose, usage, and parameter meaning. It lacks explicit error-handling details, but the simplicity and output schema mitigate the gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description adds meaning by explaining that tool_name is the name of a finance tool and should be the value returned by search_finance_tools. This provides essential context beyond the bare 'string' type.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action ('Get') and the specific resource ('exact parameter schema') for a single named finance tool. It also differentiates from siblings by indicating it follows search_finance_tools, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly states when to use it: 'use after search_finance_tools has told you the tool name'. This provides clear sequencing and implies it is for schema retrieval rather than execution, which distinguishes it from execute_finance_tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_finance_categoriesA
List the domains of finance tools available (market data, portfolio analysis, risk analysis, technical analysis, fundamental analysis, currency/crypto) along with how many tools live in each.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It clearly states that the tool lists domains and provides tool counts, and implies a read-only, non-destructive action. For a simple listing tool, this is sufficient transparency; no hidden side effects or additional requirements are relevant.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the verb, resource, and key output aspects. It lists examples efficiently without redundancy and earns its place with high information density.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter tool with an output schema present, the description is complete. It covers what the tool does (lists domains) and what it returns (domain names and counts), and the sibling context makes the tool's role clear. No further detail is required.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, which gives a baseline of 4. The description adds meaningful context beyond the empty schema by naming example categories and explaining the output includes tool counts. However, since there are no parameters to describe, the contribution is minimal but acceptable.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and names a clear resource ('domains of finance tools'), enumerates example categories, and notes the counts per domain. This distinguishes it from siblings like search_finance_tools, get_tool_schema, and execute_finance_tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The context in which to use this tool is implied (exploration/discovery of available finance domains), but there is no explicit statement of when to prefer it over alternatives or any exclusion criteria. The sibling tools are not referenced in the description, so no when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_finance_toolsA
Find the finance tools most relevant to a natural-language request.
Call this FIRST before execute_finance_tool. It searches across all 43 registered finance tools (market data, portfolio analysis, risk, technical analysis, fundamentals, currency/crypto) and returns only the ones relevant to your query, each with its name, description and the parameters it expects -- so you never need the full tool catalog in context at once.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| top_k | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosure. It discloses that this is a read-only search operation across all 43 tools, returns only relevant tools, and includes name, description, and expected parameters. It does not discuss exact matching semantics or edge cases, but it provides substantial behavioral context for a discovery tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no wasted words. It is front-loaded with the core purpose, then provides usage ordering, and finishes with a rationale for why the tool avoids loading the full catalog. Every sentence contributes unique value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 2-parameter search tool with an output schema, the description covers purpose, tool categories, return content, and usage order. It does not explicitly explain both parameters in prose, but the output schema and simple schema reduce that burden, making it mostly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description only implicitly clarifies the 'query' parameter as a natural-language request. It does not mention 'top_k', its default, or how it affects the result set. The parameters are simple enough to infer, but the description adds minimal value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('find') and resource ('finance tools most relevant to a natural-language request'), clearly distinguishing this discovery tool from the execution sibling. It explicitly contrasts with execute_finance_tool by stating it returns tool metadata rather than executing, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit sequencing by saying 'Call this FIRST before execute_finance_tool,' which gives clear usage context. It also describes the broad coverage across all 43 finance tools, but it does not explicitly state when to use list_finance_categories or get_tool_schema instead, so it lacks a full alternatives exclusion.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
TDQS
Each tool has a distinct role: listing categories, searching for tools, fetching schemas, and executing. There is no functional overlap between any two tools.
All tool names follow a consistent verb_noun pattern (list_finance_categories, search_finance_tools, get_tool_schema, execute_finance_tool), making the API predictable and easy to navigate.
With only 4 tools, the server is well-scoped for its aggregator purpose. Instead of exposing 43 tools directly, it provides a lean meta-layer that is easy to learn and use.
The tool set covers the full discovery-to-execution workflow: list categories, search, get schema, and execute. There are no obvious missing operations for an aggregator that intentionally hides the underlying tool catalog.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Personal finance for AI agents — onboard, import statements, categorize & budget over MCP.
MCP server connecting AI agents to non-custodial staking data across 130+ networks.
Hosted MCP server for LLM cost estimation, model comparison, and budget-aware routing.
The financial MCP for AI agents - 90+ financial tables, SEC filings, signals, alt-data.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA meta-server that aggregates multiple MCP servers into a single interface, reducing token usage by 98%+ through progressive tool discovery and direct code execution that processes data between tools without consuming context window space.1610Apache 2.0
- AlicenseNot gradedqualityAmaintenanceA proxy server that wraps existing MCP servers to significantly reduce token consumption by compressing tool descriptions into a two-step interface. It enables users to integrate extensive toolsets without exceeding context limits or incurring high API costs.116Apache 2.0
- AlicenseAqualityAmaintenanceAn MCP orchestration layer that aggregates multiple MCP servers while exposing only 8 meta-tools, dramatically reducing context window usage, and provides SLOP scripting, event monitoring, and tool customization.10MIT
- AlicenseNot gradedqualityDmaintenanceEnterprise-grade dynamic MCP proxy that eliminates token bloat by lazy-loading tool schemas based on semantic intent, enabling efficient orchestration of multiple backend tools from a single endpoint.MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/YugMakhecha17/MCP_Aggregator'
If you have feedback or need assistance with the MCP directory API, please join our Discord server