Open the console

Get started

Quickstart

From nothing to a deployed agent that answers you. About fifteen minutes, most of it waiting for the first build.

Before you begin

  • Python 3.12 or newer, and uv.
  • git, and a GitHub account that can create a repository. The platform builds from your remote, never from your disk.
  • A model API key. The agent you are about to scaffold uses a Gemini model, so a Google AI Studio key is the quickest to get.
  • An account. Accounts are created by invitation: accept the email and set a password before going further. Not invited yet? Request early access.
  • Somebody who can install a GitHub App on your repository — an admin of the GitHub organization that owns it. It may not be you, so ask early (step 3).

1. Install the CLI and sign in

uv tool install elan-cli

elan login
elan whoami

login prints a link and a code. Open the link in a browser, sign in if asked, check that the code it shows matches the one in your terminal, and approve. Your refresh token goes to the OS keyring, never to a file.

whoami prints your tenant on its own line — tenant acme, say. You need it in the next step.

2. Create a repository and scaffold it

A project is one git repository, producing one image; every agent and workflow in it ships together. Create an empty repository on GitHub first — no README, license or .gitignore, or your first push is refused because the remote has history yours does not. Then, with your own tenant and repository on the first two lines:

TENANT=acme                              # the tenant whoami printed
REPO=https://github.com/acme/agents      # the empty repository you just made

elan projects create agents --repo $REPO

mkdir agents && cd agents
elan init --tenant $TENANT --project agents --repo $REPO --agent hello-agent

projects create reserves the name in your organization, so the project appears in the console before anything is deployed. If it answers that agents already exists, somebody in your organization has it — pick another name and use it in both commands, rather than deploying over theirs.

init writes a commented elan.yaml (the deploy contract — read it), one agent under agents/hello_agent/ exporting MANIFEST and build(), a git-ignored .env, a .venv holding the platform runtime, and a CLAUDE.md with .claude/settings.json so an AI coding assistant opened in the repo knows its rules and where these docs are; then it runs git init. If it could not build the environment it says so, and elan env retries. Slugs are checked here rather than at deploy time: tenant and project are 3–16 characters, an agent 5–16, all lowercase letters, digits and single hyphens, starting with a letter.

--repo becomes source.repo, which is what the build clones. Leave it out and the file gets the placeholder https://github.com/ORG/REPO, which nothing checks until the build fails to clone it — if that happened, edit source.repo by hand.

3. Let the platform clone your repository

A private repository can only be cloned with permission, and the permission is a GitHub App installation: an admin of the GitHub organization installs the App once and chooses which repositories it covers. Install the App on the repository from step 2. A public repository needs no installation.

Nothing in the CLI or the console can grant this on your behalf — that is the point of it being an installation — and the same admin can revoke it from GitHub at any time without involving the platform.

Skip it and the failure looks like a typo in your URL

The deploy is accepted, a build starts, and minutes later it fails with Repository not found — which reads as a wrong source.repo rather than a missing permission. Check the installation before the URL. The same message appears when the App is installed but does not cover this particular repository.

4. Run it locally

Open .env and put your key on the line init left for it:

GOOGLE_API_KEY=AIza...

Then start ADK's own developer UI, pointed at your repo:

elan adk web

Open the URL it prints and pick hello_agent — ADK lists the module name, with an underscore. The agent runs behind the same plugins a deployed pod uses, minus billing. Iterate here: every round trip through a deploy costs you a build.

The name is GOOGLE_API_KEY because that is what a deployed pod receives: llm.keys: {google: default} in elan.yaml resolves to it. Use the platform's names in .env and your laptop and the pod read the same variables.

5. Give the platform your model key

A deployed pod never reads .env. It gets its key from your organization's secrets, under the name llm.keys points at — here a provider key called default:

elan secret set llm default     # paste the key, press Enter, then Ctrl-D
elan secret ls                  # names only, never values

--from-file <path> reads it from a file instead. There is no --value flag, on purpose: a secret on a command line is a secret in the shell history. You can also set it in the console, under Config → Secrets → New secret, with the kind Provider key (llm) and the name default. Secrets belong to the organization, so every project can name this one.

Without it, the agent never starts

Its pod is told to mount a key that does not exist, and Kubernetes will not start a container whose environment names a missing secret. Set the key before you deploy. Changing it later reaches only pods that start afterwards — running ones keep the value they started with.

6. Validate, commit and push

elan validate

git add -A
git commit -m "first agent"
git branch -M main
git remote add origin $REPO
git push -u origin main

validate reads elan.yaml and imports your agents' manifests, then checks them against each other in both directions with the same model the service uses — a local yes is a service yes. Fix everything it reports before you spend a build.

The push is not optional. init ran git init and added no remote, and the build clones your remote at the commit you deploy — so deploy refuses a commit that no remote branch holds, saying it is “not on any remote branch”, before anything is built. In a new terminal, $REPO is gone: set it again or type the URL.

7. Deploy

elan deploy

deploy resolves your branch to a commit, writes that sha into source.ref, submits, and prints each phase as it is reached — build, scan, provision, sync and the rest — then which agents moved to the new image. Writing the sha leaves elan.yaml changed on disk; commit it with your next change.

The first deploy of a project is the slow one

It provisions a database, a bucket, topics and subscriptions, and every later deploy reuses them. If it fails, elan logs <deployment-id> prints the build output and elan status <deployment-id> the phase it stopped at and why.

8. Talk to it

elan invoke hello-agent --text "what can you do?"

# the same conversation, with the session id it printed
elan invoke hello-agent --session cli-9a3f1b2c4d5e --text "tell me more"

Run it from inside the repository: invoke takes the project from elan.yaml. It prints the invocation and session ids, then the reply.

The first reply after a quiet period is slow, and is not a failure

An agent scales to zero by default, so the first message after a quiet spell waits for a pod to be scheduled, a sandboxed container to start and ADK to import — about 13 seconds typically and 22 at the slow end, occasionally more. invoke prints queued while that happens. A warm agent answers in the time your model takes.

Where to go next

Reading this as a model? llms.txt indexes every page, and each page has a “Copy for AI” control.