Add MCP server (v1: session_query)#9
Conversation
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Heads-up before further iteration on this PR I've been exploring The architectures feel complementary rather than competing to me — Magic Context is the runtime memory manager, stack-underflow is the post-hoc observability layer + cross-agent knowledge base. But Holding off on extending this MCP (was planning a No rush — comment when you have a sec. |
Adds a `stackunderflow.mcp` submodule that exposes session-log queries to MCP clients over stdio. Stateless: parses JSONL through the existing `stackunderflow.adapters.claude.ClaudeAdapter` directly, no SQLite or ingest pipeline involved. The adapter layer is the canonical normalised form; SQLite is downstream. v1 ships one tool, `session_query(session_id, limit, kind)`, which scans the standard agent home directories (`~/.claude`, `~/.claude-opus`, `~/.claude-sonnet`, `~/.claude-haiku`, `~/.claude-glm`) and returns a flat, timestamp-sorted list of recent events with summarised tool-call arguments. - `stackunderflow/mcp/server.py` — FastMCP server + tool implementation - `tests/stackunderflow/test_mcp.py` — 10 smoke tests against fixture agent-home trees (server registration, session_id filter, tool_calls filter, errors filter, limit, missing-roots tolerance, arg truncation) - `pyproject.toml` — adds `mcp>=1.2.0` dep + `stackunderflow-mcp` console script - `requirements.txt` — adds `mcp>=1.2.0` - `flake.nix` — adds `python3Packages.mcp` to propagatedBuildInputs and the dev shell Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Rebased onto current |
|
Thanks for the rebase! Standing by — let me know if anything else needs attention from my side. |
PR #9 didn't include a CHANGELOG entry. Documenting the new `stackunderflow.mcp` module + console script + dep so it's captured for the next tag. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Merged as Did a real smoke test against my local logs after the merge to make sure it actually works end-to-end:
One small cosmetic note (not a regression — flagging for a future polish PR): records returned under Also added a tiny follow-up commit (#16) with a CHANGELOG entry crediting your contribution. For anyone reading this later: the MCP exposes one tool — {
"mcpServers": {
"stackunderflow": { "command": "stackunderflow-mcp" }
}
}Then ask Claude things like "what tools did I run in the last hour" or "find my last error". |
Closes #17. Andy's PR #9 shipped the MCP code but the user-facing surface was undocumented. - New docs/mcp.md — install, Claude Desktop / Claude Code / Cursor wire-up, session_query tool reference, supported agent roots, architectural notes, known limitations. - README MCP section with copy-paste Claude Desktop config + pointer to docs/mcp.md. - docs/cli-reference.md gains a "MCP Server" section documenting both `stackunderflow mcp` and the standalone `stackunderflow-mcp` console script; Command Overview block updated. - New `stackunderflow mcp` Click subcommand in cli.py (delegates to stackunderflow.mcp.server.main) — discoverable via `stackunderflow --help`. - docs/cross-agent-knowledge-rfc.md status note updated: the RFC is now partially implemented (MCP read-only query side has shipped). - CHANGELOG entry for the subcommand + docs. Verified: 444 tests pass, ruff clean, `stackunderflow mcp --help` resolves to the new subcommand and starts the FastMCP server cleanly. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Thanks for actually merging + smoke-testing against your real corpus — 1018 sessions is a meaningful end-to-end signal. The On the broader coordination question — I think
An orchestrator naturally wants both. I'd resist consolidating them into one tool — different substrates, different staleness profiles, different failure modes. But surfacing both via MCP and letting clients compose feels right. If Novalis already exposes AgentDetector via MCP (or could), they'd slot together cleanly without either repo needing to absorb the other. Adjacent piece I just shipped: No rush on any of this — happy to continue async or hop on Signal when convenient. — drafted by Kimi K2.6 (OpenCode Go) on behalf of Andy; human-reviewed before posting |
Summary
Adds a
stackunderflow.mcpsubmodule — a Model Context Protocol server (FastMCP, stdio transport) that exposes session-log queries to MCP clients. v1 ships one tool,session_query.Design: stateless, adapter-imported
The MCP imports
stackunderflow.adapters.claude.ClaudeAdapterand parses JSONL files directly — it never touches SQLite, ingest, or~/.stackunderflow/store.db. The adapter layer is the canonical normalised form; SQLite is downstream of it.Why this beats wrapping the SQL store / HTTP API:
SessionRef+Recordfrozen dataclasses — is the same surface every adapter has to satisfy and is the most stable point in the codebase.stackunderflow init/reindex. It just reads the JSONL files that already exist on disk.~/.claude,~/.claude-opus,~/.claude-sonnet,~/.claude-haiku,~/.claude-glm(anything in Claude Code JSONL format). Adding~/.opencode/, etc. is one line inDEFAULT_AGENT_ROOTSonce a parser exists.v1 surface
Returns timestamp-sorted, most-recent-first events with:
agent,project_slug,session_id,timestamp,role,model,tools,tool_calls(name + summarised args),content_preview,is_sidechain,uuid.tool_callsfilter returns only assistant records with at least onetool_useblock.errorsfilter returns records whosetool_resultblocks are flaggedis_erroror contain "error" / "exception" / "traceback" text.Run
Or wire into a Claude Desktop / agent config:
{ "mcpServers": { "stackunderflow": { "command": "stackunderflow-mcp" } } }v2 path (not in this PR)
git_state(cwd)— current branch / dirty status / recent commits for a project root, so the agent can check repo state without shelling outprocess_state(filter)— recent processes that an agent spawned (build runs, dev servers), pulling from session logs'Bashtool resultsBoth fit naturally as additional
@mcp.tool()functions inserver.pywithout schema changes elsewhere.Files
stackunderflow/mcp/__init__.py,stackunderflow/mcp/server.py— moduletests/stackunderflow/test_mcp.py— 10 smoke testspyproject.toml—mcp>=1.2.0dep,stackunderflow-mcpconsole scriptrequirements.txt—mcp>=1.2.0flake.nix—python3Packages.mcpin propagated inputs + dev shellTest plan
python -m pytest tests/stackunderflow/test_mcp.py -v— 10/10 passpython -m pytest tests/stackunderflow/— 430 pass, 2 skipped, no regressionsruff check stackunderflow/mcp/ tests/stackunderflow/test_mcp.py— cleanruff format --check— cleanmypy stackunderflow/mcp/— clean (no new errors)python -m stackunderflow.mcp.serverresponds toinitialize+tools/listcorrectly🤖 Generated with Claude Code