Skip to content

Build an app with an agent

The goal: your own agent runtime (Claude Code, or anything that speaks MCP) reads the repository and database attached to one of your app groups, writes code, and opens a pull request — while Axowl decides what it is allowed to touch and records what it did.

Axowl does not build the application and does not host a screen for it. It supplies the materials and the authority.

Two things are a person’s job, not the agent’s. Do them first:

  1. Connect a Git repository to the client the agent will work on.
  2. Attach a database to the app group.

The hire dialog checks both and will point you at the setup screens if either is missing. An agent only ever gets read on these — connecting them is a prerequisite, not something it can do.

App group → AgentsHire. Pick a kind, name it, give it a TTL (required — an agent without an expiry cannot be created), and choose the client it works on.

There is no scope picker on this screen. The kind decides the scopes. That is deliberate: the permissions live in the role, and letting the screen choose them too would create a second source of truth that drifts.

For the workflow in this guide you need three scopes:

NeedScope
Read the repositoryorg.git_repository.read
Open pull requestsorg.git_repository.propose_change
Read the databaseorg.data_source.read

design already holds all three, so it is the shortest path even though the name suggests otherwise. Check the kind table in Agents before assuming.

custom starts with nothing. Hiring it and connecting straight away gets you a refusal on every gated tool. To give it authority, add permissions to the AGENT_CUSTOM role on the roles screen.

Terminal window
claude mcp add --transport http axowl https://testapi.axowl.com/mcp

The first tool call returns 401, your client discovers the authorization server, and a browser opens. Sign in, pick the agent it may act as, approve. See MCP server for the alternative: a credential issued from the agent’s card, with no browser step.

Call axowl_context first, always:

agent : App Builder (design)
org : acme
app group : 6f1c…
repository : acme/storefront (branch main)
database : attached (production-read)
you may:
read repository files yes
read database yes
open pull requests yes

It answers the two questions that otherwise cost you a wasted attempt: is anything connected, and may I touch it. A NO line names the missing scope and says whether the agent or you is the one lacking it.

A normal loop looks like this:

  1. axowl_db_schema — never guess table names.
  2. axowl_db_query — read real rows. SELECT only; a failing query returns the database’s own error so your model can fix the statement.
  3. axowl_repo_list_files / axowl_repo_read_file — read what exists before changing it.
  4. Your runtime writes the code.
  5. axowl_propose_code_change — whole files, not patches. It opens a pull request.

The pull request is the only way code changes. There is no direct-push path, and merging stays a human step. Paths are filtered — .github/, .env, key and certificate files are refused individually, so one bad path does not sink the rest of the change. A pull request is capped at 20 files and 512KB.

A refusal is a sentence, not an error, and it names the subject:

code — denied (agent lacks org.git_repository.propose_change)
code — denied (delegating user lacks org.git_repository.propose_change)

The second one matters. Authority is what the agent holds ∩ what you hold, so widening the agent will not lift it — you have to hold the scope too. A person cannot hand a machine authority they do not have themselves.

If every tool refuses, there is no delegating person on the session. axowl_whoami says so directly.

Suspend or revoke the agent in the Agents tab. Its badge flips immediately and tokens stop working on the next call — revocation does not wait for an access token to expire. The TTL does the same thing on its own if you forget.

Both are recorded. A revoked agent’s roster row is retired, never erased.