finanal-mcp
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., "@finanal-mcpExplain the macro and narrative behind NVDA's rally."
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.
finanal-mcp
A minimal, token-efficient MCP server that combines stock prices and fundamentals with the macro and micro narrative around them — so an AI agent can reason about why a stock moved, what people are thinking about it, and what probable scenarios lie ahead.
Why this project exists
Knowing a stock's PE ratio or current price is not enough. The interesting questions are: why did this stock dip today? What does the market narrative say about it? What are the macro tailwinds or headwinds? What could happen next?
Answering those questions requires combining three things simultaneously:
Fundamentals and price data — earnings, ratios, revenue growth, institutional flows
Real-time news and macro context — what analysts, media, and macro events are saying
The narrative — sentiment, concall tone, sector rotation, management guidance
The tools chosen — FMP, Tapetide, and Tavily — are the best available for each of those jobs. FMP is the gold standard for US stock fundamentals. Tapetide is purpose-built for Indian NSE/BSE data with native MCP support. Tavily is a research-grade search engine that retrieves and synthesises real-time financial news.
Why not use the existing MCP servers for these tools directly?
All three providers publish their own MCP servers, but each exposes 50–100+ individual tools. Every tool description gets embedded into the system prompt of every LLM call. With three servers active that's potentially 150–300 tool descriptions injected into every single prompt — input tokens explode, costs spike, and the LLM gets confused by the noise.
This project is the solution: one MCP server, 6 tools maximum. The LLM talks to a single router that knows which underlying API to call, how to call it, and what parameters to use. The input token footprint stays flat no matter how many endpoints exist in the index.
finanal-mcp in one sentence: ask any financial question in plain English — the server finds the right API, calls it, and caches the answer for instant reuse.
Related MCP server: OpenInsider MCP
Why it is built this way
Decision | Rationale |
6 tools maximum | Each tool description is injected into every LLM prompt. Keeping the count to 6 keeps the input token footprint minimal and constant (~159 tokens total), regardless of how many underlying endpoints are indexed. |
Slim |
|
Response field trimming in | Known-verbose fields ( |
SQLite + FTS5 BM25 instead of vector embeddings | The endpoint index is ~300 rows. BM25 + finance synonyms hits ~90% accuracy with zero extra dependencies and zero latency. Vector search adds complexity and a model inference call for no measurable gain at this scale. |
Finance synonym expansion baked into | "PE ratio", "price to earnings", "valuation multiple" are the same query. Expanding tokens before FTS search avoids the most common failure modes without needing an LLM call. |
Tapetide as a proxied MCP server instead of a direct REST client | Tapetide exposes a native MCP server at |
Tavily for news instead of FMP news endpoints | FMP's news APIs require a paid plan (return HTTP 402 on free tier). Tavily's search engine covers US/global news, macro events, and earnings headlines on the free tier with far richer synthesis. |
Recipe cache as the first tool call | BM25 is fast but not perfect. Recipes are exact-match quality. Any question answered once correctly is answered instantly forever after, with zero redundant API discovery. A recipe hit skips both |
uv for all Python | Reproducible builds, fast installs, no system Python pollution. All commands use |
Source routing rules
These rules are enforced both in the search_apis tool description and in seeded recipes,
so any LLM using this server learns them from the first call.
Source | Use for | Never use for |
tapetide | Indian NSE/BSE: quotes, news, fundamentals, shareholding, FII/DII, screener, concalls | US or global stocks |
fmp | US and global stocks: price, financials, earnings, analyst estimates, SEC filings | News (paywalled, returns 402) |
tavily | All news and macro: US stock news, Fed/RBI decisions, earnings headlines, any web search | N/A — use as fallback for anything news-shaped |
Why not just use prompt caching?
A fair question: FMP, Tapetide, and Tavily each publish their own MCP servers. If you registered all three directly, the LLM would have the full tool list in its context. And since modern LLMs (Claude, GPT-4o) cache the system prompt, subsequent calls would hit the cache at ~90% discount — so it would barely cost anything after the first call, right?
Prompt caching fixes the wallet problem. This architecture fixes the brain problem. Even with perfect cache hits, monolithic tool registrations still fail in three ways:
1. Cache eviction tax (TTL ~5–10 minutes)
Prompt caches are ephemeral. Most providers evict after 5–10 minutes of inactivity. If a user pauses to read, grabs a coffee, or writes a long reply — the cache evicts. The very next turn re-indexes all 150–300 tool schemas at 1.25× the base rate (cache-write premium), and the full cost resets. With 6 tools and ~159 tokens of descriptions, a cache eviction costs fractions of a cent. The TTL problem simply disappears.
2. Model attention tax ("lost in the middle")
Even if holding 200,000 tokens of tool schemas in context is cheap, it is not free for the
model's reasoning. When an LLM has to parse 500 tool schemas simultaneously its retrieval
accuracy degrades measurably — it hallucinates optional parameters, confuses endpoints with
similar names, and dilutes attention on the actual task. By routing through search_apis
first, the model only sees the 3–4 tools it actually needs for that specific turn.
Attention stays sharp.
3. Context window starvation
Every model has a hard context limit. If 200,000 tokens are permanently occupied by monolithic tool schemas, that is 200,000 fewer tokens available for conversation history, API response payloads, and deep reasoning. For a tool-heavy financial workflow where API responses can be large, this matters.
The compounding win: recipes
The deeper lever is the recipe cache. A recipe hit means the model calls exactly one
tool (search_recipes) instead of the usual three (search_recipes → search_apis →
get_api_details → call_api). Every question answered correctly makes the next identical
question instant and near-zero cost. The system gets cheaper and more accurate over time.
Measured token budget
Component | Tokens |
All 6 tool descriptions combined | ~159 |
| ~310 |
| ~1,232 |
FMP | ~149 |
FMP | ~360 |
A typical recipe hit (skips search entirely) | ~80 |
Architecture
Copilot / LLM agent
│
▼
finanal-mcp (stdio)
┌─────────────────────────────────────────────┐
│ search_recipes ← check cache first │
│ search_apis ← BM25 + synonym index │
│ get_api_details ← full schema for endpoint │
│ search_docs ← BM25 doc search │
│ call_api ← live API call │
│ save_recipe ← cache successful answer │
└──────────────┬──────────────────────────────┘
│ routes by source field
┌─────────┼──────────┐
▼ ▼ ▼
FMP REST Tavily REST Tapetide MCP
(US/global) (news) (India NSE/BSE)Prerequisites
Python ≥ 3.14
uv—brew install uvorpip install uvAPI keys for FMP, Tavily, and Tapetide (free tiers available for all three)
Setup
git clone <repo>
cd finanal
uv sync
cp .env.example .env
# Edit .env and fill in your three API keysGet your keys:
FMP: https://site.financialmodelingprep.com/developer/docs — free tier, 250 req/day
Tavily: https://app.tavily.com — free tier, 1,000 credits/month
Tapetide: https://tapetide.com/mcp — free token from settings
Seed the endpoint index
Run once after cloning (or after pulling updates):
uv run scripts/seed_fmp_scrape.py # 236 FMP endpoints from official docs
uv run scripts/seed_tavily.py # 7 Tavily endpoints
uv run scripts/seed_tapetide.py # 49 Tapetide tool schemas
uv run scripts/enrich_docs.py # 348 synthetic BM25 docsVerify with smoke tests
uv run scripts/test_search.py
# Expected: 15/15 ✓ all rank-1Run the MCP server
uv run python main.pyThe server communicates over stdio and is consumed by VS Code / Copilot via the MCP protocol. You do not interact with it directly.
Register in VS Code (user-level — works in all workspaces)
Add to ~/Library/Application Support/Code/User/mcp.json (macOS) or the equivalent
user-level mcp.json on your OS:
{
"servers": {
"finanal-mcp": {
"type": "stdio",
"command": "uv",
"args": ["run", "python", "main.py"],
"cwd": "/absolute/path/to/finanal"
},
"tapetide-mcp": {
"type": "http",
"url": "https://mcp.tapetide.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_TAPETIDE_TOKEN",
"Content-Type": "application/json",
"Accept": "application/json, text/event-stream"
}
}
}
}Note:
tapetide-mcpis registered separately as an HTTP server so Copilot can call its tools directly (faster path).finanal-mcpproxies through to it as well, but direct registration gives Copilot access to all 49 Tapetide tools without going through the router.
How to use it from Copilot Chat
finanal-mcp is a tool router, not a chat assistant. An LLM agent (Copilot, Claude,
etc.) calls its tools to discover and invoke the right financial API. The mandatory workflow:
Step-by-step tool call order
1. search_recipes(query)
└─ If score < -1.0 → use that recipe directly, skip to call_api. Done.
2. search_apis(query, source="fmp"|"tapetide"|"tavily")
└─ Returns ranked endpoint list with id, summary, source, parameters.
3. get_api_details(endpoint_id)
└─ Returns full parameter schema so call_api gets the right args.
4. call_api(endpoint_id, params={...})
└─ Executes the live API call and returns the data.
5. save_recipe(question, summary, endpoint_ids=[...])
└─ Always save after a good answer — next identical query is instant.Example queries and what happens
Query | Route | Tool sequence |
"Polycab current price" | tapetide | search_recipes → call_api(tapetide get_stock_quote) |
"VRT Vertiv stock price" | fmp | search_recipes → call_api(fmp /profile) |
"Polycab latest news" | tapetide | search_recipes → call_api(tapetide get_stock_news) |
"Vertiv news 2026" | tavily | search_recipes → call_api(tavily /search, topic=finance) |
"RELIANCE PE ratio" | fmp | search_recipes → search_apis → call_api(fmp /ratios) |
"India FII DII flows today" | tapetide | search_recipes → call_api(tapetide get_fii_dii_flows) |
"US Fed rate decision news" | tavily | search_recipes → call_api(tavily /search, topic=news) |
Teaching the server new routing rules
Seed recipes directly:
import db
conn = db.get_conn()
db.upsert_recipe(
conn,
question="Get quarterly earnings for an Indian company",
summary="Use tapetide get_financials (source=tapetide), section='profit_loss'.",
endpoint_ids=[22],
)
conn.commit()Or use the save_recipe tool from within a Copilot chat session after a successful answer.
DB state (after full seed)
Source | Endpoints | Notes |
fmp | 236 | Scraped from official FMP docs + community OpenAPI YAML |
tapetide | 49 | Tapetide native MCP tool schemas |
tavily | 7 | Hand-crafted from Tavily OpenAPI spec |
Total | 292 | |
Docs (BM25) | 348 | Synthetic per-endpoint + per-tag-group docs |
Recipes | 6+ | Seeded routing rules; grows with use |
Key files
main.py ← FastMCP server — 6 tools, source-aware call_api routing
db.py ← SQLite schema, FTS5 tables, BM25 search, synonym expansion
scripts/seed_fmp_scrape.py ← Primary FMP seed (236 endpoints from scraped docs)
scripts/seed_fmp.py ← Secondary FMP seed (community OpenAPI YAML, 181 endpoints)
scripts/seed_tavily.py ← Tavily endpoint seed
scripts/seed_tapetide.py ← Tapetide tool schema seed
scripts/enrich_docs.py ← Synthetic BM25 doc generation (348 docs)
scripts/test_search.py ← Smoke tests (15/15 expected)
specs/tavily.yaml ← Hand-crafted Tavily OpenAPI spec
data/finanal.db ← SQLite database (gitignored)
.env.example ← API key template
.github/copilot-instructions.md ← Copilot tool workflow instructionsMaintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- 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/Sekharz/finanal'
If you have feedback or need assistance with the MCP directory API, please join our Discord server