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
- Install some tools to a profile
- Create a Task and attach a profile and a model provider
- 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"
}