Configuration · MCP · Skills · Memory

Configure Reasonix
in five minutes

One JSON file at ~/.reasonix/config.json + per-project overrides under .reasonix/. This page documents every key, every slash command, and the on-disk shape of skills, memory, and hooks.

The config.json file

Reasonix reads a single global config from ~/.reasonix/config.json (Windows: %USERPROFILE%\.reasonix\config.json). The file is created automatically on first run; you can hand-edit it any time. The CLI flag --no-config bypasses it, useful in CI.

Per-project overrides live under <project>/.reasonix/ — skills, memory, settings.json (hooks). Project scope wins over global on name collision.

Top-level keys

{
  "apiKey": "sk-...",
  "baseUrl": "https://api.deepseek.com",
  "lang": "en",                       # UI language: en | zh
  "preset": "auto",                   # auto | flash | pro
  "editMode": "review",               # review | auto | yolo
  "reasoningEffort": "high",          # high | max
  "theme": "auto",                    # light | dark | auto
  "search": false,                    # enable web_search/web_fetch tools
  "webSearchEngine": "mojeek",        # mojeek | searxng
  "webSearchEndpoint": "http://localhost:8080",
  "mcp": [],                          # MCP server specs
  "mcpDisabled": [],                  # names skipped at startup
  "projects": {                       # per-workspace overrides
    "/abs/path": {
      "shellAllowed": ["npm", "git status"]
    }
  },
  "semantic": { ... },                # embedding provider for `reasonix index`
  "session": null
}
Trust dial

editMode is the single trust dial for an entire session. review queues edits + gates shell. auto applies edits + still gates shell. yolo skips both gates — only use inside a sandbox.

MCP servers

Reasonix speaks the Model Context Protocol natively. Every entry in config.mcp is a single string — the same format the --mcp CLI flag accepts — so one parser handles both. Three transports are supported.

Stdio (subprocess)

{
  "mcp": [
    "fs=npx -y @modelcontextprotocol/server-filesystem /tmp",
    "git=uvx mcp-server-git --repository ."
  ]
}

Format: name=command arg1 arg2. The name= prefix namespaces every tool the server exposes. Args use shell-style splitting; quote any with spaces.

SSE (HTTP)

{
  "mcp": [
    "remote=https://example.com/mcp/sse",
    "https://other.example.com/mcp"
  ]
}

Plain http:// / https:// URLs use HTTP+SSE for back-compat. Anonymous (no name=) entries work but can't be toggled by name later.

Streamable HTTP (2025-03 spec)

{
  "mcp": [
    "edge=streamable+https://edge.example.com/mcp"
  ]
}

Opt in with the streamable+ URL prefix.

CLI flags & slash commands

npx reasonix code --mcp "fs=npx -y @mcp/server-filesystem /tmp"
npx reasonix mcp inspect "git=uvx mcp-server-git"
npx reasonix mcp list
Command What it does
/mcp Open the interactive MCP hub.
/mcp disable <name> Persist to mcpDisabled; effective on next launch.
/mcp enable <name> Re-enable a disabled server.
/mcp reconnect <name> Reconnect a live server and pick up newly-registered tools.

Skills

A skill is a markdown playbook the model can invoke (/skill <name>). Names + descriptions are pinned in the prompt; bodies load on demand. Project skills override global ones with the same name.

Layout

~/.reasonix/skills/           # global
  audit-logs.md
  refactor-react/
    SKILL.md

<project>/.reasonix/skills/    # project (overrides global)
  release-notes.md

Two equivalent shapes: a flat <name>.md, or a <name>/SKILL.md folder when you want to colocate attachments.

Frontmatter

---
name: audit-logs
description: Review git log for security red flags.
runAs: inline                  # inline | subagent
allowed-tools: bash,read       # subagent tool allowlist
model: deepseek-chat           # subagent model override
---

## Task

1. Fetch the last 20 commits.
2. Flag commits whose message mentions password / secret / token.
3. Report findings.
  • name 1–64 chars: alnum, _, -, interior .. Defaults to filename stem.
  • description One line. Shown in /skill list.
  • runAs inline (default): body enters parent log. subagent: isolated child loop, only the final answer returns.
  • allowed-tools Comma-separated literal tool names. Subagent only — scopes the child's tool registry.
  • model Subagent only. Must start with deepseek-; ignored otherwise.

