Ajica: quick start
Ajica is a local server that coordinates tasks between a person and AI agents. In a typical
installation the server is available at http://127.0.0.1:7331, the data lives in SQLite, and the
person works on a Kanban board in a browser or in the native macOS app.
Connect an agent in one line
When Ajica is already running, give the agent the output of the canonical bootstrap route:
curl -fsS "http://127.0.0.1:7331/connect?client=codex"
Replace codex with claude-code, cursor, windsurf, cline, opencode or generic.
/connect returns the full checksummed skill bundle for .agents/skills/ajica/, the MCP
configuration, a safe enrollment, and the order canonical project resolve → runtime attach →
claim. To check a directory right away, add a URL-encoded path with
curl -G --data-urlencode "path=$PWD". JSON is available at /connect.json; /init is kept only
as a legacy 308 redirect.
The enrollment slug is the name of the CLI if the server can launch it: claude-code connects as
claude, while codex, cline and opencode connect under their own names. Auto-launch picks an
agent by this slug only, so an agent that an earlier /connect connected as claude-code was never
launched by the server; /connect marks such an old token file in auth.legacy_token_file.
Connecting Cline
?client=cline returns the same skill bundle with no copy or symlink (Cline finds
.agents/skills/ajica/ by itself through npx skills) and an MCP configuration in Cline's format —
the nested mcpServers.ajica.transport.{type,command,args,env} for the file
~/.cline/data/settings/cline_mcp_settings.json. The enrollment after that is the same as for any
client: ajica-server enroll --slug cline --name "Cline CLI".
Connecting OpenCode
?client=opencode returns instructions with an MCP configuration for opencode.json (the top-level
key mcp, type: "local"). OpenCode scans the rules in AGENTS.md at the project root by itself.
The enrollment after that is the same as for any client:
ajica-server enroll --slug opencode --name "OpenCode CLI".
Which route to choose
| Goal | Way | What you need |
|---|---|---|
| Just use Ajica on macOS | Native app | Install the .dmg and open Ajica.app |
| Run from source or on another OS | Python CLI | Python 3.11+, ajica-server serve |
| Manage tasks by hand | Kanban UI | Open http://127.0.0.1:7331/ |
| Connect Claude Desktop, Cursor or another MCP environment | MCP over stdio | A running Ajica and an agent token, or approval through request_access |
| Integrate a script, CI or your own agent | REST API | A bearer token and an HTTP client |
| Launch an agent from a card | Dispatch | A configured agent CLI; Ajica gives the process a temporary credential |
| Hand tasks to an already running Codex/Claude/Cursor | Attached runtime | attach_runtime + heartbeat + pull through MCP or REST |
Every route uses one database and one HTTP API. MCP is a client of that API, not a separate data server.
1. Start Ajica
Option A: the native macOS app
Install the release .dmg and open Ajica.app (macOS 12 or later). The first launch opens a short
welcome — the same steps as below, plus one question about anonymous usage metrics, which stay off
until you turn them on. You can bring it back with Ajica ▸ Getting started…. The app itself:
- starts the local server on port
7331; - opens the Kanban board;
- manages the master token;
- offers to install the CLI and to copy the MCP configuration from the status bar menu.
To build locally from the repository:
make macos-app-dev
open build_macos/Ajica.app
Option B: the Python CLI
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .
export TASK_SERVER_TOKEN="$(openssl rand -hex 32)"
ajica-server serve
By default the server listens on 127.0.0.1:7331 and the database is at
~/.tasktracker/tasks.db. The equivalent start without an installed entry point:
python -m taskserver serve
Useful variants:
ajica-server serve --port 7340 --db /absolute/path/to/tasks.db
ajica-server doctor
ajica-server openapi > openapi.json
TASK_SERVER_TOKEN is the credential of the server's owner. Do not hand it to AI agents: they are
meant to use separate agent tokens with limited rights.
2. Check the start and open the interface
| Address | Purpose |
|---|---|
http://127.0.0.1:7331/ |
Kanban UI |
http://127.0.0.1:7331/health |
Availability check |
http://127.0.0.1:7331/docs |
Swagger UI |
http://127.0.0.1:7331/docs.md |
The full guide (currently in Russian) |
http://127.0.0.1:7331/changelog.md |
Version history (Changelog) |
http://127.0.0.1:7331/agent.md |
A compact contract for an AI agent |
http://127.0.0.1:7331/openapi.json |
The OpenAPI schema |
In the UI, create or choose a workspace, register a project directory and create a task. A project
in Ajica is tied to an absolute path on disk. The native app authorizes its own window
automatically; when you open the board in an ordinary browser, enter the master token the server
was started with. The browser keeps it only in the sessionStorage of the current tab.
3. Give an agent access
Choose one of four ways. The agent does not need the master token for any of them.
Ajica launched the agent itself
When a person starts work from a card, Ajica passes the chosen CLI the task, PROJECT_ROOT and a
short-lived credential automatically. No extra token setup is needed in the agent's process.
Approval straight from an MCP client
Start MCP without a token, call the request_access tool, show the user the returned user_code,
and after approval call check_access. The token is kept inside the session and is not returned
to the chat.
Enrollment from the terminal
ajica-server enroll --slug codex --name "Codex CLI"
The command shows only the approval code. After you confirm in Ajica it writes the credential to
~/.ajica/agents/codex.token with restricted permissions itself. MCP can read this file by slug:
ajica-server mcp --agent-slug codex
For a direct REST call, load the credential into the environment without printing it:
export AJICA_AGENT_TOKEN="$(cat ~/.ajica/agents/codex.token)"
Local administrative issue
The owner of the machine, with direct access to the database, can issue or rotate a credential:
ajica-server agent-token codex --name "Codex CLI"
ajica-server agent-token codex --rotate
The command saves the value to ~/.ajica/agents/codex.token with mode 0600 itself and never
prints it. Load the credential from that file into the environment; do not pass it through a prompt,
a URL, a task comment or a repository.
4. Connect MCP
Ajica must be running. For an installed CLI the basic command looks like this:
AJICA_AGENT_SLUG=codex ajica-server mcp
For the native macOS app use the built-in binary:
/Applications/Ajica.app/Contents/Resources/ajica-server
An example MCP client configuration:
{
"mcpServers": {
"ajica": {
"command": "ajica-server",
"args": ["mcp"],
"env": {"AJICA_AGENT_SLUG": "codex"}
}
}
}
Where to save the configuration:
- Claude Desktop on macOS:
~/Library/Application Support/Claude/claude_desktop_config.json; - Cursor, per project:
.cursor/mcp.json; - another MCP client: its section for stdio servers, with the same command and arguments.
One MCP server serves all projects: the project is chosen by an explicitly passed path or by the
canonical working directory. Do not add --project-id to a new configuration — it is only a legacy
fallback. If the directory is not registered yet, use the MCP tools request_project and
check_project, or:
ajica-server register-project --path "$PWD" --name "My project" --slug codex
A person confirms the registration of a directory in Ajica, and chooses the workspace there too.
5. Connect the REST API
All working endpoints live under /api/v1. Every request to them needs a credential:
export AJICA_BASE_URL="http://127.0.0.1:7331"
curl -sS --get \
-H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
--data-urlencode "path=$PWD" \
"$AJICA_BASE_URL/api/v1/projects/resolve"
The minimal lifecycle of an executable task:
TASK_ID="task_01..."
# Read the card and check execution_kind/readiness
curl -sS -H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
"$AJICA_BASE_URL/api/v1/tasks/$TASK_ID"
# Claim a single or a ready composite before changing any files
curl -sS -X POST -H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
"$AJICA_BASE_URL/api/v1/tasks/$TASK_ID/claim"
# Before the automatic checks
curl -sS -X POST -H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
-H "Content-Type: application/json" -d '{"status":"testing"}' \
"$AJICA_BASE_URL/api/v1/tasks/$TASK_ID/status"
# After the checks pass: the final comment first, then done
curl -sS -X POST -H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
-H "Content-Type: application/json" -d '{"text":"Changes and checks..."}' \
"$AJICA_BASE_URL/api/v1/tasks/$TASK_ID/comments"
curl -sS -X POST -H "Authorization: Bearer $AJICA_AGENT_TOKEN" \
-H "Content-Type: application/json" -d '{"status":"done"}' \
"$AJICA_BASE_URL/api/v1/tasks/$TASK_ID/status"
If the tests fail, first return the task to in_progress, add a comment with the error, and only
then fix it. Call /wait-user before asking the user a question.
6. Two ways a task reaches an agent
Dispatch: Ajica launches the CLI
A person moves the card into work or launches it explicitly from the UI. In auto mode Ajica first
looks for a live attached session of the project, and if there is none, it launches the configured
CLI at the project root. This is the usual way for an agent that is not running yet.
Attached runtime: the agent is already running
An already running Codex, Claude Code or Cursor must register a runtime, otherwise Ajica may spawn a second process in the same working tree. The session cycle:
attach_runtimewithproject_id,cwd, PID and the heartbeat interval.runtime_heartbeatevery 20 seconds with the statusidleorbusy.pull_next_taskwhen an assignment is waiting.- An ordinary
claim_taskconfirms that the task was accepted. detach_runtimebefore the session ends.
The same operations exist in REST: attach starts at /projects/{project_id}/agent-runtimes, and
heartbeat, pull and detach use /agent-runtimes/{runtime_id}/.... cwd must be inside the
PROJECT_ROOT of the project.
7. The kinds of task an agent will see
| Kind | Behavior |
|---|---|
single |
Claim → implement → testing → done |
composite |
Coordination while the required children are not finished; once readiness=ready it runs as a worker task |
epic |
A coordination container only; it is not claimed and does not implement files itself |
The legacy command can add an old instruction file for an agent:
ajica-server init-agent /absolute/path/to/project
init-agent runs git init if needed, then creates .tasktracker/AGENTS.md. For a new connection
use /connect and the skill .agents/skills/ajica/; init-agent is kept only for compatibility
with the old process.
8. If the connection does not work
curl -sS http://127.0.0.1:7331/health
ajica-server doctor
ajica-server mcp --help
401: the credential is missing, expired or was rotated — run the enrollment again.403 PROJECT_SCOPE_REQUIRED: the agent token is not allowed for the chosen project.404onprojects/resolve: the directory is not registered yet; fileregister-project/request_projectand wait for the person's decision.409 NO_ATTACHED_RUNTIME: thesessiondelivery mode is chosen but there is no live runtime.- MCP reports
AJICA_UNREACHABLE: start the HTTP server first and checkAJICA_BASE_URL.
More: the FAQ (editions, licence, what leaves your machine), the full guide (Russian), REST/OpenAPI and the instructions for agents.