Skip to main content
Glama
FixNPE

agentic-financial-advisor

by FixNPE

Agentic Financial Advisor

A multi-agent financial advisor built with LangChain/LangGraph agents, exposed to each other over the A2A protocol, pulling live market data through an MCP (Alpha Vantage) server, and grounding answers in a local RAG (Chroma) knowledge base. Usable via a chat CLI, a Streamlit UI with a live view of the routing/agent-call flow (plus a RAG Explorer page), or directly from Claude Code — the app's own operations are exposed as an MCP server too.

Informational/educational only — nothing here is personalized financial advice.

Architecture

  • Specialist agents (agents/) — each is a standalone LangGraph create_react_agent, wrapped as an A2A server (agent card + JSON-RPC endpoint) via a2a-sdk:

    • market_research_agent — live quotes/fundamentals/technicals/macro data, via the Alpha Vantage MCP server (mcp_integration/).

    • portfolio_analyst_agent — allocation weighting and concentration risk, via local calculation tools.

    • financial_planning_agent — savings/retirement projections, via local calculation tools.

    • document_research_agent — RAG over data/documents/ using Chroma + local HuggingFace embeddings (rag/).

  • Orchestrator (orchestrator/) — a LangGraph supervisor graph that routes a user query to the relevant specialist agent(s), calls them in parallel over A2A (orchestrator/a2a_client.py), and synthesizes one final answer.

  • main.py — interactive chat CLI that talks to the orchestrator.

User -> main.py -> supervisor graph (route -> fan-out -> synthesize)
                        |         |            |            |
                   market_research portfolio  planning   document_research
                     (MCP: Alpha Vantage)    (local tools)  (RAG: Chroma)

Related MCP server: finance-agent

Setup

python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # fill in ANTHROPIC_API_KEY and ALPHAVANTAGE_API_KEY

If python -m venv fails with ensurepip is not available (this system had no python3-venv/pip installed at all and no passwordless sudo), bootstrap pip inside the venv directly instead of installing the apt package:

python3 -m venv --without-pip .venv
curl -sS https://bootstrap.pypa.io/get-pip.py -o /tmp/get-pip.py
.venv/bin/python /tmp/get-pip.py
.venv/bin/python -m pip install -r requirements.txt

Verify ALPHAVANTAGE_MCP_URL in .env against Alpha Vantage's current MCP documentation — hosted MCP endpoints can change.

a2a-sdk is pinned to ==0.3.26 in requirements.txt: newer 1.x releases restructured the SDK around gRPC/protobuf and dropped a2a.server.apps entirely, which this project's Starlette-based agent servers depend on. This pin was verified against the actual installed package, not assumed.

Running

  1. Start the four specialist agent servers:

    python scripts/run_all_agents.py

    (or run each individually in its own terminal, e.g. python -m agents.market_research_agent). The Document Research Agent auto-ingests data/documents/ into Chroma on first startup if the index is empty — no manual step needed (python -m rag.ingest still works directly if you want to force a rebuild after changing the corpus).

  2. Either the chat CLI, in another terminal:

    python main.py

    or the Streamlit UI, which also shows the routing decision and each agent's call live as it happens rather than only the final answer:

    streamlit run app/streamlit_app.py

    The Streamlit app has a second page, RAG Explorer (in its sidebar), for browsing the Chroma collection — chunks, metadata, a chunk's raw embedding vector, and a live semantic-search test against the same index the Document Research Agent retrieves from.

Corpus

data/documents/ holds the RAG source material: two markdown reference docs (investment glossary, model risk-profile allocations) plus two public government-published PDFs under data/documents/pdfs/ — a FINRA guide to spotting investment scams and a CFPB home-loan toolkit. Ingestion (rag/ingest.py) handles .md, .txt, and .pdf (text-extracted page-by-page via pypdf) uniformly. Drop more files of any of those types into data/documents/ (subdirectories are fine) and either restart the Document Research Agent (auto-ingests if the index was empty) or run python -m rag.ingest to force a full rebuild.

MCP server (use these tools from Claude Code)

mcp_server.py exposes this app's own operations — portfolio allocation, concentration risk, retirement/savings projections, RAG document search, and a full multi-agent advisor query — as MCP tools, the same way the Alpha Vantage MCP server exposes its functions to the Market Research Agent. Every tool is a thin wrapper reusing the actual app logic (the same @tool-decorated calculators the agents use, the same Chroma retriever, the same supervisor graph), not a reimplementation.

It's registered in this project's .mcp.json for Claude Code to pick up as a local (stdio) MCP server. Restart your Claude Code session for a newly added .mcp.json entry to take effect — like skills, MCP servers are loaded at session start, not picked up mid-session.

To test it manually without Claude Code:

python mcp_server.py   # runs the stdio server; Ctrl+C to stop

ask_financial_advisor (the full-orchestrator tool) requires the four specialist agent servers to already be running — it calls out to them over A2A exactly like main.py/the Streamlit UI do. The other five tools (calculators + RAG search) are self-contained and work with just this one process.

Workflow testing

tests/scenarios.json has ~19 test queries covering each specialist agent individually, multi-agent combinations, and edge cases (ambiguous/gibberish input, a zero-value portfolio). tests/run_scenarios.py runs them against the live supervisor graph (requires the four agent servers running and real API keys — these are real LLM/MCP calls, not mocked):

python -m tests.run_scenarios                            # all scenarios
python -m tests.run_scenarios --category market_research  # one category
python -m tests.run_scenarios --id multi-01 planning-02   # specific cases

