- TypeScript 96.2%
- JavaScript 3.1%
- Dockerfile 0.4%
- Shell 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The README says what taskspool is and walks from installing the CLI to a deployed, scheduled script. docs/running-a-server.md covers the image, its configuration, the identity provider and operating it. |
||
| .woodpecker | ||
| docs | ||
| packages | ||
| scripts | ||
| skills/taskspool | ||
| .dockerignore | ||
| .gitignore | ||
| .prettierrc | ||
| .u8.json | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| Dockerfile | ||
| eslint.config.mjs | ||
| GLOSSARY.md | ||
| mise.toml | ||
| package.json | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| renovate.json | ||
| Taskfile.yml | ||
| vitest.config.ts | ||
taskspool
A self-hosted script runner, in the spirit of Windmill but run from the terminal. Your scripts live in git repositories that the taskspool server hosts. Pushing to main deploys them, and they run in Deno on the server: by hand, on a schedule, as HTTP endpoints, or as tools for AI agents over MCP.
- A project is a git repository. Clone it, change scripts, push. The server checks every push (types, script shape, configuration) and refuses it whole when something is wrong, so what is deployed always type-checks.
- A script is a TypeScript file that exports
main. Its input and output types are its contract: callers' input is checked against them, and they describe the script to API clients and AI agents. - What starts a script is declared next to it, in a
.taskspool.yamlsidecar: cron schedules, an HTTP endpoint, an MCP tool. Every script can also be run by hand. - Secrets stay on the server. They are encrypted at rest, write-only, and each script reads only those its sidecar names.
- Runs are sandboxed. A run reads only its project and dependencies, gets a fresh environment, and never loads native code.
- API and CLI first. Everything is done from the
taskspoolcommand or the HTTP API; there is no web interface.
Getting started
You need Deno and Node.js locally, and a taskspool server to log in to (running one).
1. Install the CLI from the npm feed it is published to:
npm install -g @morten-olsen/taskspool-cli --@morten-olsen:registry=https://code.olsen.cloud/api/packages/morten-olsen/npm/
2. Log in. This opens your browser to sign in with the server's identity provider:
taskspool login --server https://taskspool.example.com
3. Create a project. This creates it on the server and clones it here with an example script:
taskspool project create hello-world
cd hello-world
scripts/hello.ts is a script because scripts/hello.taskspool.yaml sits next to it:
type Input = {
/** Who to greet; the world when left out */
name?: string;
};
/** Greets someone. */
export async function main(input: Input): Promise<{ greeting: string }> {
const greeting = `Hello, ${input.name ?? 'world'}!`;
console.log(greeting);
return { greeting };
}
4. Try it here, the way the server will run it:
taskspool exec hello-world --script scripts/hello.ts --input '{"name":"you"}'
5. Deploy it by pushing. taskspool git runs git with the CLI handling authentication, so the clone needs no git configuration:
git add -A && git commit -m "Start hello-world"
taskspool git push origin HEAD:main # remote: taskspool: main validated, deploying …
6. Run the deployed script, and watch its logs and result:
taskspool run hello-world scripts/hello --input '{"name":"you"}'
Next steps
-
Run it on a schedule: add a trigger to the sidecar and push.
triggers: - type: cron expression: '0 7 * * *' timezone: Europe/Copenhagen input: { name: morning }taskspool triggers hello-worldshows when it fires next and what happened last time. -
Give it a secret:
printf '%s' "$API_KEY" | taskspool secret set hello-world API_KEY, listAPI_KEYundersecrets:in the sidecar, and read it withgetSecret('API_KEY')from thetaskspoolclient package. Plain values go in variables:taskspool var set hello-world API_URL https://…. -
Call it over HTTP or from an AI agent: add
- type: apior- type: mcpto its triggers, then give the caller a token limited to that script withtaskspool token create hello-world my-app --script scripts/hello. The endpoint isPOST /p/hello-world/api/scripts/hello, and/p/hello-world/api/openapi.jsondescribes it. -
Let your coding agent work in the project:
npx skills add https://code.olsen.cloud/morten-olsen/taskspool.gitinstalls a skill that teaches it the deploy loop, the script contract and the sandbox. It is also the most complete guide to writing scripts.
taskspool --help lists every command, and taskspool <command> --help explains each.
Learn more
- The taskspool skill: writing scripts, sidecars and triggers, and calling exposed scripts.
- Running a server: the image, its configuration, and the identity provider.
- Decisions: why taskspool works the way it does, one decision per record.
- Glossary: the words taskspool uses, and what each means.
- Contributing: how work on taskspool itself is done.