Skip to main content
Glama
mrgutierrezmario

InsiderTrack MCP

README.md
# InsiderTrack MCP

An [MCP](https://modelcontextprotocol.io) server for
[InsiderTrack](https://github.com/mrgutierrezmario/insidertrack): let an AI
assistant — Claude Desktop, claude.ai, Claude Code, or any MCP client — ask
who in Congress is buying what, which corporate insiders are clustering,
what a ticker scores and why, and whether those signals actually worked.

**By M.G. Network and Technology Solutions.**

> **v0.1.0** — running in production alongside InsiderTrack: nine read tools,
> two resources, two prompts, token-gated over the public URL. Connected to
> claude.ai as a custom connector. Design notes in [DESIGN.md](DESIGN.md).

## What it looks like

A question the site cannot answer on any one page — *"Where are several
insiders buying their own stock this month, and did anyone in Congress buy
the same names? How good is that member's record?"* — becomes three tool
calls. Recorded against the live instance on 2026-09-20:

```
cluster_buys(days=30)
  BABA  2 insiders  $25.7M      PMTS  5 insiders  $12.0M
  GME   4 insiders  $21.7M      SBLK  8 insiders  $6.9M
  UBER  2 insiders  $15.3M      NGL   2 insiders  $5.8M   …

congress_trades(ticker="UBER", direction="buy", since="2026-06-01")
  Dan Newhouse (R-WA, House)  $1,001 – $15,000  traded 2026-07-10

member_track_record(politician_id=…)
  89 measured buys · 90-day win rate 43.8% · beat SPY 40.4% of the time
  avg excess vs SPY −2.3 pts · weight in the composite score: 0.9
```

So: one overlap, and the member behind it has a below-market record — the
score already discounts his trades. Claude writes that paragraph; the
server only hands it the facts, each stamped `as_of` and with the disclaimer.

## How it works

InsiderTrack already computes everything — scores, member track records,
cluster buys, 30/60/90-day outcomes — behind an HTTP API. This server is a
small, separately deployed process that exposes a curated set of tools over
that API, each described well enough that a model picks the right one, with
guardrails so a chat cannot hurt the app:

- read-only by construction (one optional write, off by default),
- bearer-token auth and a per-client rate limit over HTTP,
- capped result sizes, errors returned as data the model can recover from,
- one audit line per call,
- no database credentials, no volumes — the container can only reach the app.

## Run it

Locally, as a subprocess for Claude Code (no network, no tokens):

```bash
python -m venv .venv && .venv/bin/pip install -e ".[dev]"
claude mcp add insidertrack -e INSIDERTRACK_URL=http://localhost:8013 -- .venv/bin/insidertrack-mcp
```

Over HTTP, inside the InsiderTrack Compose stack: add the service from
[`deploy/compose.snippet.yml`](deploy/compose.snippet.yml) to its
`deploy/compose.yml`, put an `MCP_TOKENS=name:token` line in its
`deploy/.env`, and add a `/mcp` handler to the Tailscale serve config
(Tailscale strips the prefix, so the server itself listens at `/`).

Then connect a client:

| Client | How |
|---|---|
| **claude.ai / Claude Desktop** | Settings → Connectors → *Add custom connector* → URL `https://<host>/mcp`, transport Streamable HTTP, Authentication **No sign-in**, request header `X-API-Key` = the token. (claude.ai keeps the `Authorization` header for its own OAuth, so use `X-API-Key`.) The nine tools appear under *Read-only tools*; set them to *Always allow*. |
| **Claude Code** | `claude mcp add --transport http insidertrack https://<host>/mcp --header "Authorization: Bearer <token>"` |
| **Local, no network** | `claude mcp add insidertrack -e INSIDERTRACK_URL=http://localhost:8013 -- .venv/bin/insidertrack-mcp` |

```bash
python -c "import secrets; print(secrets.token_urlsafe(32))"   # make a token
```

## Tools

| Tool | Question it answers |
|---|---|
| `search` | "Who is Pelosi in this system? What's the exact ticker?" — ids and symbols for the other tools |
| `congress_trades` | "What did members of Congress do in NVDA since June?" — filter by ticker, member, buy/sell, owner, asset type, dates |
| `ticker_signal` | "What does KMX score, and why?" — the 0–100 composite, sub-scores and written reasons |
| `top_signals` | "What scores highest right now?" — the strongest tickers, no reasons |
| `cluster_buys` | "Where are several insiders buying their own stock?" — market-wide Form 4 clusters |
| `member_track_record` | "How have Pelosi's buys actually done?" — 30/60/90-day returns vs SPY, buys and sales, the weight it earns |
| `leaderboard` | "Which members beat the market most often?" — ranked by 90-day beat-SPY rate |
| `signal_outcomes` | "Does 'Strong Watch' actually go up?" — hit-rates per label per scoring version |
| `model_desk` | "What did the site's model call this morning, and how have its calls scored?" |

All read-only and idempotent (declared as such in the tool annotations),
each capped to a sensible number of rows, dollars pre-formatted, no internal
ids a model cannot use. One optional write, `watchlist_add`, exists only when
the operator sets `MCP_ALLOW_WRITES=1` and gives the server their own
watchlist identity — it never holds an admin credential.

### Resources and prompts

| | |
|---|---|
| `insidertrack://brief/today` | The site's model's morning brief and today's calls, as text |
| `insidertrack://sources/health` | How fresh each data source is, and recent errors — so an answer can say "House data is two days old" |
| prompt `morning_brief` | What changed this week: cluster buys, Congress purchases, top scores, how the model's calls resolved |
| prompt `due_diligence(ticker)` | A one-page note on one ticker, in a fixed order, ending with what the data supports, what it doesn't, and what would change the picture |

Every result carries `as_of` and a disclaimer: InsiderTrack scores public
disclosures; it is a scorecard, not investment advice.

## Development

```bash
.venv/bin/ruff check . && .venv/bin/ruff format --check .
.venv/bin/python -m pytest -q
docker build -f deploy/Dockerfile -t insidertrack-mcp .
```

Tests run against recorded API responses in `tests/fixtures/` — no
InsiderTrack instance needed. CI runs lint, tests and the Docker build on
every push; Dependabot keeps the pins current (patch and minor bumps merge
themselves once CI is green).

## Operations

Nothing to back up — no database, no volumes; tokens live in InsiderTrack's
`.env`, which its nightly backup covers. How it comes back after a reboot,
how to update or rebuild it, rotate tokens, and what to check when it's
down: [`deploy/OPERATIONS.md`](deploy/OPERATIONS.md).

## Versions

The version lives in `VERSION` and is reported by the server on
initialise and at `/health`. See [CHANGELOG.md](CHANGELOG.md).

## License

[PolyForm Noncommercial 1.0.0](LICENSE) — © 2026 M.G. Network and Technology Solutions.

TDQS

A4.4/5.0

Scored across 9 tools

Disambiguation5/5

Each tool has a distinct job: search is the ID/symbol resolver, congress_trades and cluster_buys expose trade activity, ticker_signal/top_signals split single-ticker detail from market-wide ranking, and member_track_record/leaderboard separate individual performance from rankings. Even the most similar pairs are explicitly list-vs-detail or individual-vs-ranking.

Naming Consistency4/5

Names are uniformly lowercase snake_case and mostly noun phrases describing the returned data, which is readable and predictable. The lone exception is search, a verb, while the rest are nouns like congress_trades or signal_outcomes, so the convention is slightly mixed.

Tool Count5/5

Nine tools is a well-scoped size for this domain: a lookup helper, trade queries, signal queries, performance analytics, and validation/scorecard tools each earn their place. It is small enough to navigate but large enough to cover the core workflows.

Completeness4/5

The surface covers the main workflow end to end: search resolves IDs, congress_trades and cluster_buys provide activity data, ticker_signal and top_signals deliver scores, and member_track_record/leaderboard/signal_outcomes/model_desk provide performance and validation. Minor gaps exist, such as no raw corporate Form 4 trade listing and no tool that actually uses Federal Reserve official IDs returned by search, but they are workaroundable rather than blocking.

Maintenance

ActivityMaintained
ResponsivenessNo issues