Automation

Make Nemocode do things without you typing them: rules that always run, jobs that run later, and work that starts from outside. Skills, MCP servers and the basic idea of hooks are introduced on Skills, MCP, agents; this page has the details.

Hooks

A hook is a command of yours that Nemocode runs at a fixed point. Unlike an instruction in AGENTS.md, the agent cannot forget or argue with it. /hooks shows the ones active in a project.

EventWhen it runsWhat it can do
PreToolUseBefore a tool callRefuse the call, or replace its input.
PostToolUseAfter a tool callAdd text for the agent, for example the output of a linter.
UserPromptSubmitWhen you send a messageAdd context to it.
SessionStartWith the first message of a session (once per session and server run, not per message)Add context.
StopWhen a mission is completedRun a follow-up, such as a notification. It runs in the background and gets the mission's summary as the output.

Hooks are listed per event in a file named hooks.json. A project has its own; if it has none, the one in .nemocode in your home folder applies. The first one found wins; they are not merged. Because hooks run with your rights, the file lives where the agent's shell cannot change it — edit it yourself, not through the agent.

{
  "PreToolUse": [
    {"matcher": "run_command", "command": "python3 guard_shell.py"}
  ],
  "PostToolUse": [
    {"matcher": "edit_file|edit_files|create_file", "command": "./lint.sh"}
  ],
  "Stop": [{"command": "./notify.sh"}]
}

matcher is a regular expression on the tool name; leave it out to match every tool. Names are those on What the agent can do. Several hooks for one event run in order.

What a hook receives and answers

The command runs in the project folder. It gets one JSON object on standard input with the keys hook_event_name, cwd, tool_name, tool_input, tool_output (for PostToolUse, cut to 20,000 characters) and prompt (your message, for UserPromptSubmit). The same facts are also in the environment: NEMOCODE_HOOK_EVENT, NEMOCODE_TOOL_NAME, NEMOCODE_TOOL_PATH and NEMOCODE_PROJECT_DIR.

It answers with JSON on standard output, or with nothing to agree:

AnswerEffect
{"decision": "block", "reason": "..."}Before a tool call: refuse it. The agent is told why.
{"hookSpecificOutput": {"updatedInput": {...}}}Before a tool call: run it with this input instead. Later hooks for the same call already see the new input.
{"additionalContext": "..."}Give the agent this text (cut to 4,000 characters). It counts after a tool call (PostToolUse) and for UserPromptSubmit and SessionStart; before a tool call it is ignored.
{"systemMessage": "..."}Show this note to you.
exit code 2Same as block; what the hook wrote to standard error is the reason.

Only PreToolUse can refuse a call; a block from any other event is ignored. {"hookSpecificOutput": {"permissionDecision": "deny"}} counts as a block, too. The format follows Claude Code's hook contract, so many existing hook scripts work unchanged.

A broken hook never stops a mission. A hook that takes longer than 30 seconds, crashes, is missing or prints something that is not JSON is ignored. That also means a hook is a good place to enforce a rule and a bad place to depend on a side effect.

Skills and plugins

Installing and using skills is on Skills, MCP, agents. Two additions:

Workflows

A workflow is a saved graph of subagents for work that always has the same shape — for example list the modules, review each in parallel, merge the findings. The nodes are agents (read-only or with write access), loops over a list that run in parallel, branches on a condition, and joins that wait for all or any of the incoming branches. The agent starts one with run_workflow, or you save it as a file so it can be reused:

Saved workflows appear as slash commands: type / and the workflow's name to run it. Typing it is your consent, so it starts at once. When the agent proposes a workflow with run_workflow, it always asks you first, in every mode, because one graph can start many agents; in Read Only mode it is refused. A graph stops after 200 rounds.

Scheduled tasks

A scheduled task starts a mission later, on its own. Open /schedule, press a and fill in the task, when it runs, and how often it repeats. You can also just tell the agent run this at 18:27 or every night, check the dependencies.

FieldExamples
Whenin 20 minutes, at 18:27
Everyhourly, daily, every 30 minutes (at least a minute). Empty runs once.

A task runs in the session you created it in and is written like a fresh mission: it does not remember your conversation, so a good task text says everything. Missions of a project run one after another, so a scheduled task waits its turn. Jobs survive a restart, and one that came due while the machine was off is caught up unless it is more than 24 hours overdue. A repeating job keeps its rhythm: the next run is counted from the planned time, not from when the last mission finished. Results show on the dashboard.

The server must be running. Closing the interface leaves it running, but a reboot does not. Run nemocode service install once so it starts at login — see The nemocode command. nemocode stop pauses all scheduled tasks.

Connectors

A connector lets issues and comments in a GitHub repository start missions. Open /connectors, press a and give the repository as owner/name, the authors who may trigger it, an optional trigger word, and the name of the environment variable that holds your GitHub token (default GITHUB_TOKEN).

Polling pauses while the server is stopped.

Your own agents

A custom agent is a named role with its own instructions. Create one with /agents and a: a name, a line saying when to use it, the instructions, and whether it is personal or belongs to the project (the dialog also has a model field, but a custom agent runs on the model of its role, see the list below). Or ask the main agent to save one for you.

Finishing on a condition

/goal all tests pass and the linter is clean makes a mission run until that condition is actually true, judged by a separate check on what the agent showed. It is the way to run a task unattended and know that it ended because it worked, not because the agent said so. See Setting a goal. To run it on a schedule, put the goal in the task text.