This repository is a working demo that orchestrates multiple Model Context Protocol (MCP) servers from Python. It provides:
- A CLI chat and a Streamlit UI that let you trigger MCP tools via simple
!fs,!gh,!local, and!investcommands. - A local Investment MCP server (stdio) offering tools for quick quotes, risk metrics, portfolio construction, and rebalance planning, with live data where possible and synthetic fallbacks.
At a high level, the app starts a small fleet of MCP servers (Filesystem, GitHub, Local HTTP, and the local Invest server) and routes tool calls from the chat/UI to the right server.
-
Chat-driven MCP orchestration (
chatbot/chat.py): parse!fs/!gh/!local/!investlines, send them to the right MCP server, and show results. -
Streamlit UI (
ui/app.py): friendly UI with quick actions for Filesystem, GitHub commits, and investment tools. -
Local Investment MCP server (
invest_mcp/…): stdio JSON‑RPC with tools:price_quote: last price + returns (1d/7d/30d) using yfinance/CoinGecko with synthetic fallbackrisk_metrics: annualized mean/volatility/Sharpebuild_portfolio: simplified long‑only Markowitz allocationrebalance_plan: suggested trades to reach target weights
-
External MCP servers via
npx:@modelcontextprotocol/server-filesystem@modelcontextprotocol/server-github
-
Logging & caching: JSONL logs in
logs/, data cache in.cache/invest_mcp/.
flowchart LR
UI["Streamlit UI (ui/app.py)"] -- "chat & actions" --> CHAT["CLI/Chat Orchestrator (chatbot/chat.py)"]
subgraph Orchestration
CHAT --> RUNTIME["MCP Runtime (chatbot/mcp_runtime.py)"]
RUNTIME --> FS["@mcp/server-filesystem (npx)"]
RUNTIME --> GH["@mcp/server-github (npx)"]
RUNTIME --> LOCAL["Remote MCP (HTTP RPC)"]
RUNTIME --> INVEST["Invest MCP (stdio, invest_mcp/main.py)"]
end
INVEST --> TOOLS["price_quote | risk_metrics | build_portfolio | rebalance_plan"]
TOOLS --> LIVE["yfinance & CoinGecko"]
CHAT -. "OpenAI API" .- LLM["LLM: openai.ChatCompletions"]
FS --> FSDIR["/Filesystem directory/"]
GH --> GitHub["GitHub API"]
Key decisions & trade‑offs
- MCP stdio vs HTTP: Filesystem/GitHub servers run via stdio (
npx …), while thelocalconnector uses HTTP JSON‑RPC ifREMOTE_MCP_URLis set. This keeps local dev simple while allowing remote MCPs. - Live data with fallback: Investment tools try live data (yfinance/CoinGecko) with caching; if unavailable, synthetic series keep the tools functioning for demos and offline use.
- Simple gradient optimizer (portfolio): a lightweight projected‑simplex gradient descent avoids extra solver dependencies.
- JSONL logs: minimal operational breadcrumbs without external observability systems.
└── diegoval-dev-redes-pry1/
├── README.md
├── requirements.txt
├── chatbot/
│ ├── chat.py # CLI chat orchestrator
│ ├── config.py # env vars & paths
│ ├── llm.py # OpenAI client wrapper
│ └── mcp_runtime.py # Start/route to MCP servers (stdio & HTTP)
├── demo/
│ └── mcp_github.txt # Sample text
├── Filesystem/ # Default FS root for filesystem MCP
│ ├── hola.txt
│ └── test.txt
├── host/
│ └── mcp_host_stdio.py # Minimal MCP stdio host helper
├── invest_mcp/ # Local MCP server (stdio)
│ ├── main.py # Entrypoint: run_stdio_loop()
│ ├── protocol.py # MCP request router & tool dispatch
│ ├── transport_stdio.py # stdio loop
│ ├── lib/
│ │ └── data_live.py # yfinance/CoinGecko + caching utilities
│ └── tools/
│ ├── data.py # synthetic universe & series
│ ├── price_quote.py # quotes & short-term returns
│ ├── risk_metrics.py # mean/vol/Sharpe
│ ├── build_portfolio.py# long-only Markowitz demo
│ └── rebalance_plan.py # suggested trades
└── ui/
└── app.py # Streamlit front-end
-
Python: 3.9+ recommended
-
Node.js & npx: required to launch the Filesystem & GitHub MCP servers
-
Accounts/keys:
- OpenAI API key (required):
OPENAI_API_KEY - GitHub token (optional):
GITHUB_PERSONAL_ACCESS_TOKEN/GITHUB_TOKEN/GH_TOKEN - CoinGecko (optional):
COINGECKO_PRO_API_KEYorCOINGECKO_API_KEY(demo)
- OpenAI API key (required):
# 1) Clone and enter
git clone https://github.com/Diegoval-Dev/Redes-pry1
cd Redes-pry1
# 2) Python env & deps
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# 3) Environment (required: OPENAI_API_KEY)
cat > .env << 'EOF'
OPENAI_API_KEY=sk-your-key
# Optional extras
# GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
# FS_ROOT=/absolute/path/to/Filesystem
# REMOTE_MCP_URL=http://localhost:8000 # if you have a remote MCP over HTTP
# COINGECKO_PRO_API_KEY=...
# COINGECKO_API_KEY=...
EOF
# 4a) Run the Streamlit UI
streamlit run ui/app.py
# 4b) Or run the CLI chat
python -m chatbot.chatOn first run, the app will start the MCP servers: filesystem, github (via
npx), a remote HTTP MCP if configured, and the localinvest_mcpstdio server.
All configuration can be provided via environment variables (recommended: a local .env file).
| Name | Type | Default | Required | Description |
|---|---|---|---|---|
OPENAI_API_KEY |
string | — | ✅ | OpenAI API key used by chatbot/llm.py. |
GITHUB_PERSONAL_ACCESS_TOKEN / GITHUB_TOKEN / GH_TOKEN |
string | — | ❌ | Token used by the GitHub MCP server for higher rate limits. |
FS_ROOT |
path | <repo>/Filesystem |
❌ | Root directory exposed by the Filesystem MCP server. Created if missing. |
CHAT_LOG_DIR |
path | logs |
❌ | Directory for JSONL chat and MCP logs. |
REMOTE_MCP_URL |
URL | — | ❌ | Base URL for a remote MCP over HTTP JSON‑RPC. If set, local-remote client is enabled. |
REMOTE_MCP_PATH |
path | /rpc |
❌ | RPC path appended to REMOTE_MCP_URL. |
MCP_LOG_FILE |
path | logs/invest_mcp_server.log |
❌ | Log file for the local Invest MCP server. |
MCP_LOG_LEVEL |
enum | INFO |
❌ | Log level for the Invest MCP server (INFO/DEBUG/ERROR). |
INVEST_MCP_CACHE_DIR |
path | .cache/invest_mcp |
❌ | Cache directory for live data. |
INVEST_MCP_DEBUG |
bool | 0 |
❌ | Enable verbose logging in data_live.py. |
COINGECKO_PRO_API_KEY |
string | — | ❌ | Auth for CoinGecko Pro API (preferred). |
COINGECKO_API_KEY |
string | — | ❌ | Demo key for public CoinGecko API. |
Run:
python -m chatbot.chatYou’ll see a panel with example commands. Type exit to quit. The assistant can also suggest commands, which will auto‑execute and summarize results.
Run:
streamlit run ui/app.pyThe sidebar includes quick actions for common investment queries and for listing the Filesystem root or GitHub commits.
Commands are single lines starting with a prefix and a JSON payload:
-
Filesystem:
!fs {"tool":"list_directory","args":{"path":"/absolute/path","recursive":false}} -
GitHub commits:
!gh {"tool":"list_commits","args":{"owner":"Diegoval-Dev","repo":"Redes-pry1","sha":"main","per_page":3}} -
Local HTTP MCP (example tool name):
!local {"tool":"json_validate","args":{"blob":"{\"hello\":123}"}} -
Investment tools:
!invest {"tool":"price_quote","args":{"symbols":["BTC","ETH","SPY","GLD"],"useLive":true}} !invest {"tool":"risk_metrics","args":{"symbols":["SPY","QQQ","GLD","BTC"],"riskFree":0.02,"lookbackDays":252,"useLive":true}} !invest {"tool":"build_portfolio","args":{"capital":10000,"riskLevel":3,"allowedSymbols":["SPY","QQQ","GLD","BTC","ETH"],"useLive":true}}
All tools return both a textual content entry and a structuredContent JSON payload.
-
price_quote(invest_mcp/tools/price_quote.py)- Input:
{ symbols: string[], useLive?: boolean, days?: number } - Output:
{ quotes: Array<{symbol,name,last,ret1d,ret7d,ret30d,currency,source}>, dataSource: "live"|"synthetic"|"mixed" }
- Input:
-
risk_metrics(invest_mcp/tools/risk_metrics.py)- Input:
{ symbols: string[], riskFree?: number, lookbackDays?: number, useLive?: boolean } - Output:
{ metrics: Array<{symbol, meanAnnual, volAnnual, sharpe}> }
- Input:
-
build_portfolio(invest_mcp/tools/build_portfolio.py)- Input:
{ capital: number, riskLevel: 1..5, horizonMonths?: number, allowedSymbols?: string[], useLive?: boolean } - Output:
{ targetWeights: {symbol,weight}[], allocations: {symbol,amount}[], expectedAnnualReturn?: number, volAnnual?: number, sharpe?: number }
- Input:
-
rebalance_plan(invest_mcp/tools/rebalance_plan.py)- Input:
{ current: {symbol,amount}[], targetWeights: {symbol,weight}[] } - Output:
{ totalCurrent: number, targetAmounts: {symbol,targetAmount,lastPrice}[], trades: {symbol,action,delta}[] }
- Input:
- Logs: JSONL files in
logs/, e.g.logs/chat_host.jsonl,logs/mcp_invest.jsonl, andlogs/invest_mcp_server.log. - Cache:
.cache/invest_mcp/*.jsonfor live data responses (yfinance/CoinGecko). TTL varies by call (30–600s). - Filesystem root: defaults to
<repo>/Filesystembut can be overridden withFS_ROOT.
No automated tests or CI workflows are present in the repository.
No linters/formatters or pre-commit configs are present in the repository.
Local execution only. No Docker/K8s manifests are included.
- Investment MCP server logs to
logs/invest_mcp_server.logand stderr. - The
chatbot/mcp_runtime.pylogs MCP JSON traffic underlogs/(per server).
- Secrets: Keep
OPENAI_API_KEY, GitHub, and CoinGecko keys in.env(never commit). The app reads withpython-dotenv. - Network: Live data calls hit yfinance and CoinGecko. Consider rate limits and API key policies.
- Optional: add unit tests for tool logic (portfolio optimizer, metrics).
- Optional: Dockerize the stack for reproducible runs.
- Optional: add CI (lint, tests) and pre-commit hooks.
-
Falta OPENAI_API_KEY en .envat startup- Create
.envwithOPENAI_API_KEY=...and rerun.
- Create
-
Failed starting MCP server 'filesystem'/npxnot found- Install Node.js and ensure
npxis inPATH.
- Install Node.js and ensure
-
HTTP ... at REMOTE_MCP_URLerrors- Verify
REMOTE_MCP_URLis reachable and the server speaks MCP JSON‑RPC at/rpc(or setREMOTE_MCP_PATH).
- Verify
-
Investment live data returns empty
- It falls back to synthetic data. Check internet access and optional CoinGecko keys for rate‑limit relief.
-
GitHub commits tool shows errors or is rate‑limited
- Provide a GitHub token in
.envto raise limits.
- Provide a GitHub token in
Open a PR with focused changes. Keep the README accurate: do not document features that aren’t in the code.
Unknown — no license file detected.
- Model Context Protocol servers used via
npx:@modelcontextprotocol/server-filesystem,@modelcontextprotocol/server-github. - yfinance and CoinGecko for market data; Streamlit for the UI; Rich for CLI output.
- Project metadata (name, status, license, maintainers) not provided. Document when known.
- CI/coverage/docs links absent. Add when available.
- Remote MCP endpoint (
REMOTE_MCP_URL) is optional and not included in this repo. - Python version support is inferred; no explicit toolchain/pin provided.
- No tests: add unit tests for portfolio/risk logic and MCP transport.