Free and open source, MIT

Steering files, checked before the agent reads them.

A Claude Code plugin and MCP server that read, outline, lint and budget your SKILL.md, CLAUDE.md, AGENTS.md and rule files, with no ability to change any of them. An optional hook warns when the agent is about to rewrite a markdown file in ways you did not ask for.

Install

Requires Claude Code and Node 22.13 or later on your PATH. The plugin is public on GitHub and installs from there:

claude plugin marketplace add Katta041/asitis-agent-tools
claude plugin install asitis@asitis

Inside a session, /plugin marketplace add Katta041/asitis-agent-tools and /plugin install asitis@asitis do the same. Remove it with claude plugin marketplace remove asitis.

Other MCP clients (Claude Desktop, Cursor, Codex, Gemini CLI)

npm package coming soon. @asitis/mcp is not on npm yet. Until it is, run the server from a clone of the repository. The built, pinned server is already in the plugin folder, so there is no install or build step.

git clone https://github.com/Katta041/asitis-agent-tools.git
node asitis-agent-tools/plugins/asitis/server/asitis-mcp.mjs --version

Use node as the command, the absolute path to plugins/asitis/server/asitis-mcp.mjs as the first argument, and an absolute --root for the project. For example, in Claude Desktop's claude_desktop_config.json or Gemini CLI's settings.json:

{
  "mcpServers": {
    "asitis": {
      "command": "node",
      "args": [
        "/absolute/path/to/asitis-agent-tools/plugins/asitis/server/asitis-mcp.mjs",
        "--root", "/absolute/path/to/project"
      ]
    }
  }
}

Cursor and Codex configs are in the repository README. Once the package is on npm, the same configs will use npx -y @asitis/mcp@0.1.0 (always pinned, never @latest).

The five tools

The server is read-only: there is no write, patch or delete tool and no write code in it. Every tool is annotated readOnlyHint: true.

read_markdown
The file text exactly as stored, plus a byte profile: encoding, BOM, CRLF, LF and CR counts, final newline, trailing whitespace, invalid UTF-8 ranges and a SHA-256. File content is labelled as data, not instructions, and hidden characters and comments are summarised up front.
outline
Headings with line numbers, skipping frontmatter and fenced code.
lint_steering
Frontmatter on line 1 and valid YAML; required name and description for SKILL.md and subagents; unknown keys; length against vendor limits; broken relative links and @path imports; zero-width and bidirectional characters; hidden HTML comments that read like instructions; text hidden with inline styles; duplicate and contradictory-looking rules. With no path it lints every steering file in the folder.
context_budget
Approximate tokens per file and per tool for what loads every session: Claude Code (CLAUDE.md plus @imports, rules, MEMORY.md, the skill and subagent listing), Codex, Gemini CLI, Cursor and Copilot. Token counts are local estimates, not any vendor's tokenizer.
find_steering_files
Every steering file in the project, grouped by when it loads: every session, on match, on invocation, on demand, memory.

Limits follow the vendors' public docs, with sources cited in the repository. Examples: SKILL.md under 500 lines with description at most 1,024 characters; MEMORY.md loads its first 200 lines; Codex reads 32 KiB of AGENTS.md; Windsurf rules are capped at 12,000 characters.

What else is in the plugin

  • Skill markdown-byte-clean: teaches Claude to edit minimal ranges and never rewrite a whole markdown file, keeping frontmatter, line endings, BOM and trailing spaces as they are.
  • /asitis:md-lint [path]: lint one file or every steering file in the project.
  • /asitis:md-budget [path]: what your steering files cost per session, and what to cut.

The guard hook

An optional PreToolUse hook on Write, Edit and MultiEdit. For an existing markdown file it warns when the change would convert line endings, strip trailing whitespace (two trailing spaces are a hard line break), add or remove the BOM, drop the final newline, move or break the frontmatter, rewrite more than 30% of a file of more than 20 lines, or touch a file with invalid UTF-8.

Set the guard_mode plugin option: ask (default) shows the warning and asks you to allow or reject, deny blocks the change and tells Claude to retry with a minimal edit, off disables it. If the hook input is malformed it fails closed with a one-line message; set guard_mode to off if that gets in your way.

It is an accident guard, not a security boundary. It does not see Bash (sed -i, redirects, scripts) or other programs, and anything running as you can bypass it.

Privacy statement

  • No network. The server and the hook make no connections, contain no network code, collect nothing and send nothing. No telemetry, no update check.
  • No writes. They never write, rename or delete a file and create no temp files. The server logs one start-up line to stderr (version and root folder), never file content.
  • One folder. Every path is resolved with realpath and must stay inside the root you start the server with. Traversal and symlinks that resolve outside are refused. Only markdown files are read: .env*, .claude/settings*.json, .git/ and every other file type are refused.
  • Enforced by Node. In the plugin the server runs under Node's permission model, with read access to the plugin and your project only, and no write, network or child-process rights.
  • Pinned. The plugin never downloads the server at runtime. The bundled file's SHA-256 is recorded in the repository and a test fails if it differs from a fresh build.
  • Your assistant's traffic is not ours. Tool results go into the model's context, so they reach whichever AI provider your assistant uses.

Each tool result ends with one line linking to asitis.app. Turn it off with the footer plugin option or --no-footer.

Source, changelog and security policy: https://github.com/Katta041/asitis-agent-tools. Report vulnerabilities privately through the repository's security policy.