Skip to main content
Build a digest agent that reads the starter app’s notes database, summarizes it in a hosted job, and runs on a daily schedule. You will write its standing instructions, declare its resources, supply model credentials, and start a job through the API. Start with a private slate created with init, as in the Quickstart, and work from its checkout. Use an account that can manage the slate so you can configure its owner-mode secret and inspect the job. Agents explains the distinction between an agent definition and each job that runs it.
1

Write the agent

Create agents/digest/ and add the two files below. The directory name, digest, becomes the agent’s name.instructions.md holds the agent’s standing instructions. Every hosted job of this agent runs with them. The prompt you send arrives as a separate user message.
agents/digest/instructions.md
slate.json is the agent’s declaration: the resources it needs. It uses the same schema as the app’s public/slate.json. connections is required; databases and secrets are optional.
agents/digest/slate.json
The starter app also declares notes in owner mode, so the app and this agent use the same hosted database. The API key belongs to the slate’s Owner and supplies hosted model authentication.Repeated resource names must agree across declarations: all use the same mode, and repeated connections use the same toolkit. An agent gets only its own declared resources; it does not inherit the app’s declaration.Every directory under agents/ needs a slate.json, even one that declares nothing: { "connections": {} }.
2

Supply model credentials

The example declares an owner-mode ANTHROPIC_API_KEY. Save an Anthropic API key for the slate’s Owner with the CLI’s secrets set command. It targets your personal Owner by default; choose the organization explicitly if the slate belongs to one. Run npx @usecontextlayer/cli secrets set --help for the input and Owner-selection syntax.Hosted agents support these credential declarations:
  • ANTHROPIC_API_KEY: an Anthropic API key. If both are declared, this one is used.
  • CLAUDE_CODE_OAUTH_TOKEN: a Claude subscription token, which claude setup-token creates.
The secret’s mode decides whose value a job uses. In owner mode the slate’s Owner saves one value and every job uses it. In viewer mode each person saves their own, and a job uses the value of the person it acts for. See Secrets.Jobs use claude-haiku-4-5 unless the agent declares ANTHROPIC_MODEL under secrets. To choose the model, declare ANTHROPIC_MODEL with a mode and save a full Anthropic model ID as its value, the same way as the key. Once declared, the value is required. A changed value applies to jobs started after the change.
3

Deploy by pushing to main

Commit the agent and push main:
Hosted jobs read the agent from the latest commit on main, so a pushed change to instructions.md or slate.json applies to the next job. Database migrations and schedules take effect only when the pushed commit builds and deploys successfully. See Deploy.
4

Start a hosted job and inspect it

Hosted jobs start through the platform API, and only on private slates. The CLI’s agent command runs an agent on your own machine instead; npx @usecontextlayer/cli agent --help describes it.Open the deployed notes app and add a few notes for the agent to summarize. Notes created during local development stay in the local database and are not present in the hosted database.Call Start an agent job with a prompt with “Summarize the notes.” Keep the job identifier returned by the API for the requests below. The start request returns after the job is accepted for execution; it does not wait for the answer.Start by checking its current operation, then wait for the operation result. A successful result should summarize the notes you added. Each job starts a fresh conversation; start a new job for another task.For more detail, use these inspection operations:Private-slate viewers can start jobs and read results for their own jobs and app-actor jobs. Detailed transcripts, usage, live inspection, schedule inspection, aborting, and deletion require slate management permission.Results and transcripts stay available after the job finishes. Abort an agent job’s pending operation stops it and keeps its records. Delete an agent job and its execution state removes the job and releases its computer. Deleting a job does not delete rows it wrote to a database or undo what its tools did elsewhere.
5

Schedule it

A schedule is a Markdown file in the agent’s schedules directory. Its YAML front matter sets cron, and its body is the prompt each firing sends.
agents/digest/schedules/daily.md
cron takes five fields and is read in UTC. This one fires at 09:00 UTC every day. The file name without .md is the schedule’s name.Commit agents/digest/schedules/daily.md, push main, and wait for that deployment to succeed before checking the installed schedule.Schedules come from Git. When a push to main deploys successfully, ContextLayer replaces the agent’s schedules with the files in that commit. Delete a file and push, and that deployment removes its schedule. List an agent’s provisioned schedules and Get a provisioned agent schedule show what is installed.Each firing starts a fresh hosted job with the file’s body as its prompt, using the agent’s instructions and resources from the latest commit on main. Who the job acts for follows the agent’s declaration:
  • An agent with no viewer-mode resources, like digest, runs one job for the app at each firing.
  • An agent with any viewer-mode connection, database or secret runs one job for each slate member at each firing, using that member’s viewer-mode resources. A person becomes a slate member when they complete the slate’s setup; ContextLayer then migrates their viewer-mode databases and installs the agent’s schedules for them in the background.
Check that the provisioned schedule list includes daily. Scheduled jobs appear in the agent’s job list under that schedule name. You now have a deployed agent, a verified manual result, and a recurring daily run.

What the hosted agent can use

Each hosted job gets a fresh Linux computer and these tools:
  • Coding tools. read, write, edit and bash work on the job’s computer. The computer has no internet access. Its files are scratch space: no other job sees them, and they last only as long as the job’s computer. Keep anything that must last in a database.
  • database_query. Runs parameterized SQL against a database the agent declares. Writes persist immediately and are visible to the app and to other jobs that use the same database. The database’s tables come from its migrations under databases/<slug>, which ContextLayer applies when the slate deploys.
  • Connection tools. For each connection the agent declares, the job gets that service’s actions from Composio, bound to the account assigned to the connection and named <slug>__<ACTION> after the connection’s slug. A job does not start until every connection the agent declares has an assigned account. Connect an account with the CLI’s accounts add command and, after you push, assign it with the connections command; each command’s --help shows how.
The model is not offered connection tools directly. It finds them through Code Mode, which searches and describes the job’s tools, and calls them from short scripts. Those scripts run in a sandbox that reaches only the job’s own tools, including database_query and the coding tools. The model can also call database_query and coding tools directly.

Try it locally

To test the authored instructions against your local notes, run this from the checkout:
This uses the Claude Agent SDK, your own Claude authentication, and the checkout’s local database. It starts the local development server and runs in the checkout; it does not create a hosted job or test the hosted provider secret. The declared hosted model settings do not configure this local runtime. Use a hosted job to verify the deployed database, the saved provider credential, and hosted scheduling. Use a local run while developing instructions against local data.