Settings
IsonForge reads settings from JSON files at startup. Values become session defaults; command-line flags always override.
File sources (precedence, lowest to highest)
| Source | Path | Scope |
|---|---|---|
| User | ~/.isonforge/settings.json |
All your projects |
| Project | <cwd>/.isonforge/settings.json |
Committed to the repo |
| Local | <cwd>/.isonforge/settings.local.json |
Gitignored - personal overrides |
| Runtime | --settings <path-or-json> |
Per-invocation |
Each later source overrides keys set in earlier ones. Project beats user, local beats project, runtime beats everything.
Filter which sources load:
isonforge --setting-sources user,project # skip local
isonforge --setting-sources user # ignore project + local entirely
Known fields
{
"effort": "high",
"permissionMode": "acceptEdits",
"outputFormat": "text",
"maxTurns": 10,
"maxBudgetUsd": 5.00,
"addDirs": ["../shared", "../utils"],
"systemPromptAppend": "Always use TypeScript strict mode. No `any`.",
"theme": "default",
"hooks": {
"PreToolUse": [
{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "make lint"}]}
]
},
"mcpServers": {
"github": {"command": "mcp-github", "args": ["--token", "$GITHUB_TOKEN"]}
},
"permissions": {
"rules": [
{"tool": "bash", "args_pattern": "git status*", "action": "allow"},
{"tool": "bash", "args_pattern": "rm -rf*", "action": "deny"}
]
}
}
Flag values always win over settings:
# settings.json says effort=high; this run uses low
isonforge --effort low "quick fix"
Inline JSON via --settings
--settings accepts either a file path or an inline JSON string:
isonforge --settings '{"effort":"max","permissionMode":"plan"}'
isonforge --settings ./team-settings.json
Inline form is handy for one-off scripts. The JSON is parsed and merged on top of file sources.
Recommended split
- User (
~/.isonforge/settings.json): your personal defaults, MCP servers, hooks you want everywhere. - Project (
<cwd>/.isonforge/settings.json): team-shared - check this in. Project-specific hooks, permission rules, MCP servers, FORGE.md path references. - Local (
<cwd>/.isonforge/settings.local.json): your personal overrides for this project. Add to.gitignore. Useful for paths, API keys for MCP servers, or experimental hook commands.
Sample .gitignore entry:
.isonforge/settings.local.json
Hooks in settings
See Hooks for the full hook schema. Brief preview:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{"type": "command", "command": "./scripts/check-license.sh", "timeout": 10}
]
}
],
"PostToolUse": [
{"matcher": "Edit|Write", "hooks": [{"type": "command", "command": "pnpm format"}]}
]
}
}
MCP servers in settings
See MCP. Brief preview:
{
"mcpServers": {
"github": {
"command": "mcp-github",
"args": ["--repo", "myorg/myrepo"],
"env": {"GITHUB_TOKEN": "$GITHUB_TOKEN"}
},
"postgres": {
"command": "uvx",
"args": ["mcp-server-postgres"]
}
}
}
Permission rules
Persistent rules at ~/.isonforge/permissions.json get loaded automatically (or override via permissions.rules in settings.json):
{
"preset": "auto",
"rules": [
{"tool": "bash", "args_pattern": "docker compose*", "action": "allow"},
{"tool": "bash", "args_pattern": "kubectl delete*", "action": "deny"},
{"tool": "mcp__github__*", "action": "allow"}
]
}
See Permission modes.
Inspect effective settings
/config
Opens ~/.isonforge/config.json (API key + endpoint) in $EDITOR. For settings inspection use:
isonforge --verbose "test" 2>&1 | grep -i settings
Verbose mode logs what got loaded from where.
When settings don't apply
- Flag override: a CLI flag always wins.
- Subagent context: sub-agent (
task_explore/task_research) inherits the parent session's settings, not its own. - Background agents: spawned with effort + permission mode from parent at spawn time. Mid-flight settings changes don't propagate.