Skip to main content

Working with Tasks

Tasks let you register prompts with a suite of installed servlets and trigger them on-demand in our infrastructure. Trigger a tool-using LLM from your web chat! Handle a webhook! Periodically schedule a smart assistant!

With Tasks, the prompt is the program. Prompts carry out your instructions, and intelligently use tools they are provided from their assigned profile.

Getting Started

  1. Install some tools to a profile
  2. Create a Task and attach a profile and a model provider
  3. Run the task!

Creating Tasks

Prompt

The prompt may contain {{ bracketed }} items to be expanded at run-time. For instance, with a payload of the shape:

{
"text": "hello",
"struct": {
"field": "content"
},
}

You could refer to text using {{ text }} or to field in struct using {{ struct.field }}.

Additionally, the special {{ @payload }} syntax expands to the entire contents of the payload. For an explainer of the syntax, refer to the Mustache manual.

Tool Availability

Tasks inherit the tools and configuration installed to your profile. You can create multiple profiles, including task-specific ones.

Servlets run by tasks do not have access to the file system but do have access to the network. For the stability of the service, we've blocklisted a number of URLs and IPs, so if you run into any issues please reach out to us on Discord.

Settings

When registering a task you must select a model provider. We currently support models by OpenAI and Anthropic.

Your Task may require a valid model provider API key to be specified. This key is stored encrypted at rest and is decrypted for use during task execution.

Task Execution (Runs)

Once you've registered a Task you can run it as many times as you like.

Triggering a run returns a URL that you can poll to track progress. The response from this URL contains log output from the run as well as structured messages exchanged with the runner. The messages are available in the results attribute of the response. The last message received will be marked with lastMessage, indicating the end of your Task run.

You control the name of the run -- attempting to re-trigger a run with the same name multiple times is idempotent.

You can trigger a task run with parameters, which will be interpolated into the prompt. For example, a task might specify a prompt like:

You are a research science assistant. Fetch content from `{{url}}` and analyze it for rigor. 

Track your concerns in the Notion database called "Science Yelling Bucket" in a new row containing the link and your reaction.

If you were to run the task with {"url": "https://www.drbronner.com/"}, if you have the Notion and Fetchs installed, you should see some reaction in your Notion database.

URLs You Can Use

This information will eventually migrate to the API docs. All URLs are authenticated with a Cookie header with a sessionId. Use npx --yes -p @dylibso/mcpx@latest gen-session to get a sessionId if you want to call these from the command line.

List tasks

GET /api/tasks/~/:profile

Create a task

PUT /api/tasks/~/:profile/:task

Create or update an existing task. You control the task name parameter.

Takes the following body:

{
"runner": "openai",
"openai": {
"prompt": "You cannot believe it is not butter. And yet you must react to the content from this url: `{{ url }}`.",
"model": "gpt-4o"
},
"settings": {
"key": "<an openai api token>"
}
}

Create a signed runner url

POST /api/tasks/~/:profile/:task/signed

Create a signed url. Returns {"url": "<signed url>"}. The signed url is sensitive data. Anyone that has it can execute task runs with your configured servlet installations on your behalf. Keep it secret! Keep it safe.

Trigger a run

POST <signed url>

Trigger a run. You can control idempotency using the run-id header.

Takes a JSON body; all top-level keys are interpolated into the task prompt.

{
"any": "key",
"or": "string",
"value": "works"
}

List runs

GET /api/runs/~/:profile/:task

Get the status of a run

GET /api/runs/~/:profile/:task/:run

Get the run data. Can be polled. The run starts in pending state and moves through running to a terminal state of either ready or error. The run may move back through the pending state as the run progresses.

Returns the following:

{
"name": "foo",
"status": "pending", // or "running", or "ready", or "error"
"results": [{
"msg": "hello world",
"time": 1737011633610,
"level": 30
}, {
"msg": "message",
"exchange": {
"role": "assistant",
"content": "Weena wonna wonga, Solo"
}
}, {
"msg": "final message",
"lastMessage": {
"role": "assistant",
"content": "<look at all this content>"
}
}],
"created_at": "2025-01-16T07:13:53.606Z",
"modified_at": "2025-01-16T07:13:53.606Z"
}