Skip to main content
Managed Deep Agents can run agents on a cron schedule. When you deploy the project, mda deploy provisions each schedule as a LangSmith cron after the deployment is live.
Managed Deep Agents is in public beta and available on LangSmith Cloud in the US region only.

Project structure

Schedule declarations live in the project-level schedules/ directory, with one schedule per file:

Add a schedule

The file name becomes the managed schedule name. The schedule module must export a named schedule declaration.
schedules/daily-digest.ts

Configure schedule input

Each schedule must define exactly one of:
  • prompt: A natural-language prompt. Managed Deep Agents converts it to a user message when the cron fires.
  • input: A structured LangGraph input object. Use this when you need to pass custom graph input instead of a single prompt.
schedules/nightly-sweep.ts
cron must be a standard five-field cron expression: minute, hour, day of month, month, and day of week. If timezone is omitted, LangSmith crons use UTC.

Choose thread behavior

Schedules use ephemeral threads by default. Managed Deep Agents creates a fresh thread for each run and asks LangSmith to delete that temporary thread after the run completes. Use a persistent thread only when scheduled runs should accumulate durable thread state across invocations. A persistent thread ID must be the UUID of a thread that already exists on the deployment. Managed Deep Agents passes the value straight to the Agent Server, which rejects any ID that is not a UUID.

Create the persistent thread

Create the thread before you deploy the schedule. Open the deployment in LangSmith Studio, create a new thread, and copy its thread ID. mda deploy prints the deployment URL, and LangSmith lists it on the deployment page. Neither Managed Deep Agents nor the mda CLI creates the thread, so this is a one-time manual step for each persistent schedule.

Declare the persistent schedule

Use that thread ID in the schedule declaration.
The following example requires durable memory.
schedules/nightly-memory.ts

Deliver results to Slack

Set deliverTo to post the final response through a configured Slack channel. Use a Slack channel ID because scheduled runs have no originating thread.
Schedule delivery requires managed-deepagents version 0.4.0 or later.
schedules/monday-greeting.ts
The Slack bot must have access to the destination.

Use static declarations

Schedule declarations are extracted at compile time. Keep schedule configuration statically serializable:
  • Use literals, arrays, objects, and references to top-level literal constants.
  • Do not read environment variables, call functions, spread objects, or compute schedule values dynamically.
  • Put dynamic behavior in the agent, tools, middleware, or runtime context instead.

Test schedules locally

mda dev compiles schedules/ and lists each schedule in its startup banner, but it does not provision them. Schedules run only on a deployment.
Schedules never fire under mda dev. The local server reports no error, so a schedule that is listed at startup is still inactive.
To test the agent behavior a schedule triggers, send the schedule’s prompt or input to the agent directly in local Studio. To test the schedule itself, deploy the project to a development deployment.

Deploy schedules

Test the project locally with mda dev, then deploy it with mda deploy. Open deployment traces in LangSmith to inspect model calls, tool calls, errors, and latency. When the deployment reaches DEPLOYED, mda deploy deletes the cron jobs that earlier schedules/ declarations created and creates cron jobs for the current declarations. Removing a local schedule file and redeploying removes the corresponding managed cron. Schedules created at runtime are unaffected.
If you deploy with --no-wait, the CLI triggers the remote build and exits before the deployment reaches DEPLOYED, so it does not reconcile schedules during that invocation. Run mda deploy without --no-wait when adding, changing, or removing schedules.

Create schedules at runtime

Runtime schedules require managed-deepagents 0.9.0 or later.
Declarations in schedules/ are fixed when you deploy. The schedules API creates schedules while the agent runs, so the agent can set up recurring or one-time work in response to a conversation. Call it from a tool or from middleware. Each schedule belongs to the current user or to the agent. The agent reaches this API only through tools that you write. Expose the calls the agent needs, and leave out the ones it should not reach. When a tool creates a schedule during a channel run, such as a Slack conversation, the schedule inherits that channel. Each run posts its final answer back to it. A new thread posts a new Slack message, and the current thread replies in the existing Slack thread. newThread decides which of the two a schedule uses.

Create a recurring schedule

remind_me gives the agent a way to set up a recurring reminder for the person it is talking to. The agent calls it with the prompt to run and a cron expression for how often to run it. Each time the cron fires, a new run starts with that prompt as its user message. The agent decides what each scheduled run is asked to do.
tools/schedules.ts
Asked in Slack to send a standup reminder every weekday, the agent calls remind_me. It passes a prompt of its own wording and the cron 0 9 * * 1-5. Each weekday run posts its answer to that Slack conversation as a new message, because cron schedules default to a new thread.

Create a one-time schedule

Pass at in place of cron for work that runs once. follow_up_later gives the agent a way to set a single follow-up, such as checking a deploy after it finishes.
tools/follow-up.ts
A one-time schedule defaults to the current thread, so its run continues the conversation that created it and replies in the same Slack thread.

Create options

object
required
{ type: "user" } selects the authenticated person of the current run, and the schedule runs as that person. An optional id must match that person. { type: "agent" } selects the schedules the agent owns, which run as the agent’s service identity.
string
A five-field cron expression for a recurring schedule. Give exactly one of cron and at.
Date | string
A Date, or an ISO 8601 timestamp that ends with Z or a UTC offset. The schedule runs once. The runtime rounds it up to the next whole minute. It must be at least one minute and at most 365 days in the future.
string
default:"UTC"
An IANA time zone for cron, such as America/Los_Angeles. Do not pass it with at.
string
A prompt that each run receives as a user message. Give exactly one of prompt and input.
object | object[]
A structured LangGraph input for each run.
boolean
true starts each run on a new thread. false continues the current thread. Defaults to true with cron and false with at.
boolean
default:"false"
Create the schedule without running it.
object
JSON metadata for your own use. Keys that start with mda_ are reserved.

Manage schedules

list, get, update, and delete cover the rest of a schedule’s life. Expose them as tools when the agent should manage the schedules it created. An agent with list and delete can answer “what reminders do I have?” and cancel one on request. Pause a schedule with update instead of deleting it when the person wants it back later.
update accepts cron, at, timezone, prompt, input, paused, and metadata. The channel and the thread choice are fixed at creation. list hides expired one-time schedules unless you pass includeExpired: true. For the agent owner, list and get also return the schedules in schedules/, which you change in code.

Troubleshoot schedules

  • must export a named schedule declaration: Export a top-level schedule from each file in schedules/.
  • must define exactly one of prompt or input: Add either prompt or input, but not both.
  • cron must be a standard 5-field expression: Use five cron fields, not seconds-based cron syntax.
  • schedule is not static: Replace computed values with literals or top-level literal constants.
  • failed to create cron for schedule: Open the deployment URL in LangSmith and confirm the deployed Agent Server is healthy.
  • Invalid thread ID: must be a UUID (HTTP 422): A persistent schedule declares a thread ID that is not a UUID. Replace it with the UUID of an existing thread. See Choose thread behavior.
  • A schedule does not run during local development: mda dev does not provision schedules. See Test schedules locally.

Next steps

Deploy an agent

Deploy and reconcile schedule changes.

CLI reference

Look up mda deploy flags and troubleshooting.