Subsystem

Part 1 of 6 The first minute

Install it, and tell your agent

By the end of this chapter, Subroutine is installed on your computer, Claude Code has its tools and its skill, and the first piece of work on the website rebuild is filed under an account of the agent's own. You will have typed four commands and one sentence.

The examples follow Laurence, a developer rebuilding his team's website, on his laptop. Nothing is served, nothing needs a password, and the work stays in a file on his own disk.

Four commands

Subroutine comes with a command-line program. Install it as a tool, with uv:

$ uv tool install subroutine
Resolved … packages in …
Prepared … packages in …
Installed … packages in …
…
Installed 2 executables: subr, subroutine

That puts two commands on your PATH: subroutine, and subr, which is the same command, shorter. The foot of this page names the release these examples were checked against.

$ subroutine init
Ready. Try: subroutine add "something to do"

subroutine init makes the database your work is kept in, and an account for you in it, named after the account you use on your computer. There is nothing to configure first.

The last two give Claude Code the tools and the skill:

Not checked: the build does not run this.

$ claude plugin marketplace add simonholliday/subroutine
$ claude plugin install subroutine@subroutine

Adding the marketplace clones a repository, so it needs Git. That is the one prerequisite here that is Claude Code's rather than Subroutine's. Claude Code's documentation covers plugins and marketplaces.

No uv? Its installation page has a one-line installer, or pipx does the same job with pipx install subroutine. If your terminal then cannot find subroutine, uv tool update-shell adds uv's folder to your PATH, and a new terminal finds it.

What the plugin gives it

Tools come over the Model Context Protocol (MCP). Claude Code is an MCP client: it is given servers, each either a program it starts or the address of an instance already serving, and it asks each one which tools it has.

The plugin configures Subroutine's own server, which is the command subroutine mcp. Written out, that configuration is:

{
  "mcpServers": {
    "subroutine": {
      "command": "subroutine",
      "args": ["mcp"]
    }
  }
}

It opens no port. A client talks to it over its input and output, so when no client is running it, nothing is serving. Any MCP client can be given the same thing by hand, and a later chapter does exactly that. The plugin is the Claude Code shortcut, and it brings the skill as well.

Then one sentence

Start a fresh Claude Code session, because a session is given its tools when it begins and one that was already open has none. Then tell it:

Not checked: the build does not run this.

we use Subroutine now

That sentence is the setup. What follows is what the agent does with it, and you are reading rather than typing.

The plugin brings a skill as well as the tools: the practice rather than the operations. It has a section for exactly this moment, and its first instruction is to ask only what cannot be undone, and state the rest. So the agent proposes rather than interviews.

What it does with it

It looks before it creates. A duplicate project is invisible until somebody files into the one nobody reads, so the first call is a question:

subroutine_project()
…

It proposes a key and makes the project, rather than asking you to choose one. A key is a path segment and will be part of a URL, so it is read far more often than it is typed:

subroutine_project(key="web", title="Website rebuild")
…

It does not ask which workspace, because a fresh install has exactly one. It does not ask about privacy, because there is one account. Both of those are undoable later, and the skill says to state them and move on; the one thing it would stop and ask about is the workspace, if there were more than one, because items are numbered per workspace and a project cannot be moved between them.

It marks the checkout, so that a session starting in this directory does not have to work out which project the work belongs to:

$ subroutine use --here --project web
…

That writes a small .subroutine file at the repository root, naming a project and not a credential, so it is safe to commit. From then on, work added anywhere under this directory goes to web unless a line says otherwise.

And it writes a pointer into the file it reads at startup, CLAUDE.md or AGENTS.md, naming the project. Without that, the next session does not know any of this happened, and adopts again.

Ask it who it is

Ask Claude Code to call its subroutine_whoami tool. The first line is the call it makes, and the lines after it are what the tool answers:

subroutine_whoami()
laurence (person), via the local database.
…

It is working as Laurence. Until an agent on this laptop has an account of its own, it uses the one subroutine init made, so everything it files carries Laurence's name. For one person on one laptop that is not wrong, and it is worth knowing rather than discovering.

An account of its own

This is the one step that is yours rather than the agent's, because it prints a credential:

$ subroutine agent create claude --profile worker --project web --store
Created service account claude, with the contributor role.

  sr_…

That is the only time the credential is shown. Nothing recovers it afterwards.

Checked, by presenting it: claude (agent), in projects (comment:read, comment:write, project:read, task:read, task:write, workspace:read), and only within web

Written to /home/laurence/.config/subroutine/credentials.toml as the agent on connection 'local'.
'subroutine' here acts as claude wherever CLAUDECODE is set, and as laurence otherwise.

subroutine agent create makes the account, gives it a role, issues its credential and then checks what that credential can do by using it, all at once.

The last line is how Subroutine tells the two of them apart. Claude Code sets CLAUDECODE on the commands it runs and on the servers its tools come from, so both act as claude. Everything else on the laptop, Laurence's own terminal included, acts as Laurence.

Whose name a change carries

An agent reaches Subroutine two ways, through its tools and through commands in its shell, and each finds its credential for itself. So check both halves, and your own terminal too.

$ subroutine whoami
laurence (person), via the local database.
…

Ask Claude Code to run the same command in its shell:

$ subroutine whoami
claude (agent), via token 'claude agent' (…).
This connection's agent credential, because CLAUDECODE is set here.
Account parent: laurence.
Narrowed to projects web.
…

Then start a new session, because a session's tools find their credential when they start, and ask it to call subroutine_whoami again:

subroutine_whoami()
claude (agent), via token 'claude agent' (…).
Account parent: laurence.
Narrowed to projects web.
…

If either answer names Laurence, that half of the agent's work carries Laurence's name, and nothing else will show you.

Its first piece of work

Now ask for something to be filed. You are describing work, not writing a ticket:

subroutine_add(text="Write the copy for the home page +web")
Added #1  task  Write the copy for the home page  (read +web)

+web files it in the project, and the answer says it read it that way. In your own terminal, subroutine journal says who did what:

$ subroutine journal
…
    …  @claude (agent, @laurence)  created               #1 Write the copy for the home page

The work is claude's, and @laurence beside it names the person whose agent it is. That attribution is the reason to give an agent an account at all: it is what lets you hand over work you would otherwise supervise.

From here you talk to your agent rather than to Subroutine. File that as a bug. What can I actually start? What did we decide about retries? The next chapter puts that work on a screen you can watch while it happens.