Router agent-selection mismatches print as warnings (routing is LLM-based and won't always pick the exact expected set); the runner only exits non-zero on a genuine agent error or unhandled exception.

LLM response caching

On by default: a persistent SQLite cache (data/llm_cache.sqlite, gitignored) so re-running the same query/scenario doesn't re-spend on the Anthropic API — useful since tests/scenarios.json gets run repeatedly during development. Measured on a real re-run: ~2x faster, with a genuine (partial, not 100%) reduction in API calls — LangGraph embeds a random tool_call_id into each agent's own tool-calling turns, so those specific turns miss the cache even on an identical repeat query, while the router/synthesizer calls and each agent's first turn hit it reliably.

Set LLM_CACHE_ENABLED=false in .env, or delete data/llm_cache.sqlite, whenever you need a guaranteed-fresh answer — this matters most for market data queries, where an exact-wording repeat would otherwise replay a stale quote instead of fetching a current one.

Observability (LangSmith)

Set LANGSMITH_API_KEY in .env (get one at https://smith.langchain.com/ -> Settings -> API Keys) to turn on full tracing across the whole system — every LLM call, tool call (MCP/RAG/calculators), and LangGraph node in every process shows up in the LangSmith UI under your LANGSMITH_PROJECT. This is zero-code auto-instrumentation from LangChain/LangGraph once the env vars are set (agents/common/observability.py::enable_tracing(), called at the top of every entrypoint). Leave LANGSMITH_API_KEY blank to run with tracing off.

Each user query gets a request_id, generated in main.py/tests/run_scenarios.py and propagated through the supervisor graph and over A2A (as message metadata) to every specialist agent it calls. The orchestrator's own run (route -> fan-out -> synthesize) appears as one nested trace; each specialist agent runs in its own process so it appears as a separate trace, but every trace involved in one user query is tagged with the same request_id — filter on metadata.request_id in the LangSmith UI to reconstruct the full "360 view" of one query across all four agents plus the orchestrator. (Traces aren't stitched into a single literal parent-child tree across the A2A/process boundary — that would need distributed trace-context propagation, which isn't implemented here.)

For a testing view in the LangSmith UI (rather than only console output):

python -m tests.upload_dataset   # push tests/scenarios.json as a LangSmith dataset (idempotent)
python -m tests.langsmith_eval   # run it as an experiment; prints a results URL

This runs the same scenarios as tests/run_scenarios.py but records them as a LangSmith experiment against the financial-advisor-workflow-scenarios dataset — viewable under Datasets & Testing as a results table (routing-match and no-agent-errors scores per row) with a full trace attached to every row.

Notes

  • Embeddings are local (sentence-transformers/all-MiniLM-L6-v2) so RAG works without an extra API key.

  • create_react_agent (from langgraph.prebuilt) is deprecated as of LangGraph 1.x in favor of langchain.agents.create_agent, but still works — every agent in this repo has been smoke-tested against the installed version. Migrate when LangGraph actually removes it (planned for 2.0).

Related MCP Connectors

  • Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.

  • SmartMoney77 MCP v0.6.0 — 14 public tools that turn financial questions into exact numbers and citable links. New: historical_investment_return and compare_investments, which compute "what if I had invested" results from real yearly price data. Also compound interest, FIRE number, credit-card payoff, emergency fund, inflation, latte factor, investment fees, cost of waiting, plus discovery/deep-link/share-pack tools for a catalog of calculators in 6 languages (he/en/ar/es/pt/in). Public, no login. Endpoint: https://smartmoney77.com/mcp

  • Your agent needs markets — prices and fundamentals for listed companies, the filings behind them, crypto, and what the prediction markets put the odds at. **What you can ask for** • "Pull this company's income statement, cash flow and balance sheet for the last 8 quarters." • "What did insiders buy or sell, and when?" • "Snapshot prices for these 50 tickers, then the OHLC history for the three that moved." • "What are the current odds on this event across Kalshi and Polymarket?" • "Screen for companies matching these financial criteria." **How to use it** Point any MCP client at https://mcp.aisa.one/finance/mcp and sign in with OAuth — there is no key to create or paste. 49 tools: prices and snapshots, income statements, balance sheets and cash flows, metrics and ratios, earnings and analyst estimates, filings and line-item search, insider trades, macro interest rates, news, a screener; CoinGecko spot prices, market tables, OHLC, per-venue tickers and trending; Kalshi and Polymarket markets and trades; plus EDINET filings for Japan. **Why this rather than the source** Equities, crypto and event markets behind one account, so a cross-asset question is one conversation. **It is also a door to the rest** The same login reaches 26 sources and 580+ operations. Read the number here, then ask the same agent what X is saying about the ticker today — without adding a second server. **What it costs** Finding and inspecting an operation is free. Running one is billed per call at API prices, with no seat and no monthly minimum, and every call takes max_price_usd so an agent cannot overspend by accident. **Where else it reaches** https://mcp.aisa.one/marketpulse/mcp · /crypto-market-data/mcp · /prediction-market-data/mcp · /stock-pulse/mcp for one slice each.

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides 10 financial data tools (market data, economic indicators, news, insider trades, and calendars) via a single MCP layer, enabling any MCP-compatible LLM to access diverse financial data through a unified interface.
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to call deterministic finance tools (compound interest, loan payment, currency conversion, etc.) through MCP, with a shared tool registry used by both the agent loop and MCP clients.
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Provides live financial data for any LLM agent, including stock quotes, crypto prices, SEC filings, XBRL financials, FX rates, and macro indicators, through ten MCP tools.
    11
    75 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to read and write a self-hosted portfolio tracker through 25 MCP tools, covering net worth, flows, forecasts, decisions, and audit.
    6 npm
    Apache 2.0