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! Periodically schedule a smart assistant! Write a servlet that schedules tasks, then accidentally implement Skynet!

Registration

Tool Availability

Tasks inherit the tools and configuration installed to your profile. At present, you can only have one user profile. In the near future you'll be able to 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.

Runners

When registering a task you must select a runner. We currently support OpenAI. When you've selected a runner, you can configure it further: for example, OpenAI requires a prompt and a model (we currently support gpt-4o.)

The prompt may contain {{ bracketed }} items to be expanded at run-time.

Note: only data in the shape of Map<string, string> from the trigger request is supported. Don't use any nested objects or array values.

The runner requires a valid OpenAI key to be specified. This key is stored encrypted at rest and is decrypted for use during task execution.

Task Execution (AKA 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/profiles/~/default/tasks

Create a task

PUT /api/profiles/~/default/tasks/: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>"
}
}

Trigger a run

PUT /api/profiles/~/default/tasks/:task/runs/:run

Trigger a run. This is an idempotent request.

Note: The :run parameter can be whatever you want. Just make sure it's a unique value.

Takes the following body:

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

List runs

GET /api/profiles/~/default/tasks/:task/runs

Get the status of a run

GET /api/profiles/~/default/tasks/:task/runs/: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.

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"
}