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:
from m8tes import M8tes
client = M8tes(api_key="m8_...")
print(client.github_app.status())Install the m8tes GitHub App
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.
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:
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):
# 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.
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:
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
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
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).
Related
- Computer use: desktop/browser in the same sandbox
- Agents: creating and running agents
- Users:
user_idisolation - Human-in-the-loop: permission modes that gate merges and shell
- API reference:
github-appandagents/{id}/repos