Slash commands

/skill list List every skill, scope-tagged.
/skill new <name> Scaffold a stub at project scope. Add --global for ~/.reasonix/skills.
/skill show <name> Print the full body.
/skill <name> [args] Run it. Args are appended to the body as a single string.

Memory

Memory is user-private knowledge pinned into the immutable prefix — so the agent reads it on every turn without re-priming. Two scopes: global (cross-project facts about you) and project (per-workspace context). Distinct from a committable REASONIX.md, which lives in the repo.

Layout

~/.reasonix/memory/
  global/
    MEMORY.md                      # index — pinned into the prefix
    user_role.md
    feedback_terse_comments.md
  <project-hash>/                  # sha1(absRoot)[0..16]
    MEMORY.md
    project_release_freeze.md

Entry shape

---
name: user_role
description: User is a senior backend engineer; new to React.
type: user                       # user | feedback | project | reference
scope: global
created: 2026-05-09
---

Body — the actual remembered fact, in plain markdown.

Types: user (who they are), feedback (corrections / preferences), project (initiative / deadline / motivation), reference (where to look in external systems).

Slash commands

/memory list List all entries, both scopes.
/memory show <name> Display body. Scope is auto-resolved.
/memory forget <name> Delete one entry.
/memory clear <scope> confirm Wipe an entire scope. confirm is mandatory.

Writing memories: say it in chat ("remember I prefer Vitest over Jest"). The model invokes the scaffold_memory tool, which proposes a file and waits for your /apply.

Hooks

Hooks are shell commands the harness fires on lifecycle events. Configured in settings.json, not config.json. Project scope first, then global.

Where to put them

<project>/.reasonix/settings.json   # project scope
~/.reasonix/settings.json           # global scope

Shape

{
  "hooks": {
    "PreToolUse": [
      {
        "command": "node scripts/audit.js",
        "match": "^(write|edit_file|bash)$",
        "description": "Audit risky tool calls before they run",
        "timeout": 5000
      }
    ],
    "PostToolUse": [
      { "command": "echo done >> /tmp/reasonix.log" }
    ],
    "UserPromptSubmit": [],
    "Stop": []
  }
}

Events

  • PreToolUse Before a tool runs. Gating: exit 2 blocks; exit 0 passes. 5 s default timeout.
  • PostToolUse After a tool runs. Non-gating; warn-only on non-zero. 30 s default.
  • UserPromptSubmit Before user input is processed. Gating (exit 2 blocks the message).
  • Stop On /quit or session exit. Non-gating.

Stdin payload

Each hook receives a JSON object on stdin describing the event:

{
  "event": "PreToolUse",
  "cwd": "/workspace",
  "toolName": "bash",
  "toolArgs": { "command": "rm -rf /" },
  "turn": 3
}

Permissions

Shell commands are gated per-workspace. The first time the agent runs a command, you get an interactive allow once / allow always / deny prompt; "allow always" persists the exact prefix to config.json under that project.

{
  "projects": {
    "/abs/path/to/repo": {
      "shellAllowed": [
        "npm test",
        "git status",
        "ls"
      ]
    }
  }
}

Exact match after trim. git alone does not cover git push origin main; list each prefix you actually want green-lit.

/permissions list Show this project's allowlist.
/permissions add <prefix> Add a shell prefix.
/permissions rm <prefix|index> Remove by name or list index.
/permissions clear confirm Wipe everything. confirm is mandatory.

Semantic index

reasonix index builds an embedding index the agent can query. Pick an embedding provider:

{
  "semantic": {
    "provider": "ollama",
    "ollama": {
      "baseUrl": "http://localhost:11434",
      "model": "nomic-embed-text"
    },
    "openaiCompat": {
      "baseUrl": "https://api.example.com/v1",
      "apiKey": "...",
      "model": "text-embedding-3-small"
    }
  }
}

Switch by changing provider. Local Ollama is free and air-gapped; OpenAI-compat lets you point at any hosted embedding API.

Still stuck?

Open a discussion or drop into good first issue. Every avatar on the contributors wall started somewhere.