Skip to main content
Glama

swiss-knife

test license: MIT python 3.13+

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

Related MCP server: mcp_server_for_claudes_toolbox

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 INT reports signal_unsupported (console interrupts cannot be delivered to arbitrary processes); use TERM or KILL.

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, and run-logged tests spawn real processes and sockets — no mocks. Use sys.executable -c for 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 .scm files under file_outline/queries/, not inline strings.

  • Run uv run pytest -q before submitting; CI runs the suite on Linux, macOS, and Windows.

License

MIT

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vinmh/swiss-knife'

If you have feedback or need assistance with the MCP directory API, please join our Discord server