Skip to content

About

MCP tool server for AI coding agents -- encoding-aware file tools, binary analysis, DAP debugger, SSH/SFTP, process memory, and more

Topics

Resources

Stars

24 stars

Watchers

0 watching

Forks

Repository files navigation

agent-tool

한국어

agent-tool MCP server

MCP (Model Context Protocol) tool server for AI coding agents.

Why?

Built-in tools in AI coding agents (Claude Code, Cursor, Codex, etc.) have known limitations:

  • Tab indentation breaks: LLMs output spaces, but your project uses tabs. The built-in Edit tool writes spaces as-is, corrupting your indentation style.
  • Encoding corruption: Editing EUC-KR, Shift-JIS, or GB18030 files silently converts them to UTF-8, breaking legacy projects.
  • Too many separate tools: Making the agent find, install, and configure Redis CLI, MySQL client, SSH client, etc. is tedious and error-prone. agent-tool bundles 40 tools into one binary and exposes them on demand through compact profiles.
  • No reverse engineering support: Built-in tools can't disassemble binaries, inspect PE/ELF headers, find function boundaries, or search cross-references. agent-tool includes static binary analysis (disassembly, decompilation to C with PDB/DWARF types, xref, function detection), a DAP debugger, and CheatEngine-style memory tools -- giving your agent full reverse engineering capabilities.
  • Network censorship: In some countries, government-level web filtering breaks plain curl/wget requests. agent-tool uses ECH (Encrypted Client Hello) and DoH (DNS over HTTPS) by default to work around these restrictions.

agent-tool solves these with agent-oriented tools that preserve project conventions while keeping model context bounded.

Supported Agents

Claude Code, Codex CLI, Cursor, Windsurf, Cline, Gemini CLI, and any MCP-compatible agent.

LLM-efficient by default

The default core profile exposes only 11 schemas (including toolbox) instead of all 40. In a protocol-level measurement this reduced the serialized tool list from about 74 KB (full) to 15 KB. For the smallest steady-state context, start with --profile core-lite; its five schemas are about 6.4 KB and expose only read, write, edit, grep, and toolbox. Use toolbox(operation="describe", tool="ssh", compact=true, tool_operation="execute") to load only one operation's fields and required list, then invoke it through toolbox(operation="call", tool="ssh", arguments={...}). The gateway does not depend on dynamic tool-list refresh, so it works with fixed-binding clients such as Codex. Describe returns a tool/version-bound schema_handle; sending it on a later describe returns a short unchanged acknowledgement when the schema is still current. Common compact operations include SSH execution, MySQL queries, file copy, Windows screenshots/clipboard images, and static-analysis operations. You can also start with --profile core-lite|coding|remote|analysis|full.

Potentially large text responses default to 32K characters with a 128K hard ceiling. Truncation is always visible and pageable tools return next_offset or next_cursor. Local relative paths resolve against an explicit workspace, then the MCP client root.

Features

