MCP server · Audited from source

Finance Toolkit MCP server

by jerbouma/financetoolkitMIT licenceAudited 21 Sep 2026 · source ffd971075709

PyPI financetoolkit 2.1.5stdiostreamable-http★ 5,361
✕BLOCKGrade F · 55/100 · 21 Sep 2026 · ffd9710

Is it safe? No — BLOCK, grade F (55/100). The tool list is built at runtime, so we cannot read it from the source. The audit recorded 30 findings (0 critical, 4 high, 7 medium, 14 low). Maintainer's description: Transparent and Efficient Financial Analysis

Ask an AI about this pageGChatGPTCClaudePPerplexityGeGeminiXGrok
More
Cite

Cite this page

ModelsAtlas. “Finance Toolkit MCP server (jerbouma/financetoolkit)”. Retrieved 21 Sep 2026. https://modelsatlas.com/mcp/jerbouma/finance-toolkit

Why this is BLOCK. The audit found 0 critical and 4 high findings; the most severe is Code injection at financetoolkit/cache/serialization_model.py:50. Each finding is listed below with its file and line.

Why this page is still public. People search for this server by name. Hiding it would leave them with the README's word alone; here they see what the code does. We list it so you can decide, and we do not show connect commands for BLOCK servers.

Trust audit

Audit 0.4.1 · full source read 21 Sep 2026

Trust score55/100✕BLOCK F
0 critical4 high7 medium14 low5 info

30 findings, listed below with the file and line each was found on. Grade A needs a sandboxed behavioural run too; this audit read the source only.

What the source does

  • FilesystemDeclared1 observation
  • NetworkDeclared4 observations
  • ShellDeclared4 observations
  • DependenciesPinnedNothing floats
  • SecretsFoundSee the findings

Findings (30)

Sorted by severity · the 25 most severe of 30 are listed

HIGHCode injectioncode.deserialize · financetoolkit/cache/serialization_model.py:50
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
return pickle.loads(zlib.decompress(payload))  # noqa: S301
Why
deserialises untrusted bytes into live objects
Fix
use json or yaml.safe_load
HIGHCode injectioncode.deserialize · financetoolkit/cache/serialization_model.py:78
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
return pickle.loads(zlib.decompress(payload))  # noqa: S301
Why
deserialises untrusted bytes into live objects
Fix
use json or yaml.safe_load
HIGHCode injectioncode.eval_exec · financetoolkit/ratios/ratios_controller.py:495
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
calculation = eval(formula_adjusted)  # noqa
Why
evaluates text as code
Fix
remove; use a parser or a dispatch table
HIGHNetwork egressnet.tls_off · financetoolkit/utilities/requests_model.py:59
F-04 Network egressCWE-200 · CWE-319Layer L1
url, headers=headers, timeout=timeout, verify=False  # noqa
Why
certificate verification is disabled
Fix
leave verification on
MEDIUMInventory / provenanceinv.binary · financetoolkit/portfolio/example_datasets/example_portfolio.xlsx
F-13 Inventory / provenanceCWE-1104Layer L0
example_portfolio.xlsx
Why
a compiled or binary member cannot be reviewed from source
Fix
ship source, or explain the binary in the README
MEDIUMCode injectioncode.dynamic_import · financetoolkit/mcp_server/registry_controller.py:386
F-02 Code injectionCWE-78 · CWE-94 · CWE-95Layer L1
module = importlib.import_module(module_path)
Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · README.md:118
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · financetoolkit/discovery/discovery_controller.py:56
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · financetoolkit/discovery/discovery_controller.py:124
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · financetoolkit/discovery/discovery_controller.py:229
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
MEDIUMHard-coded secretssecret.generic · financetoolkit/discovery/discovery_controller.py:292
F-03 Hard-coded secretsCWE-798 · CWE-321Layer L1

Excerpt withheld: it is a secret, and we never print one.

