Metadata-Version: 2.4
Name: spoken-alpha-mcp
Version: 0.1.0
Summary: MCP server for Spoken Alpha — earnings-call data and language signals API. Tools for ir-page lookup, earnings-calls history, and press-releases (scaffolded).
Project-URL: Homepage, https://spokenalpha.com
Project-URL: Documentation, https://api.spokenalpha.com/docs
Project-URL: Pricing, https://spokenalpha.com/pricing
Project-URL: Repository, https://github.com/Spoken-Alpha/earnings-signal/tree/main/mcp/spoken-alpha-mcp
Project-URL: Issues, https://github.com/Spoken-Alpha/earnings-signal/issues
Author-email: Spoken Alpha <earnings.signal.proj@gmail.com>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agent,earnings,finance,hedge-fund,investor-relations,mcp,model-context-protocol
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: respx>=0.21; extra == 'dev'
Description-Content-Type: text/markdown

# spoken-alpha-mcp

MCP (Model Context Protocol) server that exposes the [Spoken Alpha](https://spokenalpha.com) public API as tools any Claude-using agent can call by name.

The server is a thin client over `api.spokenalpha.com/v1/*`. It does not bypass auth, expose internal endpoints, or add functionality beyond what the public API ships. Wrapping, not extending.

## What it gives you

Three tools, one per Tier 1 endpoint in the [public API reference](https://api.spokenalpha.com/docs):

| Tool                  | Endpoint                                            | Status in v1                          |
| --------------------- | --------------------------------------------------- | ------------------------------------- |
| `get_ir_page`         | `GET /v1/companies/{ticker}/ir-page`                | Live                                  |
| `get_earnings_calls`  | `GET /v1/companies/{ticker}/earnings-calls`         | Live                                  |
| `get_press_releases`  | `GET /v1/companies/{ticker}/press-releases`         | Scaffolded — 503 until structured ingest ships |

All three accept a US ticker (`AAPL`, `MSFT`, `BRK.B`). `get_earnings_calls` also accepts `limit`, `cursor`, `date_from`, `date_to`, `confirmed_only`, plus client-side `fiscal_year` / `fiscal_quarter` filters.

## Getting an API key

Spoken Alpha is in private beta. Email **kyle@spokenalpha.com** to request a key. Pricing tiers and the public listing are at [spokenalpha.com/pricing](https://spokenalpha.com/pricing). Set the raw key as `SPOKEN_ALPHA_API_KEY` — the server forwards it as `Authorization: Bearer <key>` on every request.

## Install

Requires Python 3.11+.

```bash
pip install spoken-alpha-mcp
# or, after this package is published to the registry:
# uvx spoken-alpha-mcp
```

From a local checkout:

```bash
cd mcp/spoken-alpha-mcp
pip install -e .
```

## Wire it into Claude Desktop

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):

```json
{
  "mcpServers": {
    "spoken-alpha": {
      "command": "spoken-alpha-mcp",
      "env": {
        "SPOKEN_ALPHA_API_KEY": "sk_live_..."
      }
    }
  }
}
```

If `spoken-alpha-mcp` isn't on `PATH`, replace with the absolute install path or use `python -m spoken_alpha_mcp`.

## Wire it into Claude Code

Per-project MCP server (in your repo's `.mcp.json`):

```json
{
  "mcpServers": {
    "spoken-alpha": {
      "command": "spoken-alpha-mcp",
      "env": { "SPOKEN_ALPHA_API_KEY": "sk_live_..." }
    }
  }
}
```

## Example session

```
You: Where's Apple's IR page, and when was their last earnings call?

Claude calls get_ir_page("AAPL") → returns
  { "ticker": "AAPL",
    "company_name": "Apple Inc.",
    "ir_page": { "url": "https://investor.apple.com/...", "validation_status": "valid", ... },
    "_self": "..." }

Claude calls get_earnings_calls("AAPL", limit=1) → returns
  { "ticker": "AAPL",
    "calls": [ { "id": "call_AAPL_2026Q2_earnings", "call_date": "2026-05-01", ... } ],
    "pagination": { "next_cursor": null, "has_more": false },
    "_self": "..." }

Claude: Apple's IR page is at investor.apple.com (validated). Their most
        recent earnings call was Q2 FY2026 on 2026-05-01.
```

## Error handling

Every tool returns either a success payload or an error payload of the shape:

```json
{
  "error": true,
  "code": "ticker_not_found",
  "message": "No company found for ticker.",
  "status_code": 404,
  "request_id": "8c3f1e2a-...",
  "documentation_url": "https://api.spokenalpha.com/docs/errors#ticker_not_found"
}
```

Codes you'll see in practice:

- `unauthorized` (401) — bad or missing `SPOKEN_ALPHA_API_KEY`.
- `forbidden_for_tier` (403) — your tier doesn't include this field/endpoint.
- `ticker_not_found` / `ir_page_not_found` (404) — company or IR URL missing.
- `validation_error` (422) — query param out of range.
- `rate_limit_exceeded` (429) — hourly/monthly cap; `rate_limit_reset_at` is the unix timestamp.
- `data_not_yet_available` (503) — for `get_press_releases` in v1; the payload carries `planned_launch`.
- `timeout` / `network_error` — transport failure before reaching the API.

## Configuration

| Env var                       | Default                              | Notes                                    |
| ----------------------------- | ------------------------------------ | ---------------------------------------- |
| `SPOKEN_ALPHA_API_KEY`        | _(required)_                         | Raw bearer key from your dashboard.      |
| `SPOKEN_ALPHA_API_BASE_URL`   | `https://api.spokenalpha.com/v1`     | Override for staging / local dev.        |

## Development

```bash
cd mcp/spoken-alpha-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

## What this is NOT

- **Not** an MCP for our internal trading signals. The proprietary surface (per-speaker deviation, the LLM scorer composition, `short_signal_score`) is walled off in ADR-0031 — by the same rules, this MCP only exposes the public API.
- **Not** a richer client than the API itself. If a field isn't in the public API contract, it isn't in this MCP. New endpoints come through the API roadmap.