Tool Description Status
Edit String replacement with smart indentation and encoding preservation (supports dry_run) ✅
Read Encoding-aware, line-numbered reading. Defaults to 400 lines/32K chars, reports truncation and exact next_offset, safely handles very long lines, optional SHA-256. Flexible offset and MCP ImageContent support ✅
Write Encoding-aware file creation/overwrite ✅
Grep Encoding-aware regex search with 32K output budget, compact file-grouped output, relative paths, .gitignore/.ignore/generated-directory filtering, binary detection, output modes/context, and deterministic next_cursor paging without repeated matches ✅
Glob Sorted, bounded file matching with **, relative paths, .gitignore/.ignore/generated-directory filtering, explicit has_more, and deterministic cursor paging ✅
ListDir Bounded/pageable directory listing. max_entries + continuation cursor, directory/file filters, entry-name glob filters, counts-only mode, flat/tree output ✅
Diff Compare two files with unified diff output (encoding-aware). Files differing only in line endings or a trailing newline say so instead of returning an empty diff ✅
Patch Apply unified diff patch to a file (supports dry_run). Each line keeps its own ending, so a mixed CRLF/LF file is not rewritten ✅
Checksum Compute file hash (md5, sha1, sha256) ✅
FileInfo File metadata (size, encoding, mixed line-ending counts, indentation, line count) ✅
ConvertEncoding Convert file encoding (EUC-KR ↔ UTF-8, add/remove BOM, etc.) ✅
Delete Safe file/directory deletion, including compact batches of up to 100 file_paths. Directories require recursive=true; protected roots, symlink blocking, bounded errors, and dry_run preview ✅
Rename Atomic file/directory rename or move (dry_run) ✅
ProcList List running processes — PID, name, command line, memory. Sensitive args auto-masked. Filter by name or port ✅
ProcKill Kill, suspend, or resume processes by PID or port. Tree kill, signal selection (kill/term/hup/int/stop/cont), zombie handling (Linux), dry_run ✅
ProcExec Execute commands as new processes without blocking the agent: runs still going after yield_after_sec return a job_id (wait/status/tail/cancel/list, process-tree kill), background jobs keep capturing output, suspended start, lifetime timeout/env vars, and safe repeated-diagnostic compaction with expiring raw-output retrieval ✅
SSH SSH execution with 32K head+tail capture, original byte counts, proper non-zero-exit errors, and background jobs (start/wait/status/tail/cancel, also visible via toolbox operation=job), UTF-8 powershell_script output on non-English Windows. Auth-aware pooling, host-key verification, ProxyJump, IPv6 ✅
SSHKey Convert local private keys between PuTTY PPK v3, traditional PEM, modern OpenSSH, and PKCS#8. Auto-detects input, supports encrypted PPK/OpenSSH output, writes mode 0600, and never returns key material ✅
SFTP Transfer files and manage remote filesystems over SSH. Upload, download, ls, stat, mkdir, rm, chmod, rename. Reuses SSH session pool. Max 2 GB per transfer ✅
Bash Persistent shell sessions with working directory/environment retention, safe repeated-diagnostic compaction, and expiring raw-output retrieval. Session pooling (max 5, idle timeout 30 min). Unix: bash/sh, Windows: PowerShell/git-bash/cmd ✅
Download Download files from URLs to disk. ECH + DoH by default. SSRF protection. HTTP/SOCKS5 proxy. Atomic write. Max 2 GB ✅
HTTPReq Execute HTTP requests with any method (GET/POST/PUT/PATCH/DELETE/HEAD/OPTIONS). API testing with custom headers, body, proxy. SSRF protection ✅
Query Read one value from a JSON, YAML or TOML file by dot-notation path (e.g. dependencies.react, services.web.ports[0], users[*].email); format from the extension or format. Saves tokens on large configs ✅
Copy Copy files/directories with atomic write and permission preservation. Recursive directory copy. Windows locked-file fallback (renames running exe/DLL aside). dry_run preview ✅
Mkdir Create directories with optional permission mode (octal, e.g. 0755). Recursive by default (mkdir -p). dry_run preview ✅
MultiRead Read up to 50 files with a call-wide 32K budget, 200-line per-file default, long-line safety, and per-file/overall continuation metadata. Hashes are opt-in ✅
RegexReplace Regex find-and-replace across files/directories. Encoding and line-ending preserving, capture groups ($1, $2). Skips binary files. dry_run preview ✅
NetCheck Network diagnostics: external_ip (public IPv4/IPv6 with provider fallback), dns (A/AAAA/MX/CNAME/TXT/NS/SOA over DoH or the system resolver), tls (certificate subject, issuer, expiry, SANs, TLS version, cipher), port (TCP OPEN/CLOSED with response time) ✅
MySQL Execute SQL queries on MySQL/MariaDB. Table-formatted SELECT results with configurable row/column/cell/total-output limits; affected rows for DML. Use SQL LIMIT/OFFSET for paging ✅
Redis Execute Redis commands with formatted output by type. TLS support. Dangerous commands (FLUSHALL, SHUTDOWN, etc.) blocked ✅
SLOC Count source lines of code per language. 70+ language detection, per-file/language breakdown, blank line stats, max_depth control ✅
Debug Interactive debugger via DAP (Debug Adapter Protocol). Full DAP coverage with bounded values/output and paging for variables, completions, modules, and loaded sources. Tested with dlv (Go), debugpy (Python), codelldb (C/C++/Rust). Works with any DAP-compatible adapter. Stdio and TCP modes. Note: vsdbg (Microsoft) requires VS Code licensing and is not usable standalone — use codelldb or netcoredbg as open-source alternatives ✅
Analyze Static binary analysis and reverse engineering. Decompilation of x86/x64 PE/ELF functions to C (Gosleigh, a Go port of Ghidra's decompiler core, run in an isolated worker process with time/memory limits); a matching PE PDB (built-in reader, no DIA SDK; pdb_force loads one whose GUID differs) or embedded DWARF is read automatically for function names, prototypes, struct/enum types, global data, bitfields and local variables (names and types) in decompilation (the structs/enums a function names are printed after it with member offsets and enum values; type_info prints any other by name), and for names and exact function bounds in disassemble, call_graph and function_at; MSVC decorated names are demangled; Go binaries use the Go ABI; non-returning functions are detected as in Ghidra (noreturn_verify keeps a callee whose code reaches a ret returning when its call sites alone voted it non-returning); undecodable bytes end only their path (halt_baddata()); a runaway flow (junk-byte obfuscation, where Ghidra times out) is decompiled inside the function's x64 .pdata extent with each exit marked (halt_missing()), and assume_branches fixes conditional jumps a runtime trace resolved; agent-tool decompile-all dumps a whole binary to a JSONL corpus; x86/x64/ARM/ARM64 disassembly (address + instruction by default, show_bytes adds the hex encoding; switch tables inside the code print as data lines with their case targets); semantic x86/x64 instruction search (mnemonic, register, immediate, memory displacement) with exhaustive executable-offset recovery, CFG confidence, function names, target/result filters, and parallel fixpoint register/stack/read-only constant tracing into ABI-aware calls and tail calls (stdcall argument cleanup modeled, read from the imported DLLs for x86 imports); PE/ELF/Mach-O parsing with bounded, pageable PE import output; xref to an address, the strings containing a text, or a struct field (Class::member, confirmed by decompiling), covering code, immediates and data pointers (vtable slots), each reference named by its containing function; function discovery/call graphs (function bounds without a PDB matched PDB bounds for 100% of addresses on a large x64 image, 99.5% on x86; callers through thunks and tail jumps, vtable references), pointer/RTTI/vtable/struct analysis, imphash, Rich header, DWARF, strings, hexdump, pattern search, entropy, overlay detection, and binary diff. No global file size limit ✅
Memtool CheatEngine-style process memory tool — search/filter/read/write memory values, read_chain (resolve base+offset pointer chains, batched in one call), live disassembly (x86/x64/ARM/ARM64), undo, struct pattern search, pointer scan, memory diff. Disk-backed snapshots for large scans. Session management with idle timeout. Windows (ReadProcessMemory) and Linux (/proc/pid/mem). Windows auto-enables SeDebugPrivilege when elevated; opt-in force_dacl bypasses a same-user process's self-hardened DACL (original restored after). Long scans yield a job_id and stop promptly on cancel (a cancelled filter is rolled back) ✅
Wintool Windows GUI automation — find/enumerate windows and child controls, capture screenshots (ImageContent PNG via PrintWindow), read clipboard images, read/set text, click, type, send raw messages, show/hide/minimize/maximize, move/resize, close, focus. screenshot/clipboard return ImageContent by default (save_path option for file output). Enables AI agents to "see" and interact with GUI applications. Windows only ✅
CodeGraph Fully embedded semantic code graph: Go standard-library AST plus lazy compressed tree-sitter WASM for C/C++, Python, C#, Rust, and Java. Adds declaration/definition identity, return-chain and generic/alias propagation, transitive includes, calibrated overload evidence, virtual/interface dispatch, macro/callback edges, build-condition provenance, and multi-root workspaces. No compiler, language server, external binary, LLM call, or token cost ✅
SetConfig Change runtime settings (encoding, file size limit, symlinks, workspace, etc.) ✅
Help Built-in usage guide for agents (encoding, indentation, troubleshooting) ✅

Persistent analysis annotations

The existing analyze tool can save user comments and labels in SQLite with annotation_set, search/read them with annotation_list, and remove them with annotation_delete. Disassembly and decompilation load saved notes automatically. These are user assessments, visibly separate from automatic symbols and debug types; labels and subjects do not rename engine symbols or override inferred types.

{"operation":"annotation_set","file_path":"sample.exe","rva":"0x1234","subject":"rax","comment":"User pointer returned here","annotation_status":"hypothesis","annotations_path":"project.annotations.sqlite"}
{"operation":"disassemble","file_path":"sample.exe","va":"0x140001234","annotations_path":"project.annotations.sqlite"}
{"operation":"annotation_list","file_path":"sample.exe","query":"User","annotations_path":"project.annotations.sqlite"}

Call through toolbox (operation="call", tool="analyze", arguments={...}); use toolbox describe or help topic analyze for the full schema and examples.

  • annotations_path manually selects the SQLite file for saving and loading; relative paths use the workspace/MCP root. The default is <user config dir>/agent-tool/analysis-annotations.sqlite (Windows: under %APPDATA%). Reads do not create databases; the first annotation_set does. This is separate from the rebuildable codegraph DB and disposable analysis cache.
  • Notes are scoped by the full binary SHA-256 and static address. Identical copies keep their notes; changed binaries do not inherit them. There is no automatic migration between builds. Use a static va (hex or file/debug symbol) or PE rva (module-relative offset), not a live ASLR address or file offset.
  • annotation_kind is instruction (default), function (entry address), or decompile. Optional subject identifies a register, operand, or variable at that location. annotation_status is hypothesis (default), confirmed, or rejected; this records the user's assessment.
  • For a C-line comment, first run decompile with line_numbers=true. Pass the returned code_hash, the C-body line (L number), the function entry va, and annotation_kind="decompile" to annotation_set. Notes render before the corresponding line. A changed C snapshot keeps the note at the function header as needs_review instead of attaching it to another line. Headers, annotations, and trailing type definitions do not count toward L numbers.
  • Function notes appear above the C body. Instruction notes appear inline in disassembly. Decompile also gathers instruction notes inside exact PDB/.pdata or sized ELF-symbol ranges, showing each original VA above the C body. Unknown ranges fall back to entry notes with a notice; at most 16 ranges per function are used. These notes are not guessed onto individual C lines.
  • Set without an ID creates a new anchor; it rejects an occupied anchor instead of overwriting another editor's work. Update by annotation_id requires the exact expected_revision string from set/list. Omitted fields are preserved; nonempty top-level fields update only those values. Use annotation_patch for explicit empty strings or line=0; its supplied fields override top-level values. The merged record must still have a label or comment and a valid anchor. Delete requires both ID and expected revision. Stale edits/deletes fail without changing the record; read it again before retrying. Revisions remain strings, including in rendered notes and abbreviated receipts.
  • List supports address, kind, subject, status, ID and literal query filters (ASCII case folding). max_results defaults to 50 (max 200); result_offset is a row index and next_result_offset continues the JSON list. Output limits can shorten a page; raise max_output_chars when a single listed note cannot fit. Writes require at least 256 output characters, checked before any change. If full write details cannot fit, success still returns a short JSON receipt with saved, annotation_id, revision (or deleted) and details_omitted=true. Disassembly/decompile page by character instead. Rendered views cap notes at 500; list retrieves the rest.
  • Annotation DB load failures produce a visible warning alongside the original disassembly/decompilation; annotation CRUD still reports DB errors normally. Legacy v1/v2 DBs remain readable without modification. Their first write atomically migrates to v3, adding missing revision/evidence/provenance/anchor fields. Existing revisions are preserved (v1 starts at "1"). Older builds that only understand v1/v2 cannot open a v3 DB.

Partial edit example (use the ID and revision returned by your last read):

{"operation":"annotation_set","file_path":"sample.exe","annotation_id":"<id>","expected_revision":"1","annotation_patch":{"comment":"Confirmed user pointer","annotation_status":"confirmed","label":""},"annotations_path":"project.annotations.sqlite"}

Batch and evidence example:

{"operation":"annotation_batch","file_path":"sample.exe","annotations_path":"project.annotations.sqlite","batch":[{"operation":"set","rva":"0x1234","subject":"rax","comment":"User pointer","provenance":"manual analysis","evidence":[{"kind":"static","va":"0x140001230","source":"lookup_user call","detail":"Return value is used as a context pointer"}]},{"operation":"set","annotation_id":"<id>","expected_revision":"1","annotation_patch":{"annotation_status":"confirmed"}}]}
  • A batch contains 1..32 set/delete items sharing one binary and DB. It opens and hashes once; each item commits independently and returns an indexed receipt, including conflicts. Successful items remain committed when another fails. Required max_output_chars is at least 768 * item_count + 256, checked before any changes. The default budget supports 32 items. A DB-open error fails the envelope; cancellation leaves completed items committed and marks remaining items failed.
  • Optional evidence stores up to 16 user-supplied observations with kind (static, runtime, user), optional exact-string va, source, and required detail. provenance records the origin of the judgment. Neither sources nor observations are fetched or automatically verified. Both appear in saved/rendered notes and are searchable; sparse edits preserve them. annotation_patch with evidence:[] or provenance:"" explicitly clears them.
  • When saving a C-line note, include the exact raw line in anchor_text. annotation_suggest with its annotation_id decompiles that function and returns the current code_hash, revision and up to three candidate lines. Unchanged snapshots use the original line; otherwise stored text or token overlap proposes candidates. Equal top scores are marked ambiguous. Generic/missing anchors may produce no candidates. Old notes without text need manual selection after a snapshot change. Suggestions never write the DB. After review, call annotation_set with ID, expected_revision and annotation_patch:{"line":N,"code_hash":"<current hash>","anchor_text":"<raw line>"}. The revision guard still applies. Source/detail/provenance limits are 512/1024/512 UTF-8 bytes; anchor_text is one C line, max 2048 bytes.
{"operation":"annotation_suggest","file_path":"sample.exe","annotation_id":"<id>","annotations_path":"project.annotations.sqlite"}

Keep private annotation databases out of public Git history. This repository ignores *.annotations.sqlite* and the default DB filename. Custom filenames need their own ignore rule. Keep a backup of durable notes; clearing analysis caches does not remove them.

Key Improvements

Smart Indentation

LLMs typically output spaces, but many projects use tabs. AgentTool auto-converts indentation to match the file's existing style.

  • Inherits indent_style, indent_size, and tab_width per property from parent .editorconfig files, respecting root = true, unset, indent_size=tab, and common ** path patterns
  • Falls back to a content sample of up to 8 MiB, without a fixed line-count cap. Long lines and LF, CRLF, or CR endings are supported. Lexical block-opening evidence takes priority over raw indent/dedent frequencies, reducing confusion with continuation alignment; inconclusive evidence retains the deterministic frequency fallback
  • When recovering unique anchors, new space-indented levels use the nearest block-width evidence within 32 lines and 16 KiB. Lexical state is scanned from the file start within the 8 MiB sample; anchors beyond it retain the previous fallback. Common comments, quoted/raw/triple-quoted literals, and parenthesized/bracketed continuations are excluded from structural evidence. This is a heuristic, not a language parser or semantic formatter
  • Preserves the detected space width when existing space indentation conflicts with a tab setting
  • Converts tabs/spaces and space widths such as 2 ↔ 4; converted matches stay at line boundaries, and tab-depth correction preserves relative nesting
  • Unique line and multiline block anchors use actual local indentation and prefix mappings, preserving minority styles, alignment, and indented blank lines. Block nesting must agree
  • C++/header and Python file edits lazily reuse the embedded Tree-sitter WASM engine to infer new space-indented levels from direct statements in the actual enclosing block, rather than nearby sibling blocks or argument alignment. No external compiler, Python installation, CGO, or index is required
  • For successfully parsed replacement snippets, continuation lines aligned to an actual inline token column follow the opener's indentation shift; hanging indentation retains level rescaling even when the first argument is inline, and multiline literal/comment interiors retain their supplied content. Exact matches and explicit style overrides keep their existing behavior
  • Syntax assistance falls back to the existing heuristic on unsupported files, inconclusive/error-bearing enclosing blocks, analysis failures/timeouts, or sources over 8 MiB. Each parse has a 2-second budget; replacement-snippet assistance is limited to 64 KiB/512 lines. Syntax recovery is not a guarantee of semantic equivalence
  • Rejects equally plausible tab-depth candidates instead of choosing one arbitrarily
  • Detection is heuristic, not a language formatter; use dry_run=true to review an automatic edit

Encoding Preservation

Edits preserve the original file encoding instead of forcing UTF-8.

  • Detection priority: BOM → per-call encoding override → inherited .editorconfig charset → BOM-less UTF-16 → valid UTF-8 → chardet auto-detection → fallback encoding
  • Supported: UTF-8, UTF-8 BOM, EUC-KR, Shift-JIS, ISO-8859-1, UTF-16 (LE/BE, with or without BOM), and more
  • Inherited settings: charset inherits independently of indentation settings; new files honor charset = utf-8-bom by writing a UTF-8 BOM
  • Decode failures: malformed UTF-8/UTF-16, detected lossy decoding, and unsupported encodings return errors. write refuses to overwrite an existing file whose encoding cannot be read
  • Retry without project changes: read, multiread, edit, multiedit, write, patch, and file_info accept encoding="EUC-KR", encoding="CP949", or another supported charset, overriding .editorconfig. An existing BOM still takes priority; use convert_encoding for intentional conversion
  • Detection limits: automatic detection remains heuristic; its 64 KiB sample starts after the ASCII preamble so long headers do not hide legacy text. Specify encoding or charset when the result is ambiguous
  • No false warnings on ASCII: valid UTF-8 is verified directly, so plain ASCII files never raise a low-confidence warning
  • Line endings: Detects LF, CRLF, CR, and mixed files. edit matches a multi-line old_string whether the file uses CRLF or LF, including files that mix both, and text inserted by edit/regexreplace follows the newline style of the region it lands in, so the rest of the file is left byte-identical

Consistent reads and edit batches

  • read, multiread, file_info, grep, and patch agree on LF, CRLF, and CR line boundaries. A final terminator adds no phantom line; reading past EOF returns no lines.
  • Read hashes come from the same raw bytes as the text. edit, multiedit, write, patch, regexreplace, and convert_encoding check their captured source hash before saving. expected_hash is available on edit, multiedit, and patch.
  • multiedit supports the same encoding and indent_style options as edit; each replacement sees the previous result, and a failed replacement leaves the whole file unchanged.
  • multiread accepts global or per-file encoding. Resume the original input list with start_file_index=next_file_index and resume_offset=next_offset (omit the offset when zero); the current file keeps its original window end, and later files keep their original ranges.
  • Read output budgets are 256–131072 characters. An oversized first line is visibly shortened so paging can advance; raise max_output_chars or max_line_chars to inspect it in full.

Conversion and bulk-operation results

  • Directory regexreplace reports files_scanned, error_count, limit_reached, and truncated. The matching-file cap is explicit. Successful files stay changed if another file fails; inspect the partial result and retry only failed files.
  • diff accepts encoding_a/encoding_b and context_lines=0. It distinguishes identical decoded text from identical bytes, reports CR/LF placement changes, and separates a missing final newline from other ending changes.
  • convert_encoding accepts from_encoding for source hints. GBK and GB18030 remain distinct targets; GB2312 is a GBK compatibility alias. Characters unsupported by the chosen target leave the original unchanged.
  • File writes stage a replacement beside the target. If staging or replacement fails, they return an error and do not fall back to truncating the original in place. Close programs locking the target or correct directory permissions before retrying.

Token-safe directory listings

listdir defaults to 500 entries per page and returns next_cursor when more entries are available. Narrow results with directories_only, files_only, name_pattern (for example A*), or multiple OR patterns in include. Use counts_only=true when only matching file/directory counts are needed.

Idle memory release

After 30 minutes with no tool call, the server returns its heap to the OS. A stdio MCP server cannot tell an abandoned client from a quiet one -- the process that spawned it may be alive, finished with it, and still holding the pipe open, so no EOF ever arrives -- and exiting on that guess would break a session that merely paused. Releasing the memory is the safe half of that trade: an instance that once read a 50MB file settles back to its ~20MB baseline instead of holding 200MB for the rest of the machine's uptime. Open shell and ssh sessions survive, and nothing the client can observe changes.

Quick Start

  1. Download the binary for your OS from Releases
  2. Run agent-tool install (or agent-tool install claude for a specific agent)
  3. Restart your IDE / agent
  4. Done — the compact core tools are available immediately; toolbox describes and calls every other tool on demand

Or just ask your AI agent to do it for you:

"Download agent-tool from https://github.com/knewstimek/agent-tool/releases/latest and run agent-tool install"

Any capable AI coding agent (Claude Code, Codex, etc.) can handle the full download → install → restart flow automatically.

Recommended: Tell your agent to prefer agent-tool

After installing, agents will have access to agent-tool but may still default to built-in tools (Read, Edit, etc.). To ensure agents prefer agent-tool's encoding-aware, indentation-smart tools, add one of the instructions below.

Code navigation tip: For large projects, add this to your CLAUDE.md / AGENTS.md to enable AST-based code navigation:

At the start of a session, run codegraph(op="index", path="<project_root>") to build a code index.
For several repositories sharing one graph, use codegraph(op="index", path="<db_root>", roots=["<source_root_1>", "<source_root_2>"]). Source-root provenance prevents unrelated projects with the same symbol names from contaminating candidates while explicit/transitive includes can still cross roots.
Then use codegraph for structural queries (find, callers, callees, methods, inherits) instead of grep.

Pick Strict or Soft:

Mode When to use Instruction
Strict Projects with non-UTF-8 files or mixed indentation ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools. agent-tool preserves file encoding and respects .editorconfig indentation settings.
Soft General projects Prefer agent-tool MCP tools (mcp__agent-tool__*) over built-in file tools when available.

Where to put it:

Claude Code — CLAUDE.md (per-project) or global instructions

Per-project — add to your project's CLAUDE.md:

ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools.

Global (all projects) — add to ~/.claude/CLAUDE.md:

ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools.

Hard enforcement — deny built-in file tools at the permission level via ~/.claude/settings.json:

{
  "permissions": {
    "deny": ["Read", "Edit", "MultiEdit", "Write", "Glob", "Grep"]
  }
}

This makes Claude Code's built-in file tools unavailable, so the agent is forced to use agent-tool. Recommended when you want strict enforcement without relying on prompt instructions.

Codex CLI — model_instructions.md (global)
  1. Add to ~/.codex/config.toml (top-level, not inside [mcp_servers.*]):
model_instructions_file = "~/.codex/model_instructions.md"
  1. Create ~/.codex/model_instructions.md:
ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools.
  1. Restart Codex.

Per-project — add to your project's AGENTS.md instead.

Cursor / Windsurf / Cline — .cursorrules or AGENTS.md

Add to your project's .cursorrules, .windsurfrules, or AGENTS.md:

ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools.

Installation

Auto-install (recommended)

# Register with all detected agents (full auto-approve — all tools)
agent-tool install

# Safe mode — only auto-approve local file tools (no SSH, HTTP, DB, shell)
agent-tool install --safe-approve

# No auto-approve — manual approval required for every tool call
agent-tool install --no-auto-approve

# Register with a specific agent
agent-tool install claude
agent-tool install claude --safe-approve

# Uninstall (removes agent-tool entry only, preserves other settings)
agent-tool uninstall          # from all agents
agent-tool uninstall claude   # from specific agent

Install permission levels:

Level Flag Auto-approved tools
Full (default) (none) All tools (mcp__agent-tool__* wildcard)
Safe --safe-approve 29 local-only tools (read, edit, write, grep, glob, etc.) — no SSH, HTTP, DB, bash, process control
None --no-auto-approve No tools — every call requires manual approval

Approval level is independent of schema profile: installation may approve the full namespace while the server still starts with the token-efficient core profile. toolbox is intentionally not auto-approved by --safe-approve, because its operation=call gateway can invoke network, shell, database, and process-control tools. Safe-mode users should review each toolbox approval and avoid granting it a permanent allow rule unless they intend to trust the full AgentTool namespace.

Manual setup

Claude Code / Cursor / Cline (settings.json or mcp.json):

{
  "mcpServers": {
    "agent-tool": {
      "command": "/path/to/agent-tool"
    }
  }
}

Codex CLI (~/.codex/config.toml):

[mcp_servers.agent-tool]
command = "/path/to/agent-tool"

Options

# Select the initial schema profile (default: core)
agent-tool --profile core-lite

# Keep the core and eagerly expose only selected additional tools
agent-tool --profile core+copy+delete+ssh+wintool

# Set fallback encoding for projects with non-UTF-8 files
agent-tool --fallback-encoding EUC-KR

Profiles are presets: core-lite (read/write/edit/grep/toolbox), core (11 schemas), coding (core plus broader file/build/shell tools), remote, analysis, and full. Append +tool names to a preset for a custom initial inventory; for example, core+copy+delete+ssh+wintool exposes 15 tools while leaving analysis and other remote tools behind the gateway. The same syntax works in AGENT_TOOL_PROFILE and toolbox operation=profile. Unknown tools or empty components reject the whole selection before any tools are registered. At runtime, prefer the client-independent toolbox gateway: operation=describe returns one tool's schema (compact=true plus tool_operation limits it to one operation), and operation=call invokes it through the stable toolbox binding. Re-send a returned schema_handle to avoid receiving an unchanged schema again. When command diagnostics are compacted, operation=output retrieves the bounded raw output by its reported ID for 30 minutes and reports next_offset when paging is needed. Long-running calls do not block the agent: bash, ssh, sftp, download, analyze, codegraph, and memtool return a job_id once a call has run for about 15 seconds (procexec after its yield_after_sec) while the work continues, so the agent can answer the user or do other work. operation=job with job_action=wait|status|tail|cancel|list collects the result; cancelling a wait never stops the job. enable, disable, and profile remain available for clients that honor tools/list_changed; fixed-binding clients can always keep using the gateway.

Environment Variable

Set AGENT_TOOL_FALLBACK_ENCODING and/or AGENT_TOOL_PROFILE to avoid repeating CLI flags:

# Windows (no admin required)
setx AGENT_TOOL_FALLBACK_ENCODING EUC-KR
setx AGENT_TOOL_PROFILE coding

# Linux / macOS (add to ~/.bashrc or ~/.zshrc)
export AGENT_TOOL_FALLBACK_ENCODING=EUC-KR
export AGENT_TOOL_PROFILE=coding

Priority: CLI flag > environment variable > default (UTF-8).

Local SSH/SFTP connection profiles

SSH and SFTP accept either connection_profile or a session-local connection_id, so host, user, key, and jump-host fields do not need to be repeated. Profiles are read from the OS user config directory at agent-tool/connections.json; override the location with AGENT_TOOL_CONNECTION_PROFILE_FILE. Keep this file local and explicitly ignored if it is placed inside a workspace.

{
  "connections": {
    "dev": {
      "host": "192.0.2.10",
      "user": "builder",
      "key_file": "/local/path/to/id_ed25519",
      "host_key_check": "strict",
      "trusted": true
    }
  }
}

An initial call returns an opaque connection_id that remains reusable by both tools for 30 minutes. Local profiles default to trusted:true; set trusted:false to show the private-address warning on every call instead of once per pooled connection. This affects only display; SSRF blocking and cloud metadata protection are unchanged. SSH also supports quiet, echo_command, and result_only; the last returns compact JSON centered on stdout, stderr, and exit_code. SFTP supports quiet, result_only, and upload_many (up to 100 files).

For Windows PowerShell, pass script text in powershell_script instead of command. SSH uploads a unique UTF-8 temporary .ps1 through a short PowerShell command's standard input, executes its contents with a short PowerShell launcher, and deletes it after success or failure. Standalone powershell[.exe] / pwsh[.exe] commands using -EncodedCommand (or -enc, -ec, -e) are staged automatically at 8,000 UTF-16 code units. Safe profile, interactive, apartment, and execution-policy options are preserved; unsupported options or shell suffixes require explicit powershell_script input. Scripts are limited to 4 MiB. SFTP is not required, including on legacy Windows SSH servers.

{"operation":"execute","connection_profile":"dev","powershell_script":"Write-Output 'hello'","result_only":true}

Preparation and foreground execution share timeout_sec. Background scripts use the same upload and cleanup path, then expose job_id for wait/status/tail/cancel. The remote launcher attempts cleanup in finally; confirmed completion also triggers bounded SSH cleanup. Cancellation or connection loss does not prove remote termination, so the tool leaves deletion to the remote launcher and reports cleanup_warning if completion or cleanup could not be confirmed. This warning is separate from the script's exit code and captured output.

Local SSH private-key conversion

ssh_key converts a private-key file without sending its contents over the network or returning key material in the response. Input is auto-detected as PPK, PEM, PKCS#8, or OpenSSH. The output format is one of ppk, pem, pkcs8, or openssh.

{
  "operation": "convert",
  "input_path": "server.pem",
  "output_path": "server.ppk",
  "output_format": "ppk",
  "input_passphrase": "",
  "output_passphrase": "",
  "overwrite": false
}

PPK output uses version 3. Passphrase-protected PPK output uses Argon2id, AES-256-CBC, and HMAC-SHA-256; protected OpenSSH output uses OpenSSH's modern encrypted format. Traditional PEM and PKCS#8 output are deliberately unencrypted; use openssh or ppk when output encryption is required. New files are mode 0600, and existing files are not replaced unless overwrite=true.

Runtime Configuration

Agents can change settings at runtime via set_config without restarting:

Parameter Description Default
fallback_encoding Fallback encoding when auto-detection fails UTF-8
encoding_warnings Show encoding detection warnings true
max_file_size_mb Max file size for read/edit/grep (MB) 100
allow_symlinks Allow symlink extraction from tar archives false
workspace Explicit local workspace root. Otherwise the first MCP client root is used, then cwd (MCP root/cwd)
allow_http_private Allow webfetch/download/httpreq to access private IPs false
allow_mysql_private Allow mysql tool to access private IPs true
allow_redis_private Allow redis tool to access private IPs true
allow_ssh_private Allow ssh/sftp tools to access private IPs true
enable_doh Enable DNS over HTTPS globally (webfetch/download/httpreq/dnslookup) true
enable_ech Enable Encrypted Client Hello globally (webfetch/download/httpreq) true

Build

go build -trimpath -ldflags="-s -w" -o agent-tool .

Cross-compile:

GOOS=linux GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o agent-tool .
GOOS=darwin GOARCH=arm64 go build -trimpath -ldflags="-s -w" -o agent-tool .
GOOS=windows GOARCH=amd64 go build -trimpath -ldflags="-s -w" -o agent-tool.exe .

Release

The guarded GitHub workflow runs tests, builds all declared assets, creates the MCPB and checksums, and verifies uploaded bytes. From a clean, pushed master branch, dispatch a build-only dry run:

.\scripts\release.ps1

After the dry run succeeds, publish the version declared in main.go:

.\scripts\release.ps1 -Publish

The workflow requires tracked notes at docs/releases/vVERSION.md. Publication creates an annotated tag and GitHub Release, then updates server.json with the released MCPB hash. When RepoPlane uses this repository as its workspace, the same dry-run, publish, and status operations are discoverable through the repository-local catalog/ manifests.

Troubleshooting

Garbled text (encoding issues)

If Korean, Japanese, or other non-ASCII text appears as garbage characters:

Option 1: Add charset to your .editorconfig:

[*]
charset = euc-kr

Option 2: Set environment variable (persistent):

setx AGENT_TOOL_FALLBACK_ENCODING EUC-KR   # Windows
export AGENT_TOOL_FALLBACK_ENCODING=EUC-KR  # Linux

Option 3: CLI flag (per-session):

agent-tool --fallback-encoding EUC-KR

Built-in help for agents

agent-tool includes a agent_tool_help tool that agents can call for usage guidance. When an agent encounters encoding warnings or garbled text, it can call:

{ "tool": "agent_tool_help", "arguments": { "topic": "encoding" } }

Available topics: overview, encoding, indentation, tools, troubleshooting

Security

agent-tool provides powerful system access (SSH, MySQL, Redis, file operations, HTTP requests). When used with AI coding agents, be aware of prompt injection risks:

  • SSRF Protection: Cloud metadata IPs (169.254.x.x, fe80::/10) are always blocked regardless of settings. Private IP access is configurable per protocol via set_config (allow_http_private, allow_mysql_private, allow_redis_private, allow_ssh_private)
  • DLP (Data Loss Prevention): All outbound HTTP request bodies are scanned for sensitive data patterns (PEM private keys, AWS access keys, GitHub/GitLab tokens, Slack tokens, .env file dumps) and blocked before transmission
  • Prompt Injection Warnings: Allowed private IP connections show a compact warning; trusted local SSH/SFTP profiles show it once per pooled connection
  • Zip Slip protection: Archive entries with ../ path traversal are blocked (both zip and tar)
  • Zip Bomb protection: Single file limit (1GB), total extraction limit (5GB)
  • Symlinks: Skipped by default. Enable via set_config allow_symlinks=true (tar only; zip symlinks always skipped). Even when enabled, symlinks targeting outside the output directory are blocked
  • File size limit: Configurable max file size (default 100MB) prevents OOM on large files. Adjustable via set_config max_file_size_mb=N
  • Encoding safety: chardet uses a 64 KiB sample after the ASCII preamble; malformed input is reported before an edit can persist lossy text

For maximum security, review the AI agent's tool calls before approving, especially for SSH commands, HTTP requests to external URLs, and database queries.

Tech Stack

  • Language: Go
  • MCP SDK: github.com/modelcontextprotocol/go-sdk
  • Encoding: saintfish/chardet + golang.org/x/text
  • Distribution: Single binary (cross-compiled)
  • Decompiler: Gosleigh with embedded Ghidra x86/x64 language specs
  • PDB: gopdb (PDB 7.0 reader and MSVC demangler)

License

MIT

The decompiler (Gosleigh) and the Ghidra language specs it embeds are licensed under the Apache License 2.0; Gosleigh is a reimplementation of the Ghidra decompiler, developed by the National Security Agency (https://github.com/NationalSecurityAgency/ghidra).

About

MCP tool server for AI coding agents -- encoding-aware file tools, binary analysis, DAP debugger, SSH/SFTP, process memory, and more

Topics

Resources

Stars

24 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages