Use stetdoc with your agent
Opens the app with a prompt to read this page.
stetdoc is one binary and one skill. The skill teaches an agent to find text in a .docx with stetdoc view --find,
change it with stetdoc replace, comment with stetdoc comment, and use a batch of operations or a working copy for
the rest, all as real tracked changes. Any agent with a shell can use it that way.
Agents that take tools rather than a shell can use stetdoc mcp, which serves the same commands over the Model Context
Protocol. Claude Code uses the command and the skill, not MCP.
This page covers the one command that installs the skill, and then each agent. For each agent it says where the skill goes, how to register the MCP server if the agent uses one, and how to check that the agent sees it. Each section links the agent's own docs, which were read on 2026-10-11. Agents change their folders and config files, so trust their docs over this page when the two disagree.
Agents: Claude Code · Codex · Cursor · OpenCode · OpenClaw · Hermes Agent · Grok · cmx2 · Antigravity CLI · GitHub Copilot CLI · Amp · Factory · Dots · Cloud apps · Gemini CLI, retired
Install stetdoc
Install stetdoc first. Install lists every channel. Then run stetdoc init.
The one command
# the skill stub in your home folder, for the agents you pick
stetdoc init
# the skill stub in this project, plus a short block in AGENTS.md
stetdoc init --projectIn a terminal, init asks which agents to install for. Otherwise it installs for the agents it detects. --agent
names them instead, such as --agent claude-code,codex or --agent all. --dry-run lists what it would write and
changes nothing. Running it again is safe: a file with the same bytes is left as it is.
The stub is short. It carries the everyday commands (find, replace, comment, compare), which cover a simple task, and
tells the agent to run stetdoc skills get core for anything more, which prints the full skill embedded in the binary,
so the skill always matches the version you run. In Claude Code the stub sends the agent straight to the command. In
another agent with stetdoc's MCP tools, it sends the agent to the skills_get tool instead.
# each agent, whether it is detected, its skill folder, and the stetdoc version there
stetdoc init --list
# also print how to register `stetdoc mcp` with each agent
stetdoc init --mcp
# remove the skill folders stetdoc wrote, and nothing else
stetdoc init --removeinit never edits an agent's own config. --mcp prints the line to add, and the sections below give the same lines.
This is the real output of stetdoc init --agent all --mcp --dry-run in an empty home folder:
would write ~/.claude/skills/stetdoc/SKILL.md (Claude Code)
would write ~/.agents/skills/stetdoc/SKILL.md (Codex, Cursor, OpenCode, OpenClaw, Gemini CLI, GitHub Copilot CLI, Amp)
would write ~/.gemini/config/skills/stetdoc/SKILL.md (Antigravity CLI)
would write ~/.hermes/skills/stetdoc/SKILL.md (Hermes Agent)
would write ~/.grok/skills/stetdoc/SKILL.md (Grok Build)
would write ~/.config/cmx2/skills/stetdoc/SKILL.md (cmx2)
would write ~/.factory/skills/stetdoc/SKILL.md (Factory Droid)
To use stetdoc as an MCP server as well, keep the skill installed with it: without the skill, an agent whose MCP server fails to start may edit the .docx's XML itself.
Register `stetdoc mcp` with each agent (init edits no agent's config):
Claude Code: claude mcp add --scope user stetdoc -- stetdoc mcp
Codex: codex mcp add stetdoc -- stetdoc mcp
Cursor: in ~/.cursor/mcp.json: { "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } }
OpenCode: in ~/.config/opencode/opencode.json: { "mcp": { "stetdoc": { "type": "local", "command": ["stetdoc", "mcp"], "enabled": true } } }
OpenClaw: openclaw mcp add stetdoc --command stetdoc --arg mcp (or in ~/.openclaw/openclaw.json: { "mcp": { "servers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } } })
Gemini CLI: in ~/.gemini/settings.json: { "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } }
Antigravity CLI: agy mcp add stetdoc stetdoc mcp (or in ~/.gemini/config/mcp_config.json: { "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } })
GitHub Copilot CLI: in ~/.copilot/mcp-config.json: { "mcpServers": { "stetdoc": { "type": "local", "command": "stetdoc", "args": ["mcp"], "tools": ["*"] } } }
Amp: amp mcp add stetdoc -- stetdoc mcp
Hermes Agent: in ~/.hermes/config.yaml: mcp_servers: { stetdoc: { command: stetdoc, args: [mcp] } }
Grok Build: grok mcp add stetdoc -- stetdoc mcp
cmx2: in ~/.config/cmx2/cmx2.jsonc: "mcp": { "stetdoc": { "command": ["stetdoc", "mcp"] } }
Factory Droid: in ~/.factory/mcp.json: { "mcpServers": { "stetdoc": { "type": "stdio", "command": "stetdoc", "args": ["mcp"] } } }Several agents read the shared folder ~/.agents/skills (.agents/skills in a project) and their own folder or
~/.claude/skills too, so an agent may list the stub more than once. The copies are identical, and init prints a note
for each agent this applies to.
The author
Every revision carries an author, and stetdoc never makes one up. In a terminal, stetdoc init asks for your name once,
suggesting your git user.name, and saves the answer to stetdoc/config.toml in your config folder (XDG_CONFIG_HOME,
else %APPDATA% on Windows, else ~/.config). stetdoc init --author "Your Name" saves it without asking, and
stetdoc init --list shows the saved name. Without a terminal and without --author, init saves nothing and says how
to set one.
When a command writes revisions, the author is the first of:
--authoron the command line, or theauthorargument of an MCP tool call (stetdoc mcp --authorsets it for every call that names none),STETDOC_AUTHORin the environment,- the name saved with
stetdoc init.
With none of them, the command fails and says to run stetdoc init. Git and the operating system are never asked at
edit time: the git name is only a suggestion in init's question.
What init replaces and removes
A SKILL.md counts as stetdoc's only when it is a stub that some stetdoc build wrote, unchanged. init replaces such a
stub freely. Anything else, such as a stub you edited, your own skill named stetdoc, or a SKILL.md that is a link, is
replaced only with --force. Without it, init refuses and writes nothing.
--remove deletes a skill folder only when it holds nothing but an unchanged stub, and never its parent. It never removes
anything else, even with --force. When you name an agent with --agent and its folder fails that test, nothing is
removed. Without --agent, every agent's folder is tried and the others are left with a note. In a project, the
AGENTS.md block goes too. --remove leaves the saved author alone.
A note on MCP
Install the skill together with the MCP server, or a plugin that carries both, rather than the server alone. The skill
tells the agent which surface to use: the stetdoc command in Claude Code, elsewhere the MCP tools when they are there,
else the command. When neither works,
it tells the agent to say that stetdoc is not installed and stop. Without the skill, an agent whose MCP server fails to
start has nothing that keeps it away from the package, and in testing it fell back to unzipping the .docx and reading its
XML with its own scripts.
stetdoc mcp speaks MCP on stdin and stdout. Every snippet below runs it as a local stdio server. On your own machine
the server finds the author you saved with stetdoc init, so the snippets need nothing more. To use another name for one
agent, add --author "Name" after mcp in its snippet. Before the binary is on the PATH, npx stetdoc mcp works in
place of stetdoc mcp.
Claude Code
-
Skill:
~/, or.claude/ skills/ stetdoc/ SKILL.md .claude/in a project.skills/ stetdoc/ SKILL.md stetdoc init --agent claude-codewrites it. -
Or the plugin: it carries the skill and the guard hook (the binary must still be on the PATH). It has no MCP server: in Claude Code the command and the skill are the route. Claude Code keeps MCP tools behind its tool search, so with both an agent switched between them and the command, and the server is the same binary, so it is no fallback when the command is missing. In a session of Claude Code 2.1.275 or later, one line installs it:
/plugin install stetdoc --marketplace clauseo-ai/stetdocOn any version, two commands from the shell do the same:
claude plugin marketplace add clauseo-ai/stetdoc claude plugin install stetdoc@stetdoc -
MCP: not needed, and the command works better. If you want it anyway:
claude mcp add --scope user stetdoc -- stetdoc mcp, or--scope projectfor a project. -
Check: type
/stetdocin a session to load the skill./hookslists the plugin's PreToolUse hook. -
Docs: skills (opens another site), hooks (opens another site), plugins (opens another site).
The Claude Code guard hook
When stetdoc is missing, or its view does not answer a question, an agent may reach for the package itself: unzip the
.docx and read or rewrite word/document.xml with a script. Such an edit is not a tracked change, and it can break the
file. The plugin carries a PreToolUse hook, plugins/, that blocks those tool calls and tells
the agent to use stetdoc, or to tell the user stetdoc is not installed. It needs only sh and awk, never stetdoc.
It blocks:
- an archive tool (
unzip,zip,zipinfo,ditto,tar,bsdtar,7z,jar,unar,Expand-Archiveand the like) in a command that names a .docx, .docm, .dotx or .dotm file; - a script (
python,node,ruby,perl,php,osascriptand the like) run on such a file, and zip code (zipfile,JSZip,adm-zip,Archive::Zip,java.util.zip) in a command that names one; - a library that reads or writes .docx files directly, used or installed:
python-docx(import docx),docx2python,docx2txt,mammoth,docxtpl, thedocxnpm package,docxtemplater, Apache POI, Open XML SDK and Aspose; - a conversion with
textutil,pandoc,sofficeorlibreofficein a command that names a Word file; - copying a Word file to a
.zipname,sed -iorperl -ion a Word file or an unzipped part, andddorxxdon a Word file; - reading or writing an unzipped part (
word/*.xml,document.xml,[Content_Types].xml) with a script,sed,awk,cat,xmllintor a redirection; - the Write, Edit, MultiEdit and NotebookEdit tools on a Word file or an unzipped part, and a script written to
/tmpthat takes a Word file apart.
It allows every stetdoc command, whatever its arguments or here-document say, and commands that only list, copy, move,
hash or open a Word file (ls, cp, mv, shasum, open, file, rm). git and gh commands are not checked,
because their messages are prose. When it is unsure, it allows: it reads the command, not what a script file holds, so a
script written earlier inside the project and run without naming a Word file passes. STETDOC_GUARD=off in Claude Code's
environment turns it off.
Without the plugin, add the hook to a skill install: save the script, then add it to ~/.claude/settings.json (or a
project's .claude/settings.json). stetdoc init --agent claude-code points here.
mkdir -p ~/.claude/hooks
curl -fsSL -o ~/.claude/hooks/stetdoc-docx-guard.sh \
https://raw.githubusercontent.com/clauseo-ai/stetdoc/main/plugins/claude/hooks/docx-guard.sh{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|PowerShell|Write|Edit|MultiEdit|NotebookEdit",
"hooks": [{ "type": "command", "command": "sh ~/.claude/hooks/stetdoc-docx-guard.sh", "timeout": 30 }]
}
]
}
}Codex
- Skill:
~/, or.agents/ skills/ stetdoc/ SKILL.md .agents/in a repository.skills/ stetdoc/ SKILL.md - MCP:
codex mcp add stetdoc -- stetdoc mcp. It writes[mcp_servers.stetdoc]in~/.codex/config.toml. - Check:
/skillsin a session, or type$to mention a skill.codex mcp list, or/mcpin a session. - Docs: skills (opens another site), MCP (opens another site).
Cursor
-
Skill:
~/, or.agents/ skills/ stetdoc/ SKILL.md .agents/in a project. Cursor also readsskills/ stetdoc/ SKILL.md ~/.cursor/skillsand the Claude and Codex folders. -
MCP: in
~/.cursor/mcp.json, or.cursor/mcp.jsonin a project:json{ "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } } -
Check: open Customize in the sidebar. Skills lists the stub, and MCP lists the server.
-
Docs: skills (opens another site), MCP (opens another site).
OpenCode
-
Skill:
~/, or.agents/ skills/ stetdoc/ SKILL.md .agents/in a project. OpenCode also readsskills/ stetdoc/ SKILL.md .claude/skills, so it sees the Claude Code copy as well. -
MCP: in
~/, or.config/ opencode/ opencode.json opencode.jsonin a project:json{ "mcp": { "stetdoc": { "type": "local", "command": ["stetdoc", "mcp"], "enabled": true } } } -
Check: ask the agent which skills it has. OpenCode lists them in its
skilltool.opencode mcp listshows the server. -
Docs: skills (opens another site), MCP servers (opens another site).
OpenClaw
-
Skill:
~/. OpenClaw reads this folder in its default state. A workspace's own.agents/ skills/ stetdoc/ SKILL.md skills/folder comes first, and~/.openclaw/skillsis also read. -
MCP:
openclaw mcp add stetdoc --command stetdoc --arg mcp, or by hand in~/.openclaw/openclaw.json:json{ "mcp": { "servers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } } } -
Check:
openclaw skills list --eligiblelists the stub.openclaw mcp probe stetdocconnects and lists the tools. -
Docs: skills (opens another site), MCP (opens another site).
Hermes Agent
-
Skill:
~/, or.hermes/ skills/ stetdoc/ SKILL.md .hermes/in a project. Hermes reads a project's skills only after you runskills/ stetdoc/ SKILL.md hermes skills trustthere, and then it reads.agents/skillstoo. -
MCP: in
~/.hermes/config.yaml:yamlmcp_servers: stetdoc: command: stetdoc args: [mcp] -
Check:
hermes skills list. Each skill is also a slash command, so/stetdocworks in a session. After an MCP change, run/reload-mcpor start a new session. -
Docs: skills (opens another site), MCP (opens another site).
Grok
Grok Build (the CLI):
- Skill:
~/, or.grok/ skills/ stetdoc/ SKILL.md .grok/in a project.skills/ stetdoc/ SKILL.md - MCP:
grok mcp add stetdoc -- stetdoc mcp. Add--scope projectto write.grok/config.tomlinstead. - Check:
/skillsor/mcpsin the TUI.grok mcp listandgrok mcp doctor stetdocfrom the shell. - Docs: skills, plugins and marketplaces (opens another site), MCP servers (opens another site).
Grok Bot works from its own persistent cloud computer with a command line, so it can install stetdoc there itself.
Ask it to run the install script, then stetdoc init --agent grok or stetdoc skills get core before it works on a
.docx. The files it edits live on that cloud computer, so upload the document to it and download the result. Docs: computer and apps (opens another site).
cmx2
-
Skill:
~/, or.config/ cmx2/ skills/ stetdoc/ SKILL.md .cmx2/in a project. cmx2 also readsskills/ stetdoc/ SKILL.md ~/.agents/skillsand~/.claude/skills. -
MCP: under
mcpin~/.config/cmx2/cmx2.jsonc:jsonc"mcp": { "stetdoc": { "command": ["stetdoc", "mcp"] } } -
Check:
cmx2 mcplists each server with its status and tool count. The tools appear in sessions asstetdoc_<tool>. Ask a session which skills it has to see the stub. -
Docs:
cmx2 mcp --help. These folders were read from cmx2 0.8.11.
Antigravity CLI
Antigravity CLI (agy) is Google's terminal agent, which replaced Gemini CLI. init detects it by agy on the PATH,
or by ~/.gemini/antigravity-cli or ~/.gemini/antigravity.
-
Skill:
~/, or.gemini/ config/ skills/ stetdoc/ SKILL.md .agents/in a workspace. Antigravity CLI, the Antigravity app and the Antigravity IDE all readskills/ stetdoc/ SKILL.md ~/.gemini/config/skills. The CLI's own docs name~/too, which only the CLI and the IDE read. Antigravity CLI 1.4.8 does not read.gemini/ antigravity-cli/ skills ~/.agents/skills, as a test showed. It readsAGENTS.mdandGEMINI.mdalike, sostetdoc init --project's block inAGENTS.mdreaches it. -
MCP: in
~/, which the CLI, the app and the IDE share:.gemini/ config/ mcp_config.json json{ "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } }agy mcp add stetdoc stetdoc mcpwrites the same entry. For a stetdoc server you host yourself (see self-hosting the MCP server), give its address asserverUrl, noturl, which Antigravity ignores (agy mcp add --header "Authorization: Bearer TOKEN" stetdoc https://writes it):stetdoc.example.com/ mcp json{ "mcpServers": { "stetdoc": { "serverUrl": "https://stetdoc.example.com/mcp", "headers": { "Authorization": "Bearer TOKEN" } } } }The docs also name a workspace file,
.agents/mcp_config.json, but Antigravity CLI reads it and then ignores its servers (antigravity-cli#60 (on GitHub)), soinit --project --mcpprints the global file too. -
Check:
/skillsin a session lists the skills and where each comes from./mcpopens the MCP manager. -
Docs: skills (opens another site), MCP (opens another site), read on 2026-10-27.
Gemini CLI (retired)
Google retired Gemini CLI on 18 June 2026 in favour of Antigravity CLI (see above). init keeps it for those who still
run it, and says so when it is picked. Install for Antigravity with stetdoc init --agent antigravity.
-
Skill:
~/(Gemini CLI reads it as an alias of.agents/ skills/ stetdoc/ SKILL.md ~/.gemini/skills), or.agents/in a workspace.skills/ stetdoc/ SKILL.md -
MCP: in
~/.gemini/settings.json, or.gemini/settings.jsonin a project:json{ "mcpServers": { "stetdoc": { "command": "stetdoc", "args": ["mcp"] } } }gemini mcp add stetdoc stetdoc mcpwrites the same entry. -
Check:
/skills listin a session, orgemini skills list --all.gemini mcp list, or/mcpin a session. -
Docs: skills (opens another site), MCP servers (opens another site).
GitHub Copilot CLI
-
Skill:
~/(Copilot also reads.agents/ skills/ stetdoc/ SKILL.md ~/.copilot/skills), or.agents/in a repository.skills/ stetdoc/ SKILL.md -
MCP: in
~/.copilot/mcp-config.json:json{ "mcpServers": { "stetdoc": { "type": "local", "command": "stetdoc", "args": ["mcp"], "tools": ["*"] } } }copilot mcp add stetdoc -- stetdoc mcpwrites it for you. -
Check:
/mcp listor/mcp show stetdocin a session. Ask the agent which skills it has to see the stub. -
Docs: skills (opens another site), MCP servers (opens another site).
Amp
- Skill:
~/, or.agents/ skills/ stetdoc/ SKILL.md .agents/in a project.skills/ stetdoc/ SKILL.md - MCP:
amp mcp add stetdoc -- stetdoc mcp. - Check: ask the agent which skills and tools it has.
- Docs: skills (opens another site), MCP (opens another site).
Factory
-
Skill:
~/, or.factory/ skills/ stetdoc/ SKILL.md .factory/in a repository. Droid also readsskills/ stetdoc/ SKILL.md ~/.agents/skills. -
MCP: in
~/.factory/mcp.json, or.factory/mcp.jsonin a project:json{ "mcpServers": { "stetdoc": { "type": "stdio", "command": "stetdoc", "args": ["mcp"] } } }droid mcp add stetdoc stetdoc mcpwrites a stdio server as well. -
Check:
/mcpin a session shows the server. Ask the agent which skills it has to see the stub. -
Docs: skills (opens another site), MCP (opens another site).
Dots (ChatGPT desktop)
A dot has its own cloud computer. With local computer access turned on in the ChatGPT desktop app on your machine, it
can work on that computer's files and use local skills. So install stetdoc on the connected computer and run stetdoc init there. OpenAI's article does not name the folder a dot reads skills from. The Codex folder, ~/.agents/skills, is
the likely one, because a dot starts Codex tasks, but this is not confirmed. The article does not mention MCP. Docs:
OpenAI help article 20001530 (opens another site).
Cloud apps
Apps that run entirely in the cloud have no shell on your machine and cannot start stetdoc mcp themselves. Claude
Cowork, ChatGPT on the web, grok.com and a dot without a connected computer can use stetdoc only through a remote MCP
server that you host and add as a custom connector, where the app allows one. stetdoc ships no hosted service.
Self-hosting the MCP server shows how to run one.
Meta's Muse has no route for third-party tools today.
Building a product on stetdoc
To call stetdoc from your own code rather than through an agent, see Build on stetdoc.