Coming from Claude Code
Tatu reads several of Claude Code’s file formats on purpose, so a good part of what you wrote for Claude Code works here. This page says which part, what to change in the rest, and what does not exist.
The short version: Tatu never reads the .claude folders. You copy files into ~/.tatu or .tatu/. After that, CLAUDE.md files and their @path imports work as they are, skills work as they are, hooks work once you move them into Tatu’s settings and change the tool names, and subagents and slash commands need a small edit. A .mcp.json works as it is. Permissions and plugins do not exist.
At a glance
Section titled “At a glance”| What you have | In Tatu | Status |
|---|---|---|
CLAUDE.md in the project |
read as instructions | works as it is |
@path imports inside a CLAUDE.md |
read the same way, relative to the file that holds them, up to four levels | works as it is |
~/.claude/CLAUDE.md |
not read; copy it to ~/.tatu/AGENTS.md or ~/.tatu/CLAUDE.md |
copy |
.claude/skills/<name>/SKILL.md |
.tatu/skills/<name>/SKILL.md |
works after you copy it |
.claude/commands/*.md |
.tatu/prompts/*.md |
works after you copy it, if it uses only the fields below |
.claude/agents/*.md |
.tatu/agents/*.md |
needs tools and model changed |
hooks in .claude/settings.json |
hooks in .tatu/settings.json |
needs the tool names changed |
the rest of settings.json (permissions, env, …) |
none | does not exist; it is an error |
.mcp.json in the project |
read from the project folder; you trust the project once with /mcp trust |
works as it is |
mcpServers of ~/.claude.json |
~/.tatu/mcp.json |
works after you copy it |
| permissions, plugins | none | does not exist |
Instructions: CLAUDE.md
Section titled “Instructions: CLAUDE.md”Tatu reads AGENTS.md, and in a folder that has none it reads CLAUDE.md. It looks in ~/.tatu, in the folder you start in and in each parent folder, and in a subfolder when the model first reads or changes a file there. See AGENTS.md and /init.
What is different:
~/.claude/CLAUDE.mdand.claude/CLAUDE.mdare not read. Put the file in the project’s root, or your personal one at~/.tatu/AGENTS.md.@pathimports work as in Claude Code: a relative path is relative to the file that holds the reference,~is your home folder, and imports nest up to four levels. A path in backticks is not imported. Each imported file becomes a section of its own right after the file that imports it. See AGENTS.md and /init.- If a folder has both files, Tatu uses
AGENTS.mdand ignoresCLAUDE.md, so aCLAUDE.mdthat only says@AGENTS.mdis unnecessary. - It does not read
CLAUDE.mdfiles in folders below the one you started in.
Skills
Section titled “Skills”Tatu uses the same layout: a folder with a SKILL.md. The fields name, description, disable-model-invocation and user-invocable mean the same here as they do in Claude Code. See Skills.
Copy the skills into Tatu’s folders:
mkdir -p ~/.tatu/skillscp -R ~/.claude/skills/. ~/.tatu/skills/For a project, copy .claude/skills into .tatu/skills in the same way.
What is different:
- Every other field in the front matter is ignored without an error:
allowed-tools,argument-hint,model,context,hooksand the rest. A skill that Claude Code limits withallowed-toolshas no such limit in Tatu, because Tatu has no permissions. - The front matter is read by a small parser:
key: valuelines, quoted text,trueandfalse, and>or|blocks. Indented lines under a key are skipped, so nested values are fine. A list written with- itemat the left margin, under a key, makes Tatu ignore the whole skill, with a note at startup (frontmatter: line without a key). Indent the list, or delete the field. - Tatu fills in
$1,$2,$@,$ARGUMENTS,${1:-fallback}and${@:2}. The rest of the body is sent as written, including any command snippets: Tatu does not run anything in a skill itself. - A skill without a
descriptionis ignored.
Slash commands
Section titled “Slash commands”Files from .claude/commands/ have the shape of a prompt template: a Markdown file whose name is the command, with description and argument-hint in the front matter. Copy them to ~/.tatu/prompts/ (or .tatu/prompts/ in a project):
mkdir -p ~/.tatu/promptscp ~/.claude/commands/*.md ~/.tatu/prompts/Only files directly in the folder are read, so commands that you grouped in subfolders must be moved up. Other front matter fields (allowed-tools, model) are ignored. Tatu fills in $ARGUMENTS, $1, $2 and the other placeholders listed in the prompt templates page; any other text is sent as written.
The hook format is the same: a hooks object with the event, a matcher, and a list of { "type": "command", "command": "...", "timeout": ... }. The input on standard input and the answers are the same too: session_id, cwd, hook_event_name, tool_name, tool_input, tool_use_id in; exit code 2 to block; hookSpecificOutput with updatedInput, permissionDecision: "deny" and additionalContext, or decision: "block", out. See Hooks.
The proof is the hook of RTK, which was written for Claude Code. Its rtk hook claude command works in Tatu without changes, and a test of Tatu runs it for real against a bash call. So “mostly work as they are” means this: the format and the protocol are the same, and you move the hooks and adjust a few things.
What you must change:
-
Move the
hooksobject. Hooks go in~/.tatu/settings.jsonor.tatu/settings.json, not in.claude/settings.json. Copy only thehooksobject. Tatu stops with an error on any key it does not know, so a whole Claude Code settings file does not load:tatu: /home/ana/project/.tatu/settings.json: json: unknown field "permissions" -
Write the tool names in lowercase, as Tatu names them. A matcher must match the whole tool name and is case-sensitive, so a matcher
"Bash"never matches Tatu’sbash: the hook is loaded and never runs. A script that teststool_name == "Bash"has the same problem.Claude Code Tatu BashbashReadreadWritewriteEditeditGrepgrepGlobfindAgentagentWebSearchweb_searchWebFetchweb_fetch -
Check the keys of
tool_input. They are Tatu’s own arguments. Forread,writeandeditthe file ispath, notfile_path, andedittakes a list ofedits. Forbashthe keys arecommandandtimeout, in seconds. See Tools of the model. -
Use
TATU_PROJECT_DIR. Tatu setsTATU_PROJECT_DIRandTATU_SESSION_IDfor a hook. It does not setCLAUDE_PROJECT_DIR. The input also has notranscript_pathorpermission_mode. -
Set a
timeoutif you care. The default is 60 seconds.
What Tatu rejects, and so stops with an error when it starts:
-
an event other than
PreToolUse,PostToolUse,SessionStart,UserPromptSubmitandStop, for exampleSubagentStoporNotification:tatu: /home/ana/project/.tatu/settings.json: hooks: unknown event "SubagentStop" (use one of: PreToolUse, PostToolUse, SessionStart, UserPromptSubmit, Stop) -
a hook
typeother thancommand, and extra fields on a hook, such asif:tatu: /home/ana/project/.tatu/settings.json: json: unknown field "if" -
a matcher other than empty or
*onUserPromptSubmitorStop.
Remove those entries from the copy. JSON fields in a hook’s answer that Tatu does not know are ignored.
Subagents
Section titled “Subagents”Files from .claude/agents/ have the same shape as custom subagents: description (required), tools, model, and the body as the instructions. Two fields usually need a change:
toolsuses Tatu’s lowercase names, soRead, Grep, Glob, Bashbecomesread, grep, find, bash. Names that Tatu does not know are ignored; if none is known, the subagent does not start.modeltakesfast,balanced,main,inheritorprovider/model. A value such assonnetoropusmakes Tatu skip the file, with a note at startup. Usebalancedoranthropic/claude-sonnet-5-5, for example.
Other fields are ignored.
MCP servers
Section titled “MCP servers”The mcpServers object of a .mcp.json file has the same shape here, so the file works as it is: command, args, env for a local server, type and url and headers for a remote one, and ${VAR} in the values. Tatu reads .mcp.json in the folder you start in (not in parent folders) and ~/.tatu/mcp.json. What is different:
-
Tatu does not ask about each server. The servers of a project’s
.mcp.jsonstart only after you trust the project once, with/mcp trust. -
A server starts when the model first uses one of its tools, not when Tatu starts.
-
A server of
"type": "sse"is not supported: use the server’s streamable HTTP address. -
Tatu uses the tools of a server. It does not use its resources or prompts.
-
The command that adds a server works with
tatuin place ofclaude:claude mcp add --transport http sentry https://mcp.sentry.dev/mcpbecomestatu mcp add --transport http sentry https://mcp.sentry.dev/mcp. The scopeusermeans the same asglobalhere, andlocalis alsoglobal, with a note: Tatu has no scope for one folder.-s projectwrites.mcp.json.tatu mcp add-json,remove,listandgetare there too.
See MCP servers.
Settings
Section titled “Settings”The files and the keys are different, and Tatu does not read .claude/settings.json. Unknown keys are an error. See Settings and the settings reference. MCP servers are not a setting: they have files of their own. There is no setting for plugins.
See also
Section titled “See also”- Hooks: the full list of events and answers.
- Skills
- MCP servers
- Settings
- Security and trust