No description
  • TypeScript 96.2%
  • JavaScript 3.1%
  • Dockerfile 0.4%
  • Shell 0.3%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Morten Olsen f5144fa967
All checks were successful
ci/woodpecker/push/draft-release Pipeline was successful
ci/woodpecker/push/compliance Pipeline was successful
ci/woodpecker/push/quality Pipeline was successful
ci/woodpecker/push/image Pipeline was successful
docs: a README with a getting-started guide, and running a server
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.
2026-11-04 10:35:56 +01:00
.woodpecker feat: expose scripts over HTTP and MCP through triggers 2026-11-04 09:19:20 +01:00
docs docs: a README with a getting-started guide, and running a server 2026-11-04 10:35:56 +01:00
packages feat: scripts can return a Response, and API triggers can take GET 2026-11-04 10:17:14 +01:00
scripts feat: local script runs and the client version check 2026-11-03 23:48:35 +01:00
skills/taskspool docs: a taskspool skill for agents working in a project 2026-11-04 10:32:46 +01:00
.dockerignore fix: build the server image in CI 2026-11-03 23:15:04 +01:00
.gitignore feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
.prettierrc feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
.u8.json feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
AGENTS.md docs: install the skill from the public HTTPS URL 2026-11-04 10:33:33 +01:00
CLAUDE.md docs: AGENTS.md with our way of working and gotchas 2026-11-04 09:57:06 +01:00
Dockerfile feat: scripts export main, with schemas from their types 2026-11-04 07:37:59 +01:00
eslint.config.mjs feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
GLOSSARY.md feat: scripts can return a Response, and API triggers can take GET 2026-11-04 10:17:14 +01:00
mise.toml feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
package.json feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
pnpm-lock.yaml feat: expose scripts over HTTP and MCP through triggers 2026-11-04 09:19:20 +01:00
pnpm-workspace.yaml feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
README.md docs: a README with a getting-started guide, and running a server 2026-11-04 10:35:56 +01:00
renovate.json feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
Taskfile.yml feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00
vitest.config.ts feat: taskspool server, CLI and script client 2026-11-03 23:02:35 +01:00

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.yaml sidecar: 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 taskspool command 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-world shows when it fires next and what happened last time.

  • Give it a secret: printf '%s' "$API_KEY" | taskspool secret set hello-world API_KEY, list API_KEY under secrets: in the sidecar, and read it with getSecret('API_KEY') from the taskspool client 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: api or - type: mcp to its triggers, then give the caller a token limited to that script with taskspool token create hello-world my-app --script scripts/hello. The endpoint is POST /p/hello-world/api/scripts/hello, and /p/hello-world/api/openapi.json describes it.

  • Let your coding agent work in the project: npx skills add https://code.olsen.cloud/morten-olsen/taskspool.git installs 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.