finagent-mesh-mcp
Click on "Deploy 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., "@finagent-mesh-mcpRank SEC filing types and passages for Apple's 2024 revenue risks, then summarize."
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.
finagent-mesh-mcp
Hybrid financial agent stack for evaluating open System-1 decision models on FinAgentBench: typed Choice (which SEC filing type?) then Score / dense / lexical ranking (which passages?), with optional Gemini System-2 answer synthesis, MCP tools, and MLflow Runs/Traces.
Target hardware: HP ZGX Nano / NVIDIA DGX Spark (Grace Blackwell ARM64, ~128GB unified memory). Heavy engines are served one at a time (sequential exclusive GPU ports).
What this repo does
Institutional questions over SEC filings need document structure and passage evidence. This harness:
Samples FinAgentBench examples (document-type + chunk labels).
Runs a LangGraph agent: Stage-1 Choice → Stage-2 Score → nDCG@5 / MAP@5 / MRR@5 → optional Gemini synthesis + answer EM/F1.
Sweeps a Choice × Score paper matrix (Block A / Block B) across open decision models and strong baselines.
Writes paper-facing analysis, CSV/JSON tables, and per-example inspect HTML, with nested MLflow Runs/Traces for debugging.
Reading order for the “why”:
Doc | Audience | Contents |
Developers & architects | Short note: agent shape, FinAgentBench, MCP, performance/safety — takeaways from | |
Deeper survey | System-1 landscape, trade-offs, failure modes |
Related MCP server: SEC EDGAR Data MCP
Why FinAgentBench
Choi et al., FinAgentBench, ACM ICAIF 2025 provide ~26K annotated examples with two explicit retrieval steps and nDCG@5 / MAP@5 / MRR@5. This repo uses the ICAIF’25 challenge dump (~2.4K) from Kaggle.
Resource | Link |
Paper (ACM DL) | |
UNIST record | |
ICAIF’25 challenge | |
Kaggle data |
Pipeline stage | Job | Primitive |
Stage 1 | Rank 5 filing types | Choice |
Stage 2 | Rank passages inside the Top-1 type | Score / Action Cache / BM25 / E5 |
System 2 (optional) | Answer from top-K evidence | Gemini Flash (fail-closed) |
Further reading: Jev architecture probes, Decision 1.0/2.0, CLM, AnyJev / arXiv:2610.00831, JevBench.
How the benchmark is built
Block A — Stage-1 Choice varies; Stage-2 Lux Score is fixed. Differences in Stage-1 nDCG@5 / Top-1 recall measure routing quality.
Block B — Stage-1 Lux Choice is fixed; Stage-2 Score (or BM25 / E5 / CLM) varies. Compare overall Stage-2 nDCG@5 (full pipeline) and S2 nDCG@5|Top-1 (scorer quality when the filing type was correct).
Wrong Top-1 type yields empty_top1_chunks — a routing failure, not a scorer bug. Those examples contribute 0 to overall S2 nDCG and are excluded from conditional-on-Top-1 metrics.
Default matrix = required pairs in configs/engines.yaml (optional: false). --real defaults to ranking-only and N = min(200, dataset size).
MLflow parent Run (matrix run_id)
└─ nested Run (run_id:example_id)
└─ Trace: finagent_example
├─ stage1 Choice → stage2 Score → metrics
└─ (optional) gemini_synthesize → answer_scoreModels selected
Survey latency / composite figures are not FinAgentBench scores — they guide architectural fit; run --real for numbers.
In the harness
Model | Architecture | Params / context | FinAgent Mesh role |
Decision-2.0 Lux-9B | Qwen3.5 + Gated DeltaNet | ~8B / 16k | Shared Block A Score + Block B Choice ( |
Decision-2.0 Kai-0.6B | Vela encoder | 0.6B / 1k | Fast Stage-1 Choice. HF |
CLM-8B | Frozen Qwen3-8B dual encoder + InfoNCE | 8B+ / 2k | Stage-2 Action Cache. HF |
AnyJev L0 | Cyclic permutations on Lux Choice | inherits | Stage-1 order-bias control. GitHub |
Laya (ModernBERT) | Bidirectional MLM heads | 421M / 512 | Edge Stage-1. HF |
Qwen3-8B AR | Autoregressive JSON | 8B | Generative baseline ( |
BM25 / E5-base | Lexical / dense | — | Strong Stage-2 baselines |
Default pairs (configs/engines.yaml → matrix_pairs)
Pair id | Block | Stage 1 | Stage 2 | Default |
| A+B | Lux | Lux | Required — shared physical run |
| A | AnyJev L0 | Lux | Required |
| A | Kai / Laya | Lux | Required |
| A | Qwen3-8B JSON | Lux | Required baseline |
| B | Lux | CLM / BM25 / E5 | Required |
| B | Lux / noop | shortlist-CLM / AR | Optional ( |
| champion | AnyJev L0 | E5 / BM25 | Opt-in P1 (S8) |
| B optional | Lux | BM25→Lux Score (k=32) | Opt-in P1 (S2b) |
| B baseline | Lux | E5→CrossEncoder (k=32) | Opt-in P1 (S7; #2) |
Deferred trained CLM heads: issue #1.
P1 Stage-2 ceilings (champions, shortlist→Lux, E5→CE): feature 005-s2-approach-ceilings; measured in paper-p1-ceilings-n200 (see below).
Out of the default matrix
Model | Why interesting | Why not default |
Jev (TypeSafe) | Defines the System-1 bar | Hosted / proprietary |
djev / DiffusionGemma | Multimodal | VRAM + not text-SEC chunks |
Other Decision-2.0 sizes / Jeeves / SemIf / … | Family completeness | Overlap or memory vs sequential budget |
CLM as Stage 1 / Laya·Kai as Stage 2 | — | Wrong primitive or context/cost fit |
Results: paper-n200-full (N=200, seed=42)
Merged primary + retry matrix: 8/8 required pairs measured, ranking-only. Published analysis under artifacts/benchmarks/ includes P0 evidence (routing audit, dual S2, strata, win/loss, bootstrap CIs, multi-seed rollup).
For a non-metrics walkthrough of what these numbers mean for agent design (routing vs yield vs passage search vs generation), see Decision Models for Enterprise Agentic Architecture.md.
Headline findings
Question | Winner | Key numbers |
Best Choice router (Block A) |
| S1 nDCG@5 0.8625 (+0.021 vs Lux 0.8413); Top-1 recall 95.1%; OFR 9.0% |
Best passage scorer (Block B) |
| S2 nDCG@5 0.2825 scored-only (+0.061 vs Lux); pipeline-averaged 0.157 |
Routing / yield | Lux Choice | Empty-Top-1 40.5%; pipeline yield 59.5%. Many empties are correct Top-1 + empty pool (67/200), not only wrong type — see Routing accounting in the analysis. |
Block A order (S1 nDCG@5): AnyJev 0.862 → Lux 0.841 → Kai 0.783 → AR 0.777 → Laya 0.751.
Block B order (scored-only S2 nDCG@5): E5 0.282 → BM25 0.265 → Lux Score 0.221 → CLM 0.103. Win/tie/loss vs Lux (nDCG@5, ε=0.01): E5 51/26/34; BM25 51/23/37.
Multi-seed core (seeds 42 / 7 / 123, four pairs): AnyJev beats Lux S1 on all three seeds. Across-seed mean S2: E5 ≈ 0.265, BM25 ≈ 0.246, Lux ≈ 0.209 — Block B order is not seed-stable (BM25 ≈ E5 on seed 7; BM25 collapses on seed 123). Cite mean + min–max from the Multi-seed summary in the analysis.
Optional baselines (paper-n200-optional, same N/seed; local artifacts): BM25→CLM shortlist S2 0.1475 (beats zero-shot CLM 0.103, still behind Lux/E5/BM25); one-shot AR S2 0.2737 (~E5) as a collapsed baseline (~3% AR parse fail).
Synthesis reuse (paper-n200-full-synth): Gemini attached to saved rankings for anyjev / lux / e5 / bm25 (no Choice/Score re-run). Attempted 119–128 / pair, 0 Gemini fails. Answer EM/F1 are N/A — the harness dump has answer_label: null on all examples (skipped_no_label).
Rebuild analysis (no engines):uv run python scripts/run_benchmark.py --analysis-from paper-n200-full --multi-seed-from paper-n200-s7-core,paper-n200-s123-core
Detailed artifacts
Artifact | Path |
Analysis (read this first) | |
Analysis JSON | |
Matrix tables | |
Matrix state | |
Compact inspect (GitHub) |
|
Full inspect HTML (download) |
|
Optional / synth analyses (local) |
|
P0 evidence commands (re-run / extend)
# Rebuild published analysis + multi-seed rollup (no GPU)
uv run python scripts/run_benchmark.py --analysis-from paper-n200-full \
--multi-seed-from paper-n200-s7-core,paper-n200-s123-core
# Optional baselines (ranking-only)
uv run python scripts/run_benchmark.py --real --include-optional \
--pairs lux-clm-shortlist,one-shot-ar \
--records 200 --seed 42 --run-id paper-n200-optional
# Synthesis reuse (Gemini only; needs GOOGLE_API_KEY)
uv run python scripts/run_benchmark.py --real --with-synthesis \
--synthesis-from-rankings paper-n200-full \
--pairs anyjev-l0-lux,lux-lux,lux-e5,lux-bm25 \
--run-id paper-n200-full-synthSpec: specs/004-paper-p0-evidence/. Trained CLM-ft remains deferred #1.
Results: paper-p1-ceilings-n200 (N=200, seed=42)
P1 Stage-2 approach ceilings on the same example IDs as paper-n200-full (ranking-only). Matrix state merges the four P1 pairs with published baselines so Champion / P1 Δ columns and bootstrap CIs are filled. Spec: 005-s2-approach-ceilings.
Headline findings
Question | Winner | Key numbers |
Best Stage-2 scorer (incl. P1) |
| S2 nDCG@5 0.3517 scored (+0.131 vs lux-lux; bootstrap 95% CI excludes 0); S2|Top-1 0.3735 |
Champion compound (S8) |
| S2 0.2868 (+0.057 vs anyjev-l0-lux; +0.004 vs lux-e5). |
Pretrained CE “ceiling” (S7) | does not beat E5 |
|
Takeaway: BM25 shortlist → Lux Score is the Stage-2 win on this sample. Best Choice × classical IR helps vs Lux Score alone, but barely moves the needle vs Lux Choice × the same IR head. Off-the-shelf CrossEncoder is a useful baseline, not an IR ceiling here.
Rebuild (no engines; baselines already merged into matrix state):
uv run python scripts/run_benchmark.py --analysis-from paper-p1-ceilings-n200 \
--multi-seed-from paper-n200-s7-core,paper-n200-s123-coreArtifact | Path |
Analysis | |
Analysis JSON | |
Matrix tables |
|
Matrix state | |
Compact inspect (GitHub) |
|
Full inspect HTML (download) |
|
Full re-run:
uv run python scripts/run_benchmark.py --real --skip-synthesis \
--pairs anyjev-l0-e5,anyjev-l0-bm25,lux-lux-shortlist,lux-e5-ce \
--records 200 --seed 42 --run-id paper-p1-ceilings-n200Technical stack
Layer | Technology | Role |
Orchestration | LangGraph (+ LangChain Core) | Per-example agent graph |
System-1 | Local | Choice / Score / Action Cache / BM25 / E5 / AR |
System-2 | Gemini Flash via | Fail-closed synthesis (no extractive fallback) |
Tools | MCP ( | Optional enrichment |
Observability | MLflow 3 nested Runs + GenAI Traces | Metrics + span tree |
Eval ledger | SQLite | Crash-resume, leases, ranking vs synthesis phases |
Packaging | uv + Python 3.12, Typer, Pydantic, httpx |
|
Optional --extra real: torch, transformers, sentence-transformers, rank-bm25, huggingface-hub.
Agent flow
flowchart TD
Q[Query + SEC chunks] --> S1
S1["stage1 · Choice<br/>rank filing types"] --> S2
S2["stage2 · Score / Action Cache<br/>rank passages in Top-1 type"] --> M
M["metrics · nDCG@5 MAP@5 MRR@5"] --> R{skip_synthesis?}
R -->|yes · ranking-only| END1[End · ranking_complete]
R -->|no| G["synthesize · Gemini Flash<br/>top-K chunks"]
G --> A["answer_score · EM + token F1"]
A --> END2[End · completed]MLflow
Tracking defaults to SQLite (MLFLOW_TRACKING_URI=sqlite:///mlflow.db):
./scripts/mlflow_ui.sh
# http://127.0.0.1:5000 → experiment finagent-mesh → Runs | TracesSurface | Contents |
Runs (nested per example) |
|
Traces |
|
Set MLFLOW_DISABLE_AUTOLOG=1 to disable LangGraph autolog. Migrate old FileStore: uv run mlflow migrate-filestore --source ./mlruns --target sqlite:///mlflow.db.
Quick start: smoke test
Use a new --run-id every smoke so the SQLite ledger does not resume an old run.
0. One-time setup
cp .env.example .env
# Required for --real:
# SYSTEMONE_MOCK=0
# SYSTEMONE_BACKEND=real
# HF_TOKEN=… # Hub rate limits
# GOOGLE_API_KEY=… # only if --with-synthesis
# KAGGLE_USERNAME / KAGGLE_KEY # first FinAgentBench download only
# MLFLOW_TRACKING_URI=sqlite:///mlflow.db
uv sync --extra real --group dev
./scripts/prepare_real_stack.sh
# Optional weight prefetch:
./scripts/prepare_real_stack.sh --prefetchCreate a Hugging Face read token at HF settings/tokens. For Gemini, set GOOGLE_API_KEY. Accept Kaggle competition rules if data is not already under data/finagentbench/.
1. MLflow UI (separate terminal)
./scripts/mlflow_ui.sh2. Minimal technical smoke (S1 + S2 + Gemini + MLflow)
uv run python scripts/run_benchmark.py --real --with-synthesis \
--pairs lux-lux \
--records 5 --seed 42 \
--run-id paper-smoke-mlflow-gemini-5Pass criteria: CLI exit 0; ranking in inspect HTML; non-empty Gemini synthesis; nested MLflow Runs + Trace with systemone_* and gemini_synthesize.
Ranking-only smoke:
uv run python scripts/run_benchmark.py --real \
--pairs lux-lux --records 5 --seed 42 \
--run-id paper-smoke-rank-5Full paper run
uv run python scripts/run_benchmark.py --real --seed 42 --run-id paper-n200With Gemini synthesis on the same sample:
uv run python scripts/run_benchmark.py --real --with-synthesis \
--seed 42 --run-id paper-n200-synthWhat --real does
Resolves required Block A/B pairs from
configs/engines.yaml.Starts engines with
SYSTEMONE_BACKEND=real(refusesSYSTEMONE_MOCK=1).Force-restarts sidecars on ports 8000/8001/8002 unless
--keep-servers.Keeps Lux Score warm on :8001 across Block A while Choice swaps on :8000.
Auto-fetches FinAgentBench from Kaggle if missing (
--no-fetch-datato disable).Writes
artifacts/benchmarks/<run-id>.{json,csv,md,analysis.md,analysis.json,inspect.html,inspect.json}.
GPU policy: sequential exclusive heavies; keep Lux warm across Block A (shared Score) and Block B (shared Choice). Rebuild reports without engines: --analysis-from <run-id> / --inspect-from <run-id>.
Selective runs
uv run python scripts/run_benchmark.py --list-pairs
uv run python scripts/run_benchmark.py --list-engines
# Highest-value subset
uv run python scripts/run_benchmark.py --real \
--pairs lux-lux,lux-bm25,kai-lux \
--records 20 --seed 42 --run-id paper-core
# Optional Block B rows
uv run python scripts/run_benchmark.py --real --include-optional --run-id paper-opt
# Reuse warm sidecars
uv run python scripts/run_benchmark.py --real --keep-servers \
--pairs lux-lux --records 5 --seed 42 --run-id warm-reuse
# External server management
uv run python scripts/run_benchmark.py --real --no-manage-servers \
--pairs lux-lux --records 5 --run-id external-servers
# Rebuild published analysis/inspect from saved matrix state
uv run python scripts/run_benchmark.py --analysis-from paper-n200-full
uv run python scripts/run_benchmark.py --inspect-from paper-n200-fullStop leftovers: bash scripts/serve_engine.sh stop-all.
run_benchmark.py CLI reference
Flag | Default | Meaning |
| off | Real HF models, refuse mock, ranking-only unless |
|
| Seeded sample size |
|
| RNG seed |
|
| Matrix run id (ledger + artifact stem) |
| all required Block A/B | Comma-separated |
| — | Legacy ablation; mutually exclusive with |
| off | Add |
| off | Gemini Flash + answer scoring |
| implied by | Explicit ranking-only |
|
| System-2 model id |
|
| Dataset directory or JSONL |
|
| Report output directory |
|
| With |
| fetch on | Kaggle download if missing |
| on with | Kill ports 8000–8002 before the run |
| off | Reuse running sidecars |
| off | Do not start/stop engines |
| off | Debug only; illegal with |
| — | Catalog and exit |
| — | Rebuild reports from a saved matrix; no engines |
Layout
scripts/run_benchmark.py— paper Block A/B matrix + reports (--real)scripts/mlflow_ui.sh— MLflow UI (sqlite:///mlflow.db)configs/engines.yaml— engines, HF ids,matrix_pairsscripts/download_finagentbench_kaggle.py— fetch + convert ICAIF’25 dumpscripts/prepare_real_stack.sh— torch/transformers; optional HF prefetchscripts/serve_engine.sh— start/stop/restart/health/stop-allsrc/finagent_mesh/agent/graph.py— LangGraph pipelinesrc/finagent_mesh/runtime/harness.py/tracing.py— ledger + MLflowsrc/finagent_mesh/matrix/— report, analysis, inspect, mergesrc/finagent_mesh/clients/engines/real_infer.py— Decision-2.0 / embed / AR / CLMartifacts/benchmarks/paper-n200-full.*— published N=200 analysis; compact.inspect.md+ per-pair pages for GitHub; full.inspect.htmlfor downloadartifacts/benchmarks/paper-p1-ceilings-n200.*— same pattern for P1 ceilingsArchitecture (short):
Decision Models for Enterprise Agentic Architecture.mdSurvey (long):
Architectural Foundations for Open Decision Models.mdSpecs:
specs/003-choice-score-paper/·specs/005-s2-approach-ceilings/·specs/004-paper-p0-evidence/·specs/002-decision-model-bench/·specs/001-finagentbench-harness/
This server cannot be deployed
Maintenance
Related MCP Connectors
Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.
SEC & financial-data MCP: filings, financials, ownership, factors, fund letters, prompts.
Certified SEC EDGAR fact memory for AI agents with zero hallucination and filing provenance.
Primary-source SEC filing intelligence and financial/disclosure reconciliation for AI agents.
Related MCP Servers
- AlicenseAqualityAmaintenanceProvides 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.21177 npm1MIT
- AlicenseNot gradedqualityCmaintenanceHosted MCP server granting AI agents access to 20M+ SEC EDGAR filings, 100M+ exhibits, and comprehensive entity data through 49 tools, with support for raw documents, extracted sections, and structured JSON.6 npm1MIT
- AlicenseBqualityCmaintenanceEnables multi-agent financial research through MCP, combining live or offline market, news, fundamentals, document RAG, and risk tools with critic review, synthesis, and execution tracing.10MIT
- AlicenseNot gradedqualityBmaintenanceEnables natural language queries over financial reports, with multimodal retrieval across text, tables, and charts via an agentic RAG system.MIT