Skip to content

Platform Chat Agent (MCP Server)

A local AI assistant layer that lets Claude Desktop talk directly to Market Pulse — querying predictions, sentiment, news, and political trades via natural language.


Overview

┌─────────────────────────────────────────────────────────────────────┐
│                        Developer / Analyst                          │
│  "What does the model predict for NVDA next week?"                  │
│  "Show me recent congressional buys in tech stocks"                 │
└──────────────────────────────┬──────────────────────────────────────┘
                               │  natural language query
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        Claude Desktop                               │
│                     (Claude Sonnet / Opus)                          │
│                                                                     │
│   understands the question → picks the right tool → formats answer  │
└──────────────────────────────┬──────────────────────────────────────┘
                               │  MCP tool call (stdio)
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   mcp_server/server.py                              │
│                  (FastMCP, runs locally)                            │
│                                                                     │
│   list_tickers      get_prediction     get_all_predictions          │
│   get_sentiment     get_news           get_political_trades          │
│   get_price_history get_debate         get_prediction_accuracy      │
└──────────────────────────────┬──────────────────────────────────────┘
                               │  SQLAlchemy queries
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  Supabase PostgreSQL (prod)                         │
│                  SQLite (local dev fallback)                        │
│                                                                     │
│   predictions · news_articles · sentiment_scores                   │
│   stock_prices · political_trades · tickers                        │
└─────────────────────────────────────────────────────────────────────┘
What Why it matters
Natural language interface No SQL, no dashboard navigation — just ask
9 tools over live DB Answers always reflect the current state of the data
Runs locally via stdio No server to deploy; no API keys to expose to the internet
Claude Desktop picks the tool You don't need to know which tool maps to which question

How It Works

Step 1 — You ask Claude Desktop a question

You ──► "Which of our Korean tickers has the most bullish sentiment this week?"
         or
        "Run a bull/bear debate for Samsung (005930)"
         or
        "What's NVDA's prediction accuracy for 7-day horizon?"
  • Input: natural language question typed in Claude Desktop
  • Output: question sent to Claude with the MCP tool list available
  • Who does it: Claude Desktop (local app)

Step 2 — Claude picks and calls the right tool

Question ──► Claude reasons about which tool fits ──► tool call

Examples:
  "sentiment for AAPL"        ──► get_sentiment(ticker="AAPL", days=7)
  "recent TSLA news"          ──► get_news(ticker="TSLA", days=3)
  "Pelosi trades"             ──► get_political_trades(trader="Pelosi")
  "all predictions today"     ──► get_all_predictions(horizon="1d")
  "NVDA price last 30 days"   ──► get_price_history(ticker="NVDA", days=30)
  "bull/bear case for MSFT"   ──► get_debate(ticker="MSFT")
  • Input: your question + list of 9 available tools
  • Output: structured tool call parameters
  • Who does it: Claude (the LLM reasoning layer)

Step 3 — MCP server executes the query

Tool call arrives via stdin (stdio transport)
   │
   ▼
mcp_server/server.py  (FastMCP)
   │
   ├── opens a DB session  (SessionLocal → Supabase or SQLite)
   ├── runs SQLAlchemy query
   ├── formats result as JSON string
   └── returns JSON via stdout

DB is read-only — the MCP server never writes data
  • Input: validated tool call (name + params)
  • Output: JSON string with query results
  • Who does it: mcp_server/server.py

Step 4 — Claude formats the answer

Raw JSON ──► Claude synthesizes ──► human-readable response

Example output:
  "Samsung (005930) sentiment over the past 7 days:
   - Average score: +0.31 (positive)
   - 14 articles scored; 9 positive, 3 neutral, 2 negative
   - Strongest signal: Q3 earnings beat (score +0.72)"
  • Input: JSON tool result
  • Output: formatted, conversational answer in Claude Desktop
  • Who does it: Claude (the LLM synthesis layer)

The 9 Tools

┌───────────────────────┬──────────────────────────────────────────┐
│ Tool                  │ What it fetches                          │
├───────────────────────┼──────────────────────────────────────────┤
│ list_tickers          │ All tracked symbols (US + KR)             │
│ get_prediction        │ ML forecast for one ticker + horizon      │
│ get_all_predictions   │ Latest forecasts for every ticker         │
│ get_sentiment         │ News sentiment summary for a ticker       │
│ get_news              │ Recent headlines with sentiment scores    │
│ get_political_trades  │ Congressional + insider trades            │
│ get_price_history     │ OHLCV bars for a ticker                  │
│ get_debate            │ Multi-agent bull/bear verdict             │
│ get_prediction_accuracy│ Historical accuracy stats per ticker     │
└───────────────────────┴──────────────────────────────────────────┘

Components

Claude Desktop
   │  stdio (stdin/stdout pipe)
   ▼
mcp_server/
   └── server.py   ──── FastMCP app, 9 tools registered ────► DB
                             │
                             ├── db/database.py    (SessionLocal)
                             ├── db/models.py      (ORM models)
                             ├── sentiment/analyzer.py
                             └── models/predictor.py / debate.py
