Coding agents

A coding agent works in a real GitHub repo: clone, install, run the repo's tests, push under m8tes/…, open a PR, watch CI. Same sandbox as every other run, plus a short-lived GitHub credential narrowed to the repos your install can see.

API first. Setup is on /api/v2 + the Python SDK. The Platform Apps page and mate Configure row call the same APIs.

Setup (API / SDK)

Account-scoped, not per user_id. Check status, then pick a path:

Python
from m8tes import M8tes

client = M8tes(api_key="m8_...")
print(client.github_app.status())

Install the m8tes GitHub App

Python
url = client.github_app.install_url()
# Open url. Pick **selected repositories only**. After GitHub redirects with a ticket:
client.github_app.claim(ticket="…")

Create your GitHub App

Use this when the m8tes GitHub App is gated, or you want your own branding / allowlists.

Python
status = client.github_app.status()
url = client.github_app.setup_url(cancel_epoch=status.manifest_epoch)  # optional: org="acme", name="Acme Code"
print(url)

Open that URL. GitHub creates the App and sends you back with a ticket:

Python
install_url = client.github_app.complete_setup(ticket="…")
# Open install_url. Pick **selected repositories only**. After GitHub:
client.github_app.claim(ticket="…")

Already have an App? client.channels.upsert_identity(channel="github", …). After disconnect, client.github_app.clear_identity() goes back to the m8tes GitHub App.

Bind repos to an agent (optional. Once connected, empty agents inherit the install's repos automatically):

Python
# Repo bindings are account-scoped: end-user agents never get repo-write credentials.
# Personal development only: this disables strict user_id checks account-wide.
# This persists. For customer-facing apps, keep strict mode on and pass user_id.
client.settings.update(require_end_user_id=False)

agent = client.agents.create(name="coder")
client.agents.configure_repo(agent.id, repo_full_name="acme/api", mode="trusted")
print(client.agents.list_repos(agent.id).data)

Trusted is local-Claude-Code parity for your own repos (push/merge gated by the agent's permission mode). Guarded never merges, requires branch protection, and keeps setup/test/lint commands inert until you approve them via approve_repo_commands.

Repo secrets (the run's .env)

Most test suites need what a developer's .env holds: a test database URL, a sandbox API key. Store them per repo binding. Values are write-only and encrypted at rest; every read returns key names and rotation times only.

Python
repo = client.agents.list_repos(agent.id).data[0]
client.agents.set_repo_env(agent.id, repo.id, env={
    "DATABASE_URL": "postgres://localhost/app_test",
    "STRIPE_KEY": "sk_test_…",
})
print([k.key for k in client.agents.get_repo_env(agent.id, repo.id).keys])
client.agents.delete_repo_env_key(agent.id, repo.id, "STRIPE_KEY")

set_repo_env replaces the whole set (a key you omit is removed). Values must be 8-8192 characters; shorter ones are refused because the sandbox could not redact them from run output. At run start the sandbox writes the set to a 0600 file and points $CODING_REPO_ENV_FILE at it; the agent sources it before the repo's setup/test commands. The values never enter the model's context, the CLI environment, or the run output.

In guarded mode the repository's own code runs as the same user and can read that file. Store only what you would put in that repo's CI secrets.

Setup (Platform)

In the browser, open Apps → GitHub:

ChoiceAction
Managed AppInstall m8tes GitHub App
Your own AppCreate a custom GitHub App; choose its owner, then enter an organization name or GitHub URL
Stalled setupConnect to finish custom setup, or Switch to m8tes inside setup
Agent permissionsmate → Configure → Repository

The default install lets you choose your organization or personal account on GitHub. Select Only select repositories.

Custom setup opens GitHub in a new tab, with a checklist kept on Apps. Organization ownership is the default; personal ownership requires an explicit choice. Private apps can only be installed on their owner's account. For example, a repository URL like https://github.com/acme/api identifies acme as the organization, not an enterprise.

If a custom app was created under the wrong account, choose Switch to m8tes to clear its connection here. Then install m8tes or create a new custom app under the right organization. This does not transfer the existing app on GitHub.

How access works

LayerWhat it means
GET /api/v2/github-app/*Account-level GitHub App install (selected repos)
Shared with agentsEvery live agent inherits those repos when bindings are empty
Per-run tokenNarrowed to the bound repo_ids, ~1 hour, revoked at teardown
Mode / commandsPer-agent. configure_repo / Configure → Repository

To revoke GitHub for the whole account: client.github_app.disconnect() or disconnect under Apps.

Multi-tenant user_id

Installs and MateRepo bindings are account-scoped. Runs created with user_id (end-user isolation) do not receive the account's repo-write credential (prepare_coding_run skips them). Per-tenant coding installs are not shipped yet.

White-label / own App: setup_url() or channels.upsert_identity(channel="github") stores your GitHub App credentials; coding installs then use YOUR App (JWT, webhook, install URL) instead of the m8tes GitHub App. Same L1–L4 safety model.

What to run

Text
Open a PR that bumps <dependency> and keeps the suite green.

Skills the agent loads when a repo is available: setting-up-a-repo (first-run toolchain) and working-in-a-repo (fix → test → push → PR).

Was this page helpful?