swiss-knife
Provides MCP tools for common developer operations like file outlining, git commit context, test summary, process management, and waiting for conditions, returning structured JSON to reduce token usage.
README
swiss-knife
Structured-output CLI and MCP tools that cut agent token usage and tool-call count.
Coding agents burn tokens on chains of small shell calls: three git commands to prepare a commit, a full file read to learn one function signature, a pkill -f that matches the agent's own shell. swiss-knife bundles these recurring operations into single deterministic commands that print compact JSON, so an agent (or a human) gets the answer in one call — and gets the same answer every time.
Installation
uv tool install git+https://github.com/vinmh/swiss-knife
# or run without installing:
uvx --from git+https://github.com/vinmh/swiss-knife swiss-knife --help
Quick start
$ swiss-knife file-outline src/app.py
{
"file": "src/app.py",
"language": "python",
"symbols": [
{"kind": "class", "name": "App", "signature": "class App:", "line": 10, ...}
]
}
Output contract
Every subcommand prints a single JSON object to stdout and exits with:
| Code | Meaning |
|---|---|
0 |
success |
1 |
negative outcome, JSON still valid — test failures, wait timeout, non-zero wrapped command, kill survivors |
2 |
unrecoverable error; JSON has an "error" key |
Commands
file-outline <path>
Tree-sitter extraction of a source file's symbols — functions, classes, methods, types — with signatures and line numbers, no bodies. Read the structure of a 2000-line file for a few hundred tokens. Languages: Python, JavaScript/TypeScript, Go, Rust, C.
swiss-knife file-outline src/server.go
swiss-knife file-outline weird-extension.txt --language python
commit-context
Staged diff, branch/tracking info, untracked files, and recent log in one call — everything needed to write a commit message or PR description.
swiss-knife commit-context --repo . -n 20
test-summary <command...>
Wraps a test runner and parses its output into {passed, failed, skipped, failures: [{test, file, line, message}]}. Framework auto-detected from the project; override with --framework. Supports pytest, Jest, Vitest, go test, cargo test, RSpec, and Unity (C).
swiss-knife test-summary uv run pytest
swiss-knife test-summary --framework jest -- npx jest
proc find|stop <pattern>
Process matching against full command lines (like pgrep -f/pkill -f) that can never match its own machinery: the invoking shell chain and any command line containing a swiss-knife invocation are always excluded. find reports listening ports and process age; stop signals matches and confirms each outcome (terminated, survived, vanished, permission_denied, signal_unsupported).
swiss-knife proc find "vite dev"
swiss-knife proc stop "node server.js" --signal TERM --wait 5
wait-for
Bounded condition polling — every wait has a timeout, so it can never loop forever. Conditions (all must hold simultaneously): --port, --file, --touched (mtime at/after command start), --gone/--present (process cmdline pattern), --http (URL answers).
swiss-knife wait-for --port 5173 --http http://localhost:5173/health -t 30
swiss-knife wait-for --gone "vite dev" -t 10
run-logged [--] <command...>
Runs a command with stdout+stderr captured to a log file, avoiding three ad-hoc invocation hazards: pipes filling up and blocking, fatal errors hidden by quiet flags, and producer | grep -q dying of SIGPIPE under pipefail. Returns exit code, log tail, and optional --grep matches over the full log. On timeout the whole process tree is terminated. Put -- before commands that take their own flags.
swiss-knife run-logged --timeout 300 --grep "ERROR|WARN" -- npm run build
Logs default to a swiss-knife directory under the system temp dir; override with SWISS_KNIFE_LOG_DIR.
session-brief
One call bundling the context an agent needs to resume work in a project directory: git state, .claude/HANDOFF.md, parsed PLAN.md phase statuses, the Claude Code project memory index, the latest pi session for the directory, and any AGENTS.md files from the directory, its parents, and pi's global agent dir.
swiss-knife session-brief --cwd ~/code/myproject
mcp
Serves every command above as an MCP tool over stdio (see next section).
MCP server
Register with your MCP client — for Claude Code:
claude mcp add swiss-knife -- swiss-knife mcp
or in .mcp.json:
{
"mcpServers": {
"swiss-knife": {
"command": "swiss-knife",
"args": ["mcp"]
}
}
}
Tools: commit_context, file_outline, test_summary, proc_find, proc_stop, wait_for_condition, run_logged_command, session_brief. Each returns the same JSON the CLI prints.
Caveat: the stdio server handles one call at a time, and wait_for_condition / run_logged_command block it for up to their full timeout with no progress notifications. If your MCP client's per-call timeout is shorter, the call fails client-side while the operation keeps running. Prefer the CLI for long builds and servers; the MCP tools shine for the fast, bounded ones.
Teaching your agent to use it
Agents only reach for these tools if their instructions say to. Paste this into your CLAUDE.md (or AGENTS.md) and adjust to taste:
## swiss-knife
CLI toolkit for common operations — prefer these over chains of separate tool calls.
All commands print JSON to stdout. Exit 0 = success, 1 = negative outcome
(test failures, wait-for timeout, non-zero command, kill survivors), 2 = error
(JSON has an "error" key).
- `swiss-knife file-outline <path>` — file structure (functions, classes,
signatures, line numbers) without reading the full file. Use before reading
any file over ~200 lines, then read only the relevant ranges.
Supports Python, JS/TS, Go, Rust, C.
- `swiss-knife commit-context --repo <path>` — staged diff, branch info,
untracked files, and recent log in one call. Use instead of separate git
commands when preparing commits or PRs.
- `swiss-knife test-summary <command...>` — run tests, get structured JSON
(passed/failed/skipped/failures with file:line). Auto-detects the framework;
override with `--framework`.
- `swiss-knife proc find|stop <pattern>` — find or terminate processes by
command-line pattern. ALWAYS use instead of `pkill -f`/`pgrep -f`: it can
never match the invoking shell, reports listening ports and process age,
and confirms each kill.
- `swiss-knife wait-for [--port N] [--file P] [--gone PAT] [--http URL] -t SECS`
— poll until conditions hold. Use instead of hand-rolled `until ...; sleep`
loops; it always terminates.
- `swiss-knife run-logged [--timeout S] [--grep RE] [--] <command...>` — run a
command with stdout+stderr captured to a log file; returns exit code, tail,
and grep matches. Use for builds/servers/long commands instead of pipes.
Put `--` before commands with their own flags.
- `swiss-knife session-brief` — git state, HANDOFF.md, PLAN.md phase statuses,
and agent-harness session context in one call. Run at session start or after
compaction instead of separate git/file reads.
If the swiss-knife MCP server is registered, prefer its tools (`file_outline`,
`commit_context`, `test_summary`, `proc_find`, `proc_stop`, `session_brief`)
over the shell for these fast, bounded calls. Use the CLI instead for anything
long-running — `run-logged` builds/servers and `wait-for` with a long timeout —
because those MCP tools block the server and can exceed the client's per-call
timeout while the operation keeps running.
Platform support
| Platform | Status |
|---|---|
| Linux | supported, CI-tested |
| macOS | supported, CI-tested |
| Windows | supported, CI-tested |
Platform caveats:
- macOS: listing another user's listening ports requires root; without it those processes report
listen_ports: []. - Windows:
proc stop --signal INTreportssignal_unsupported(console interrupts cannot be delivered to arbitrary processes); useTERMorKILL.
Development
git clone https://github.com/vinmh/swiss-knife
cd swiss-knife
uv sync
uv run pytest
Layout: each command is a package under src/swiss_knife/ with two layers — core.py (pure functions returning dicts, no I/O to stdout, no Click) and a thin wrapper in cli.py that prints JSON and maps outcomes to exit codes. The MCP server in mcp_server/server.py wraps the same core functions.
Contributing
- Tests are mandatory for any behaviour change.
proc,wait-for, andrun-loggedtests spawn real processes and sockets — no mocks. Usesys.executable -cfor spawned test processes (portable, and the script text stays visible in the cmdline). - Keep JSON output schemas stable; they are the public API. New keys are fine, renames are not.
- Type hints on all public function signatures.
- tree-sitter queries live in
.scmfiles underfile_outline/queries/, not inline strings. - Run
uv run pytest -qbefore submitting; CI runs the suite on Linux, macOS, and Windows.
License
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。