mcp-agent-toolkit
README.md
# mcp-agent-toolkit
An MCP (Model Context Protocol) server exposing two other projects in this
portfolio as tools any MCP client -- Claude Desktop, or any other
MCP-compatible app -- can call directly:
- **`query_finance_filings`** -- hybrid RAG search (BM25 + semantic +
cross-encoder reranking) with cited answers over 10 companies' real SEC
10-K filings, from [rag-finance-assistant](https://github.com/naomytcheums-dotcom/rag-finance-assistant).
- **`fix_code_bug`** -- plans, writes, and test-verifies a fix for a seeded
bug in a small demo repo, from [code-fix-agent](https://github.com/naomytcheums-dotcom/code-fix-agent)'s bounded LangGraph loop.
- **`list_finance_companies`** -- lists the 10 available tickers.
MCP is the protocol OpenAI, Google DeepMind, and Microsoft have all
adopted for connecting LLM clients to external tools -- this project is
about proving I can package real, already-working agentic systems behind
it, not a toy "hello world" server.
## Why vendored, not a dependency on the sibling repos
`vendor/rag_finance/` and `vendor/code_fix_agent/` are copies of the
relevant source (and, for the finance side, the already-cleaned SEC filing
text) from the two sibling repos, not a `pip install` of them or a
`git submodule`. A recruiter who clones this repo should get a working
server without also having to clone and wire up two other repositories --
self-contained beats DRY for a single-purpose portfolio piece like this
one. The tradeoff, stated plainly: a bug fixed in the original
rag-finance-assistant or code-fix-agent repos won't automatically appear
here.
## Setup
```bash
python -m venv .venv
.venv\Scripts\activate # source .venv/bin/activate on macOS/Linux
pip install -r requirements.txt
# One-time: build the local vector store for query_finance_filings.
# No API key needed -- embeddings are local sentence-transformers.
python scripts/build_finance_index.py
```
Create a `.env` file at the project root (gitignored) with your own key,
only needed for `query_finance_filings`'s generation step and for
`fix_code_bug`:
```
ANTHROPIC_API_KEY=sk-ant-...
```
### Connect it to Claude Desktop
Add this to Claude Desktop's `claude_desktop_config.json` (Settings ->
Developer -> Edit Config):
```json
{
"mcpServers": {
"ai-portfolio-toolkit": {
"command": "C:\\path\\to\\mcp-agent-toolkit\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\mcp-agent-toolkit\\server.py"],
"env": { "ANTHROPIC_API_KEY": "sk-ant-..." }
}
}
}
```
Restart Claude Desktop, then ask it something like *"What did Apple's 10-K
say about total net sales? Use the finance filings tool."* -- Claude will
call `query_finance_filings` itself and show the tool call in its UI.
### Run the server directly (for debugging, not how an MCP client uses it)
```bash
python server.py
```
Speaks MCP over stdio -- not meant to be interacted with directly in a
terminal; use an MCP client (Claude Desktop, or the `mcp` SDK's own dev
inspector: `mcp dev server.py`) to actually call the tools.
## Design choices, stated up front
- **Environment-variable API key, not per-call config.** The sibling
Streamlit dashboards pass keys through per-request config because
they're shared multi-tenant deployments -- one process, many visitors,
each supplying their own key. An MCP server launched by Claude Desktop
is the opposite shape: one process per user, started by their own
client. An env var set in that user's own `claude_desktop_config.json`
is the correct BYOK pattern here, not a shortcut.
- **`fix_code_bug` never opens a PR.** Unlike code-fix-agent's own
dashboard, there's no natural place in a tool call for a visitor to
supply their own GitHub token and target repo, and letting an LLM's
tool-call decision push code somewhere is a meaningfully bigger blast
radius than proposing a diff it can review first. Scoped to "propose and
verify a fix" only -- see `mcp_tools/code_fix.py`.
- **`query_finance_filings` doesn't modify the vendored retrieval.py.**
Company filtering happens by biasing the retrieval query with the
company's full name and filtering the returned pool by ticker
afterward, rather than adding a `where` filter to the vendored Chroma
query -- keeps the vendored retrieval code byte-for-byte traceable back
to its source project. See `mcp_tools/finance_qa.py`.
- **Every `fix_code_bug` call gets a disposable copy of the demo repo.**
Same statefulness lesson as code-fix-agent's own dashboard: operating on
the vendored original directly would mean the first call's "fix"
permanently fixes the seeded bug for every call after it.
## Bugs found while building this, before any live run
1. **Package name collision.** The vendored `code_fix_agent/src/tools/`
package (`repo_explorer.py`, `git_ops.py`, etc.) has the same name as
the wrapper package this project's own tools live in. With both on
`sys.path`, Python resolved `import tools` to whichever one came first
and code-fix-agent's own internal imports
(`from tools.repo_explorer import write_file`) broke with
`ModuleNotFoundError`. Fixed by renaming this project's wrapper package
to `mcp_tools/` rather than touching the vendored code.
2. **Vendored files assumed a `src/` nesting level that wasn't there.**
`retrieval.py`, `generation.py`, and `indexing.py` compute
`PROJECT_ROOT = Path(__file__).resolve().parent.parent`, correct in
the original repo where they live at `src/<file>.py` one level under
the project root -- but I'd initially copied them straight into
`vendor/rag_finance/`, which put `PROJECT_ROOT` one directory too high
and broke every relative data path (`data/processed/finance_docs.json`
not found). Fixed by nesting them under `vendor/rag_finance/src/` to
match the layout the code actually assumes, instead of editing the
vendored files.
## Tests
```bash
pytest tests/ -v
```
6 tests: the server registers exactly the 3 expected tools with correct
input schemas, ticker validation/normalization, and `fix_code_bug`'s
API-key guard -- all protocol-level, none need an Anthropic API key.
`query_finance_filings`'s retrieval stage (BM25 + semantic + reranking) is
verified working end-to-end against the real indexed filings -- confirmed
it correctly isolates a single company's chunks from the shared 10-company
corpus. Its generation stage, and all of `fix_code_bug`, need a funded
Anthropic key to run past the point these tests reach -- not yet tested
live, same status as the sibling projects.
## Stack
Official `mcp` Python SDK (stdio transport) + the vendored RAG and
LangGraph agent pipelines from rag-finance-assistant and code-fix-agent.
## Status
Structurally verified: all 6 tests pass, tool registration/dispatch
confirmed through the real MCP server object (not mocked), retrieval
confirmed working against the real vector store. Generation
(`query_finance_filings`'s answer step) and the full `fix_code_bug` loop
are code-complete but blocked on the same zero-credit Anthropic API key as
the rest of this portfolio -- see Status in the sibling repos' READMEs.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues