# Toolstem Financial Data MCP — Curated Signals for AI Agents (`toolstem/toolstem-mcp-server`) Actor

Stock prices, company fundamentals, DCF valuation & peer comparison for AI agents. Agent-ready JSON. Claude & GPT.

- **URL**: https://apify.com/toolstem/toolstem-mcp-server.md
- **Developed by:** [Toolstem](https://apify.com/toolstem) (community)
- **Categories:** AI, MCP servers, Developer tools
- **Features:** Limited permissions
- **Stats:** 3 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 tool calls

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## 📊 Toolstem — Financial Data MCP for AI Agents | Stock Analysis & DCF

[![npm version](https://img.shields.io/npm/v/toolstem-mcp-server)](https://www.npmjs.com/package/toolstem-mcp-server)
[![npm downloads](https://img.shields.io/npm/dw/toolstem-mcp-server)](https://www.npmjs.com/package/toolstem-mcp-server)
[![MCP Registry](https://img.shields.io/badge/MCP_Registry-active-teal)](https://registry.modelcontextprotocol.io)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](./LICENSE)

**Curated financial data MCP for AI agents — equity research in one call.**

Toolstem is the **financial data MCP** built for AI stock analysis, equity research, and agent-driven investment workflows. Real-time stock data, company fundamentals, DCF valuations, financial metrics, and the ability to compare companies side-by-side — all returned as flat, agent-friendly JSON with derived signals already computed.

Works natively with **Claude**, **OpenAI Agents SDK**, and **LangChain**. Pay-per-call pricing, no subscription. More finance MCP servers (SEC filings, insider transactions, institutional holdings) are on the way.

Unlike passthrough wrappers that just expose a vendor's REST API, every Toolstem tool **combines multiple data sources**, **derives signals**, and **pre-computes the math** an agent would otherwise have to do itself.

One call. One agent-friendly JSON response. No nested arrays to parse, no cross-endpoint stitching, no null-checking boilerplate.

***

### Quickstart — hosted endpoint (recommended)

Point your MCP client or agent at the hosted endpoint. **No API key, no infra, no setup.** Billing is per-call via [x402](https://www.x402.org) — the agent's wallet pays directly in USDC on Base mainnet.

```
https://mcp.toolstem.com/mcp/finance
```

- **No FMP API key required** — you do not bring or manage any upstream data key.
- **No infrastructure** — nothing to install, host, or keep running.
- **No setup** — connect an MCP client and call a tool.
- `initialize` and `tools/list` are **free** (discovery and schema introspection).
- Each `tools/call` costs **$0.01 USDC** on Base mainnet, settled via x402.

#### Claude Desktop

Drop this into your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "toolstem-finance": {
      "url": "https://mcp.toolstem.com/mcp/finance"
    }
  }
}
```

Restart Claude Desktop, then ask: *"Use Toolstem to get a snapshot of NVDA."*

#### Any MCP client (LangChain.js)

The official [`@langchain/mcp-adapters`](https://www.npmjs.com/package/@langchain/mcp-adapters) library connects directly to the hosted URL:

```ts
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

const client = new MultiServerMCPClient({
  toolstem_finance: {
    transport: "http",
    url: "https://mcp.toolstem.com/mcp/finance",
    // Add your x402-signing middleware via headers, OR run an x402
    // proxy locally and point url at it. See https://www.x402.org/clients.
  },
});

const tools = await client.getTools();
const agent = createReactAgent({ llm: new ChatOpenAI({ model: "gpt-4o-mini" }), tools });
await agent.invoke({ messages: "Compare AAPL, MSFT, and GOOGL on valuation and growth." });
```

#### LangChain quick-start (`langchain-toolstem`)

The [`langchain-toolstem`](https://www.npmjs.com/package/langchain-toolstem) wrapper handles x402 payment for you — pass a funded wallet key and the tools auto-pay per call:

```typescript
import { createToolstemTools } from 'langchain-toolstem';
const tools = await createToolstemTools({ walletPrivateKey: process.env.WALLET_KEY });
// Tools auto-pay $0.01 USDC per call via x402
```

Prefer to run the server yourself with your own FMP key? See [Advanced: self-host](#advanced-self-host) at the bottom.

Try the tools live in the [Toolstem playground](https://www.toolstem.com/playground/).

Product page: <https://toolstem.com/finance/>.

***

### Pricing

- **MCP `initialize` and `tools/list` are free** — discovery, schema introspection, and health checks never cost anything.
- **`tools/call` costs $0.01 USDC on Base mainnet per invocation, paid via [x402](https://www.x402.org).** No API key, no signup, no marketplace account required — the agent's wallet pays directly.

| Tool | Per call |
|------|----------|
| `get_stock_snapshot` | $0.01 USDC |
| `get_company_metrics` | $0.01 USDC |
| `compare_companies` | $0.01 USDC |

#### How billing works

Toolstem uses the x402 payment protocol. Agents pay per call in USDC on Base — no API keys, no subscriptions, no invoices. The agent's wallet settles each call automatically via EIP-3009.

***

### How it works

Toolstem ships as a Node MCP server (this repo) **and** as a hosted, x402-gated proxy.

```
Agent ──MCP──▶ Cloudflare Worker (x402 paywall) ──MCP──▶ Toolstem MCP server ──REST──▶ Financial Modeling Prep
                  │                                          │
                  └─ free: initialize, tools/list            └─ composite tool: fans out to 3–5 FMP endpoints
                  └─ paid: tools/call → 0.01 USDC on Base       in parallel, derives signals, returns flat JSON
```

- **Cloudflare Worker** terminates the public MCP connection at `mcp.toolstem.com` and enforces the x402 payment for `tools/call`.
- **MCP server** (this package) implements the 3 composite tools and talks to Financial Modeling Prep.
- **x402 on Base mainnet** handles the micropayment — settlement is sub-second, no off-chain accounts.

***

### Tools

Three composite tools, each one synthesizing multiple FMP endpoints with derived signals and pre-computed math.

| Tool | Title | Required input | Optional input |
|---|---|---|---|
| [`get_stock_snapshot`](#get_stock_snapshot) | Stock Snapshot | `symbol` (string) | — |
| [`get_company_metrics`](#get_company_metrics) | Company Metrics | `symbol` (string) | `period` (`annual` | `quarter`, default `annual`) |
| [`compare_companies`](#compare_companies) | Company Comparison | `symbols` (string\[2..5]) | — |

All three are read-only, idempotent, and safe for agent retry.

#### `get_stock_snapshot`

Comprehensive stock overview combining quote, profile, DCF valuation, and rating into a single response.

**Input:**

```json
{
  "symbol": "AAPL"
}
```

**Example output (truncated):**

```json
{
  "symbol": "AAPL",
  "company_name": "Apple Inc.",
  "sector": "Technology",
  "industry": "Consumer Electronics",
  "exchange": "NASDAQ",
  "price": {
    "current": 178.52,
    "change": 2.34,
    "change_percent": 1.33,
    "day_high": 179.80,
    "day_low": 175.10,
    "year_high": 199.62,
    "year_low": 130.20,
    "distance_from_52w_high_percent": -10.57,
    "distance_from_52w_low_percent": 37.11
  },
  "valuation": {
    "market_cap": 2780000000000,
    "market_cap_readable": "$2.78T",
    "pe_ratio": 29.5,
    "dcf_value": 195.20,
    "dcf_upside_percent": 9.35,
    "dcf_signal": "FAIRLY VALUED"
  },
  "rating": {
    "score": 4,
    "recommendation": "Buy",
    "dcf_score": 5,
    "roe_score": 4,
    "roa_score": 4,
    "de_score": 5,
    "pe_score": 3
  },
  "fundamentals_summary": {
    "beta": 1.28,
    "avg_volume": 55000000,
    "employees": 164000,
    "ipo_date": "1980-12-12",
    "description": "Apple Inc. designs, manufactures..."
  },
  "meta": {
    "source": "Toolstem via Financial Modeling Prep",
    "timestamp": "2026-04-17T18:30:00Z",
    "data_delay": "End of day"
  }
}
```

**Derived fields (not in raw APIs):**

- `dcf_signal` — `UNDERVALUED` if DCF upside > 10%, `OVERVALUED` if < -10%, else `FAIRLY VALUED`.
- `market_cap_readable` — human-friendly `$2.78T`, `$450.2B`, `$12.5M` format.
- `distance_from_52w_high_percent` / `distance_from_52w_low_percent` — pre-computed range position.

***

#### `get_company_metrics`

Deep fundamentals analysis — profitability, financial health, cash flow, growth, and per-share metrics — synthesized from 5 financial statements endpoints.

**Input:**

```json
{
  "symbol": "AAPL",
  "period": "annual"
}
```

`period` accepts `annual` (default) or `quarter`.

**Example output (truncated):**

```json
{
  "symbol": "AAPL",
  "period": "annual",
  "latest_period_date": "2025-09-30",
  "profitability": {
    "revenue": 394328000000,
    "revenue_readable": "$394.3B",
    "revenue_growth_yoy": 7.8,
    "net_income": 96995000000,
    "net_income_readable": "$97.0B",
    "gross_margin": 46.2,
    "operating_margin": 31.5,
    "net_margin": 24.6,
    "roe": 160.5,
    "roa": 28.3,
    "roic": 56.2,
    "margin_trend": "EXPANDING"
  },
  "financial_health": {
    "total_debt": 111000000000,
    "total_cash": 65000000000,
    "net_debt": 46000000000,
    "debt_to_equity": 1.87,
    "current_ratio": 1.07,
    "interest_coverage": 41.2,
    "health_signal": "STRONG"
  },
  "cash_flow": {
    "operating_cash_flow": 118000000000,
    "free_cash_flow": 104000000000,
    "free_cash_flow_readable": "$104.0B",
    "fcf_margin": 26.4,
    "capex": 14000000000,
    "dividends_paid": 15000000000,
    "buybacks": 89000000000,
    "fcf_yield": 3.7
  },
  "growth_3yr": {
    "revenue_cagr": 8.2,
    "net_income_cagr": 10.1,
    "fcf_cagr": 9.5,
    "growth_signal": "ACCELERATING"
  },
  "per_share": {
    "eps": 6.42,
    "book_value_per_share": 3.99,
    "fcf_per_share": 6.89,
    "dividend_per_share": 0.96,
    "payout_ratio": 14.9
  },
  "meta": {
    "source": "Toolstem via Financial Modeling Prep",
    "timestamp": "2026-04-17T18:30:00Z",
    "periods_analyzed": 3,
    "data_delay": "End of day"
  }
}
```

**Derived fields:**

- `margin_trend` — `EXPANDING`, `STABLE`, or `CONTRACTING` based on net margin series direction.
- `health_signal` — `STRONG`, `ADEQUATE`, or `WEAK` from debt-to-equity, current ratio, and interest coverage.
- `growth_signal` — `ACCELERATING`, `STEADY`, or `DECELERATING` based on YoY growth trajectory.
- `revenue_cagr`, `net_income_cagr`, `fcf_cagr` — compound annual growth rates over the analyzed window.
- `fcf_margin`, `fcf_yield` — pre-computed from cash flow + revenue + market cap.

***

#### `compare_companies`

Side-by-side comparison of 2–5 companies across price, valuation, profitability, financial health, growth, dividends, and analyst ratings.

**Input:**

```json
{
  "symbols": ["AAPL", "MSFT", "GOOGL"]
}
```

`symbols` must be an array of 2 to 5 ticker strings.

**Example output (truncated):**

```json
{
  "symbols_compared": ["AAPL", "MSFT", "GOOGL"],
  "comparison_date": "2026-04-20T18:30:00Z",
  "companies": [
    {
      "symbol": "AAPL",
      "company_name": "Apple Inc.",
      "sector": "Technology",
      "price": { "current": 178.52, "change_percent": 1.33 },
      "valuation": { "pe_ratio": 29.5, "dcf_upside_percent": 9.35 },
      "profitability": { "net_margin": 24.6, "roe": 160.5, "roic": 56.2 },
      "financial_health": { "debt_to_equity": 1.87, "current_ratio": 1.07 },
      "growth": { "revenue_growth_yoy": 7.8, "earnings_growth_yoy": 10.1 },
      "dividend": { "dividend_yield": 0.5, "payout_ratio": 14.9 },
      "rating": { "score": 4, "recommendation": "Buy" }
    }
  ],
  "rankings": {
    "lowest_pe": "GOOGL",
    "highest_margin": "AAPL",
    "strongest_balance_sheet": "GOOGL",
    "best_growth": "MSFT",
    "most_undervalued": "GOOGL",
    "highest_rated": "MSFT"
  },
  "meta": {
    "source": "Toolstem via Financial Modeling Prep",
    "timestamp": "2026-04-20T18:30:00Z",
    "data_delay": "Real-time during market hours",
    "api_calls_made": 19
  }
}
```

**Derived fields:**

- `rankings` — automatically computed: `lowest_pe`, `highest_margin`, `strongest_balance_sheet`, `best_growth`, `most_undervalued`, `highest_rated`.
- All valuation, profitability, health, and growth metrics pre-computed per company.
- Uses batch quote for efficient multi-symbol price retrieval.

***

### Why Toolstem?

Most financial MCP servers expose one tool per API endpoint — forcing your agent to make 4–5 sequential calls, write glue code, and reason about raw data shapes. Toolstem is built differently:

- **Parallel data fetching** — every tool fans out to multiple sources concurrently.
- **Derived signals** — human-readable recommendations like `UNDERVALUED`, `STRONG`, `ACCELERATING` computed from raw numbers.
- **Pre-computed math** — CAGRs, YoY growth, margin trends, distance from 52-week high/low, FCF yield, and more are already in the response.
- **Flat, predictable schema** — no deeply nested vendor quirks leaking into agent prompts.
- **Graceful degradation** — if one upstream endpoint fails, the rest of the response still comes through with nulls in place.

***

### Advanced: self-host

> **Most users should use the [hosted endpoint](#quickstart--hosted-endpoint-recommended) above** — it needs no API key, no infrastructure, and no setup. This section is for users who specifically want to run the server themselves.

Run the Node MCP server locally with your own FMP key — no x402, no per-call charge beyond your FMP quota. You are responsible for obtaining and managing your own `FMP_API_KEY` and for any infrastructure you run.

#### npm

```bash
npm install -g toolstem-mcp-server
```

**stdio** (default — for Claude Desktop, Cursor, etc.):

```bash
FMP_API_KEY=your_key_here toolstem-mcp-server
```

**HTTP — local only** (default, binds 127.0.0.1):

```bash
FMP_API_KEY=your_key_here toolstem-mcp-server --http
```

**HTTP — remote + auth** (binds 0.0.0.0, requires bearer token):

```bash
FMP_API_KEY=your_key ALLOW_REMOTE=1 MCP_AUTH_TOKEN=my-secret toolstem-mcp-server --http
```

Clients must send `Authorization: Bearer my-secret` on every `/mcp` request.

**HTTP — auth disabled (local only)**:

```bash
FMP_API_KEY=your_key MCP_AUTH_DISABLED=1 toolstem-mcp-server --http
```

> `MCP_AUTH_DISABLED=1` forces the server to bind `127.0.0.1` regardless of `ALLOW_REMOTE`. This is a safe "skip auth, local only" mode for development.

**HTTP — remote without auth (dangerous)**:

```bash
FMP_API_KEY=your_key ALLOW_REMOTE=1 MCP_AUTH_DISABLED=1 I_KNOW_THIS_IS_DANGEROUS=1 toolstem-mcp-server --http
```

> **Warning:** This exposes your FMP API key to anyone who can reach the port. Requires all three env vars. A `[SECURITY WARNING]` banner prints at startup and repeats every 60 seconds. Only use for trusted networks or development.

#### Claude Desktop (self-hosted)

```json
{
  "mcpServers": {
    "toolstem": {
      "command": "npx",
      "args": ["-y", "toolstem-mcp-server"],
      "env": {
        "FMP_API_KEY": "your_fmp_api_key"
      }
    }
  }
}
```

#### From source

```bash
npm install
npm run build
FMP_API_KEY=your_key npm run start:http
```

***

### Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `FMP_API_KEY` | Yes (self-hosted) | Financial Modeling Prep API key. Get one at [financialmodelingprep.com](https://financialmodelingprep.com). Not needed when calling the hosted endpoint. |
| `PORT` | No | Port for HTTP transport. Defaults to `3000`. |
| `ALLOW_REMOTE` | No | Set to `1` to bind HTTP on `0.0.0.0` instead of `127.0.0.1`. |
| `MCP_AUTH_TOKEN` | When `ALLOW_REMOTE=1` | Bearer token for authenticating `/mcp` requests. |
| `MCP_AUTH_DISABLED` | No | Set to `1` to skip auth. Forces `127.0.0.1` bind unless `I_KNOW_THIS_IS_DANGEROUS=1` is also set. |
| `I_KNOW_THIS_IS_DANGEROUS` | No | Set to `1` alongside `ALLOW_REMOTE=1` and `MCP_AUTH_DISABLED=1` to allow remote access without auth. Triggers a periodic warning banner. |

***

### Development

```bash
npm install
npm run dev           # stdio, hot reload via tsx
npm run build         # TypeScript -> dist/
npm start             # run built stdio server
npm run start:http    # run built HTTP server
```

***

### Architecture

```
src/
├── index.ts          # MCP server entry (stdio + Streamable HTTP)
├── actor.ts          # Apify Actor entry (legacy)
├── services/
│   └── fmp.ts        # Financial Modeling Prep API client
├── tools/
│   ├── get-stock-snapshot.ts
│   ├── get-company-metrics.ts
│   └── compare-companies.ts
└── utils/
    └── formatting.ts # Market cap formatting, CAGR, trend signals
```

All FMP endpoints are wrapped in a single `FmpClient` class. Tool implementations fan out to multiple client methods in parallel via `Promise.all`, then synthesize the merged result.

***

### License

MIT — see [LICENSE](./LICENSE).

***

**Toolstem** — curated financial intelligence for the agent-native economy. <https://toolstem.com/finance/>

# Changelog

This Actor's version history is a separate document: https://apify.com/toolstem/toolstem-mcp-server/changelog.md

# Actor input Schema

## `tool` (type: `string`):

Which tool to run. If omitted, the actor runs a default demonstration (get_stock_snapshot for AAPL) so first-time evaluators see real output. Real usage should always specify a tool.

## `symbol` (type: `string`):

Stock ticker symbol for get_stock_snapshot and get_company_metrics (e.g., AAPL, MSFT, TSLA)

## `period` (type: `string`):

Reporting period (for get_company_metrics only)

## `symbols` (type: `array`):

2-5 stock ticker symbols for compare_companies (e.g., \["AAPL", "MSFT", "GOOGL"])

## Actor input object example

```json
{
  "tool": "get_stock_snapshot",
  "symbol": "AAPL",
  "period": "annual"
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "symbol": "AAPL"
};

// Run the Actor and wait for it to finish
const run = await client.actor("toolstem/toolstem-mcp-server").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "symbol": "AAPL" }

# Run the Actor and wait for it to finish
run = client.actor("toolstem/toolstem-mcp-server").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "symbol": "AAPL"
}' |
apify call toolstem/toolstem-mcp-server --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,toolstem/toolstem-mcp-server"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/v2E9HiBt3YUYsz38t/builds/QzMnFbj0iWdP8Czyg/openapi.json
