Files
last30days-skill/mcp
Matt Van Horn 35f12cb9ea feat(mcp): stdio MCP server with research tool
U3 of the Claude Desktop .mcpb bundle plan.

- internal/engine/run.go invokes python3 with the cached last30days.py,
  forwards os.Environ() so MCPB user_config env-injection reaches the
  engine, sets PYTHONPATH so the lib/ imports resolve, and surfaces
  three distinct error shapes (missing interpreter with install URL,
  non-zero exit with stderr, timeout). RunOptions.PythonPath lets tests
  inject a stub without manipulating PATH.
- internal/engine/run_test.go drives a shell-script stub interpreter
  through happy path, env forwarding, PYTHONPATH, non-zero exit with
  stderr surfacing, timeout, missing python3 (empty PATH), missing
  last30days.py, empty CacheDir, and timeout-env-override parsing.
- internal/tools/research.go registers a single research tool whose
  schema mirrors /last30days <topic> (required topic, optional emit
  enum, optional save bool). Validation failures surface as MCP
  tool errors so Claude sees structured failures instead of transport
  faults; engine extract or run errors fold engine stderr into the
  message so users can diagnose without leaving Desktop.
- internal/tools/research_test.go covers requireString, emitArgument,
  boolArgument, handler-level validation routing, and formatRunError.
- cmd/last30days-pp-mcp/main.go wires NewMCPServer + tools.Register +
  ServeStdio. main.Version is ldflags-stamped at build time and
  namespaces the per-user cache. mcp-go pinned at v0.54.0.

Smoke check: ./build/last30days-pp-mcp answers tools/list with the
research tool plus full schema and read-only/open-world annotations.
go test ./... passes across engine + tools (32 cases).
2026-05-17 20:51:00 -07:00
..

last30days-pp-mcp

Go MCP server that wraps the last30days Python engine for Claude Desktop. Packaged as a .mcpb bundle (drag-drop install into Claude Desktop).

The MCP server exposes a single research tool that mirrors the /last30days <topic> slash command available in Claude Code. At runtime the binary extracts the vendored Python engine into a per-user cache and shells out to python3 to produce the synthesis input Claude renders.

Architecture

  • cmd/last30days-pp-mcp/ - server entry point
  • internal/engine/ - embed.FS of the Python engine + cache extractor + subprocess wrapper
  • internal/tools/ - MCP tool handlers (currently research)
  • internal/engine/vendored/ - mirror of skills/last30days/scripts/, generated by scripts/sync-engine.sh (gitignored). Lives inside the engine package because //go:embed cannot reach files outside its own package directory.
  • manifest.json - MCPB v0.3 manifest consumed by Claude Desktop and printing-press bundle

Local build

# Mirror the Python engine into vendored/.
bash scripts/sync-engine.sh

# Build for the current host.
go build -ldflags "-X main.Version=dev" -o build/last30days-pp-mcp ./cmd/last30days-pp-mcp

# Package as a .mcpb (requires the printing-press binary on PATH).
printing-press bundle . --skip-build --binary build/last30days-pp-mcp

The output .mcpb lands at build/last30days-pp-mcp-<os>-<arch>.mcpb. Drag it into Claude Desktop's Extensions panel to install.

Runtime requirements

End users need Python 3.12+ on PATH. The bundle ships the engine source but relies on the host interpreter.

Versioning

The MCPB manifest.json version is hand-bumped in the same PR that ships engine changes worth releasing. Release CI stamps the Go binary's main.Version from the tag.