Component What it does Lives in
server.py FastMCP app — registers and serves 9 tools mcp_server/server.py
SessionLocal Opens/closes DB connections per tool call db/database.py
get_ticker_sentiment_summary() Aggregates sentiment for get_sentiment tool sentiment/analyzer.py
get_latest_predictions() Bulk prediction query for get_all_predictions models/predictor.py
debate() Multi-agent bull/bear analysis for get_debate models/debate.py

Data Flow

You (Claude Desktop)
  │
  │  "show me the bull/bear debate for AAPL"
  ▼
Claude (reasoning)
  │  tool call: get_debate(ticker="AAPL", market="US")
  ▼  via stdio
mcp_server/server.py
  │  db = SessionLocal()
  │  result = debate(db, "AAPL", "US")
  │
  │  debate() internally reads:
  │    ├── latest Prediction row         (ML signal)
  │    ├── SentimentScore avg (7d)       (news mood)
  │    ├── StockPrice (RSI, momentum)    (technicals)
  │    └── generates bull case + bear case + verdict via Claude Haiku
  │
  │  db.close()
  │  return JSON { bull, bear, verdict, confidence }
  ▼
Claude (synthesis)
  │
  │  formats into readable debate summary
  ▼
You (see the answer)

Setup

# 1. Run the MCP server (it stays alive as long as Claude Desktop is open)
python -m mcp_server.server

# 2. Register it in Claude Desktop  (~/.claude/claude_desktop_config.json):
{
  "mcpServers": {
    "market-pulse": {
      "command": "python",
      "args": ["-m", "mcp_server.server"],
      "cwd": "/path/to/fintrack"
    }
  }
}

# The MCP server connects to whatever DATABASE_URL is in .env
# (Supabase in prod, SQLite in local dev — automatic fallback)

Key Decisions

Decision Chosen approach Why
Transport stdio (not HTTP) No port conflicts; Claude Desktop handles the process lifecycle
DB access Direct SQLAlchemy, read-only Fastest path; no separate HTTP hop through the FastAPI layer
Tool count 9 tools (no more) More tools = more token overhead for Claude to reason through; kept focused
get_debate live Runs inference at call time Debate is expensive — only run when explicitly asked, not cached
Market filter param Optional on most tools Works for both US-only and mixed US+KR queries

What Can Go Wrong

Failure Impact How we handle it
DATABASE_URL not set Tools return empty or SQLite fallback data Check .env; MCP server logs the connection string on start
DB connection pool exhausted Tool calls hang or error Each tool opens and closes its own session; no leaks by design
get_debate slow Claude Desktop appears to hang Debate calls Claude Haiku internally — takes 3–8s; normal
MCP server not registered Claude Desktop shows no market-pulse tools Verify claude_desktop_config.json path and cwd
Stale predictions Forecasts look old Predictions refresh every 6h via the scheduler; check run_predictions job
No sentiment data get_sentiment returns score: null News scraper may have missed a cycle; check fetch_us_news / fetch_kr_news logs

Relationship to the Rest of the System

                     ┌─────────────────────────────┐
                     │      Market Pulse System     │
                     │                              │
  ┌──────────────┐   │  ┌─────────────────────────┐│
  │ Claude       │   │  │  FastAPI  (port 8000)    ││
  │ Desktop      │   │  │  React dashboard reads   ││
  │              │◄──┤  │  data from here          ││
  │  uses MCP    │   │  └─────────────────────────┘│
  │  tools for   │   │             │                │
  │  ad-hoc      │   │  ┌──────────▼──────────────┐│
  │  queries     │   │  │  Supabase PostgreSQL     ││
  └──────────────┘   │  └──────────▲──────────────┘│
                     │             │                │
  ┌──────────────┐   │  ┌──────────┴──────────────┐│
  │ MCP Server   │───┤  │  APScheduler (15 jobs)  ││
  │ (stdio)      │   │  │  fills the DB every     ││
  └──────────────┘   │  │  15min – 24h            ││
                     │  └─────────────────────────┘│
                     └─────────────────────────────┘

  MCP Server ≠ the API
  - FastAPI serves the React dashboard (port 8000, HTTP)
  - MCP Server serves Claude Desktop (stdio, no port)
  - Both read the SAME database

Glossary

Term Plain English definition
MCP (Model Context Protocol) A standard way for AI apps like Claude Desktop to call tools — like plugins, but for AI
FastMCP A Python library that makes it easy to build an MCP server; handles the protocol wiring
stdio transport The MCP server communicates by reading from stdin and writing to stdout — like a command-line pipe, no network involved
Tool A named function the AI can call, like get_prediction(ticker="AAPL") — the AI decides when to call it
Claude Desktop The desktop app version of Claude that supports MCP tool plugins
get_debate A tool that triggers a live multi-agent discussion — one simulated bull, one simulated bear, with a verdict
SessionLocal The SQLAlchemy function that opens a database connection; each tool call opens one and closes it when done
DATABASE_URL The connection string that points the MCP server at either Supabase (production) or a local SQLite file (development)
Horizon The forecast time window: 1d = tomorrow, 7d = next week, 30d = next month
Sentiment score A number from -1.0 (very negative news) to +1.0 (very positive news) computed from news headlines
Political trades Buys and sells by US Congress members (required by the STOCK Act to be disclosed within 45 days)

Last updated: 2026-06-02 · Owner: Michael Ko