Why
No further detail recorded for this rule.
Fix
—
LOWInventory / provenanceinv.binary · tests/datasets/balance_dataset.pickle
F-13 Inventory / provenanceCWE-1104Layer L0
balance_dataset.pickle
Why
a compiled or binary member cannot be reviewed from source
Fix
ship source, or explain the binary in the README
LOWInventory / provenanceinv.binary · tests/datasets/cash_dataset.pickle
F-13 Inventory / provenanceCWE-1104Layer L0
cash_dataset.pickle
Why
a compiled or binary member cannot be reviewed from source
Fix
ship source, or explain the binary in the README
LOWInventory / provenanceinv.binary · tests/datasets/historical_dataset.pickle
F-13 Inventory / provenanceCWE-1104Layer L0
historical_dataset.pickle
Why
a compiled or binary member cannot be reviewed from source
Fix
ship source, or explain the binary in the README
LOWInventory / provenanceinv.binary · tests/datasets/income_dataset.pickle
F-13 Inventory / provenanceCWE-1104Layer L0
income_dataset.pickle
Why
a compiled or binary member cannot be reviewed from source
Fix
ship source, or explain the binary in the README
LOWInventory / provenanceinv.hidden_file · .pre-commit-config.yaml
F-13 Inventory / provenanceCWE-1104Layer L0
.pre-commit-config.yaml
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWInventory / provenanceinv.hidden_file · financetoolkit/mcp_server/mcpb/.mcpbignore
F-13 Inventory / provenanceCWE-1104Layer L0
.mcpbignore
Why
hidden member outside the usual dotfiles
Fix
review its purpose
LOWFilesystem / pathfs.traversal · financetoolkit/mcp_server/mcpb/build-mcpb.sh:18
F-05 Filesystem / pathCWE-22 · CWE-59Layer L1
REPO_ROOT="$(cd "$SCRIPT_DIR/../../.." && pwd)"
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · tests/mcp_server/test_mcp_oauth.py:104
F-04 Network egressCWE-200 · CWE-319Layer L1
client = TestClient(app, base_url="http://127.0.0.1:8000")
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · tests/mcp_server/test_mcp_oauth.py:236
F-04 Network egressCWE-200 · CWE-319Layer L1
client = TestClient(app, base_url="http://127.0.0.1:8000")
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · tests/mcp_server/test_mcp_oauth.py:291
F-04 Network egressCWE-200 · CWE-319Layer L1
client = TestClient(app, base_url="http://127.0.0.1:8000")
Why
No further detail recorded for this rule.
Fix
—
LOWNetwork egressnet.raw_ip · tests/mcp_server/test_mcp_oauth.py:334
F-04 Network egressCWE-200 · CWE-319Layer L1
client = TestClient(app, base_url="http://127.0.0.1:8000")
Why
No further detail recorded for this rule.
Fix
—
LOWObfuscation / stealthobf.base64_blob · README.md:9
F-07 Obfuscation / stealthCWE-506 · CWE-94Layer L1
[![Smithery](https://img.shields.io/badge/Smithery-grey?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTM1IiBoZWlnaHQ9IjE1OSIgdmlld0JveD0iMCAwIDEzNSAxNTkiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczL
Why
No further detail recorded for this rule.
Fix
—
LOWObfuscation / stealthobf.base64_blob · README.md:10
F-07 Obfuscation / stealthCWE-506 · CWE-94Layer L1
[![Glama](https://img.shields.io/badge/Glama-grey?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzMwIiBoZWlnaHQ9IjMzMCIgdmlld0JveD0iMCAwIDMzMCAzMzAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8
Why
No further detail recorded for this rule.
Fix
—
LOWInventory / provenancemcp.no_tools_extracted · server.json
F-13 Inventory / provenanceCWE-1104Layer L3
Why
the tool list is enumerated at runtime by tools/list, not declared in source
Fix
the page says so rather than showing an empty table

Tools it exposes

None declared in source

The tool list is built at runtime, so we cannot read it from the source.

Audit history

  1. ✕BLOCK F 55 / 100

    Source changed, verdict held · ffd971075709

README badge

Badges show the current verdict, BLOCK included

ModelsAtlas: BLOCK FMODELSATLASBLOCK · F

A badge cannot be hidden by the maintainer while the verdict is BLOCK. Fix the findings, push, and the re-audit updates it.

Questions about Finance Toolkit MCP server

What is the Finance Toolkit MCP server?
Transparent and Efficient Financial Analysis
Is Finance Toolkit safe to connect to an agent?
No — not without reading the findings first. The audit graded it F (55/100) and found 4 critical or high issues in the source. Each one is listed on this page with the file and line it is on.
What credentials does Finance Toolkit need?
It reads FINANCIAL_MODELING_PREP_API_KEY, FRED_API_KEY and FT_MCP_SECRET_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does Finance Toolkit run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on PyPI as financetoolkit.
How current is this page?
The grade is for one exact copy of the source (ffd971075709), read on 2026-09-21. The repository is watched and re-audited when it changes.
I already installed Finance Toolkit. What should I do?
Remove it from your client's MCP configuration, then rotate any API keys and tokens that were in your environment while it ran.
Can the verdict change?
Yes. The repository is watched and re-audited when its source changes. If the findings are removed the verdict updates, and the history on this page shows it.

Sources

  • jerbouma/financetoolkit on GitHub — the source we read, its licence, stars and activityObserved · 21 Sep 2026
  • ModelsAtlas trust audit — BLOCK verdict for commit ffd971075709Observed · 21 Sep 2026

Spotted something wrong? Report a correction · Methodology

Keep going in your AI

Opens with this page as the source. We add nothing else to the prompt.