Set up Horde / Projects

Work in a project

Use a named project when you want separate tasks, configuration, and access to provider accounts and workers for each body of work. Several projects can share one Horde daemon.

The quick start uses the default project for an unregistered repository. Start here with Horde installed and a Git checkout that has an initial commit and a configured Git author.

1. Create a project and register its repository

horde start
horde project create my-app --concurrency 2
horde project repo-add my-app /absolute/path/to/my-app
horde project runtime-grant my-app local
horde project inspect my-app

Replace my-app with your project slug and use your checkout’s absolute path. The local grant allows this daemon’s runtime to execute the project’s tasks. New projects begin with no runtime or provider account grants.

A checkout and all its Git worktrees belong to one project. If you already used that checkout in the default project, use a separate clone for the new project. Repository ownership cannot be reassigned.

To check scheduling before configuring a model provider, run a simulated task:

horde --project my-app submit "Check project scheduling" --repo /absolute/path/to/my-app --template simulated
horde --project my-app inspect TASK_ID

Replace TASK_ID with the returned task ID. The simulated template makes no model calls.

2. Configure the project’s agents

Named projects start with built-in settings and do not inherit your default project’s user configuration. This example uses the installed Claude Code CLI for planning, implementation, and review. Save this TOML in a private file outside the repository, such as /private/path/my-app.toml:

concurrency = 2

[executors.planner]
provider = "claude"

[executors.worker]
provider = "claude"

[executors.reviewer]
provider = "claude"
horde project configure my-app --file /private/path/my-app.toml

Horde validates the file and stores it under DATA_DIR/projects/PROJECT_ID/config.toml. Continue using horde config for the default project. Repository workflow settings load afterward, but cannot define provider connections, raise concurrency, or expand account and runtime access.

3. Add a provider account

Named projects need managed accounts, even when a provider CLI is already signed in on the host. For the Claude configuration above, create an account and keep its returned ID:

horde --project my-app account create claude-main --provider claude --auth-mode login --base-url https://api.anthropic.com/v1 --concurrency 2
claude setup-token

Save the setup token in a private JSON file outside the repository, replacing the placeholder below. Use file permissions 0600 and include expires_at as Unix seconds when the expiration is known.

{
  "kind": "claude_setup_token",
  "secret": "REPLACE_WITH_SETUP_TOKEN"
}
horde --project my-app account credential-set ACCOUNT_ID /private/path/claude-credential.json
horde --project my-app account inspect ACCOUNT_ID

Replace ACCOUNT_ID with the ID returned by account creation. Creating an account grants it to its owning project. Horde selects a granted account whose provider kind, authentication mode, and endpoint match the executor’s provider configuration.

For Codex, API keys, and sharing an existing managed account, see provider account configuration. An administrator can grant an existing account with horde account grant ACCOUNT_ID my-app. Shared accounts keep one quota and concurrency total across projects.

4. Submit and follow project work

horde --project my-app submit "Add CSV export with tests" --repo /absolute/path/to/my-app
horde --project my-app list
horde --project my-app inspect TASK_ID
horde --project my-app watch TASK_ID
horde --project my-app summary TASK_ID

Use the new task ID. The summary reports the task status and integrated commit. Horde integrates local work in a separate worktree and leaves your original checkout on its branch.

Registered repositories supply the project when selection can be inferred. Passing --project explicitly keeps scripts and task commands scoped. To inspect all projects as an administrator, use horde project list and horde list --all-projects without --project.

If work waits, inspect the task’s queue reason, then check horde project inspect my-app and horde --project my-app account list. A missing runtime grant, expired credential, or exhausted account capacity can prevent execution. See capacity and credential troubleshooting.

5. Connect an agent to this project

Give the agent a project-bound MCP connection:

{
  "mcpServers": {
    "horde-my-app": {
      "command": "horde",
      "args": ["--project", "my-app", "mcp"]
    }
  }
}

Use the absolute path to ~/.local/bin/horde if your agent cannot find the command. For a custom data directory, include "--data-dir", "/absolute/path" before "mcp" and use that same directory in your CLI commands.

The connection stays bound to this project. It cannot access another project’s tasks or artifacts, list all projects’ tasks, or change project, account-grant, and fleet administration. Run those administration commands from an unbound CLI or MCP connection. See the agent reference for operation schemas and worker credentials.

Project boundaries protect Horde-managed requests and state. Programs running under the same OS account can still read each other’s files. Use a separate execution identity or VM isolation when you need a filesystem boundary.

When you need more