seristack

One YAML config. CLI command, HTTP endpoint, and MCP tool — all at once.

Seristack is a lightweight YAML-driven automation engine for DevOps, Platform, SRE, and Cloud teams. Define stacks once — run them locally, expose them as HTTP endpoints with per-stack authorization, or publish them as MCP tools for AI agents and IDEs.

Features

  • Run multiple command stacks from a single config
  • Repeat stacks with serial or concurrent execution
  • Define dependencies between stacks
  • Variable substitution using templates
  • Share output between stacks
  • Expose stacks as HTTP endpoints
  • Per-stack HTTP authorization via identity headers
  • Structured audit log for every execution
  • Run as an MCP server — stdio, SSE, streamableHTTP
  • Per-tool MCP authorization for SSE and streamableHTTP
  • Validate inputs with required, allowed, denied, and regex rules
  • Per-command timeouts using Go duration syntax
  • Works with mvdan shell (default), Bash, sh, and PowerShell

Why Seristack?

One stack, three interfaces

Use the same YAML stack as a local CLI command, an internal HTTP API, or an MCP tool for AI-enabled clients — all from the same config file.

Script-to-API without a backend

Wrap existing shell scripts and runbooks without writing a Flask, FastAPI, Express, or Go service for each operation.

MCP-native automation

Create AI-callable tools from YAML instead of hand-coding a custom MCP server. Supports stdio for Claude Desktop and Cursor, and streamableHTTP for remote clients.

Production-ready AuthZ

Restrict which users or groups can run which stacks using identity headers forwarded by nginx or Caddy. Works with any IdP — Entra ID, OCI IAM, GCP, AWS Cognito, Okta.

See it in action

Demo: running stacks via CLI, HTTP API, and MCP server with a Gemini AI agent — all from the same YAML config.

Installation

Mac and Linux (Homebrew)

brew install TechXploreLabs/tap/seristack

Linux (Release Archive)

curl -fsSL https://raw.githubusercontent.com/TechXploreLabs/seristack/main/install.sh | bash
OR
STEP 1

Download the latest release from GitHub:

VERSION=vX.X.X ARCH=amd64 # amd64 | arm64 curl -LO "https://github.com/TechXploreLabs/seristack/releases/download/${VERSION}/seristack_${VERSION#v}_linux_${ARCH}.tar.gz"
STEP 2

Extract the archive:

tar -xzf seristack_VERSION_linux_ARCH.tar.gz
STEP 3

Move to your PATH and set permissions:

sudo mv seristack /usr/local/bin/ sudo chmod +x /usr/local/bin/seristack
STEP 4

Verify installation:

seristack --help

Windows (Release Archive)

irm https://raw.githubusercontent.com/TechXploreLabs/seristack/main/install.ps1 | iex
OR
STEP 1

Download from GitHub Releases — look for seristack_VERSION_windows_ARCH.zip

STEP 2

Extract the zip file (Right click → Extract all, or use 7-Zip)

STEP 3

Move seristack.exe to a folder in your %PATH%

STEP 4

Verify in PowerShell:

seristack --help

Configuration

Sample YAML Configuration

stacks: - name: deploy description: Deploy the application to a target environment method: POST urlPath: /deploy matchAccess: ANY access: - headerName: "X-Auth-Request-Groups" headerValue: ["sre", "platform"] count: 1 timeouts: 10m executionMode: SEQUENTIAL vars: - name: env value: staging required: true allowed_value: [staging, production] - name: version required: true allowed_regex: regex("^[a-zA-Z0-9._-]+$") cmds: - | echo "Deploying {{.Vars.version}} to {{.Vars.env}}" kubectl set image deployment/app app={{.Vars.version}} - name: collect-metadata description: Produces JSON metadata for aggregation dependsOn: [deploy] count: 2 timeouts: 5m executionMode: SEQUENTIAL vars: - name: env value: staging cmds: - | echo "{\"index\": {{.Count.index}}, \"env\": \"{{.Vars.env}}\", \"status\": \"ok\"}" output: | echo '{{.Self.result}}' | grep "^{" | jq -s '{records: ., total: length}'

Running Stacks

1. Trigger all stacks

Run all stacks defined in the config file

seristack trigger -c config.yaml

2. Trigger a specific stack

Execute only a particular stack by name

seristack trigger -c config.yaml -s deploy \ --vars env=staging \ --vars version=v1.2.3

3. Start HTTP API server

Expose stacks as HTTP endpoints with audit logging

seristack run -c config.yaml \ --addr 127.0.0.1 --port 8080 \ --audit-log /var/log/seristack/audit.log

4. MCP server — stdio (Claude Desktop, Cursor, VS Code)

AI client spawns seristack as a subprocess — no port needed

seristack mcp --type stdio -c config.yaml

5. MCP server — streamableHTTP (remote clients, SDK apps)

Network-accessible MCP server with per-tool authorization and audit log

seristack mcp --type streamableHTTP \ --addr 127.0.0.1 --port 8081 \ --audit-log /var/log/seristack/mcp-audit.log

Production Security

Seristack executes shell commands — do not expose it directly to the public internet. Bind to 127.0.0.1 and place nginx or Caddy in front.

The reverse proxy handles TLS, authentication (JWT, API token, OAuth2), and rate limiting. Seristack handles per-stack authorization using identity headers forwarded by the proxy.

HTTP AuthZ

Restrict which groups or roles can execute each stack. Declare rules in YAML — works with any IdP through nginx or Caddy.

matchAccess: ANY access: - headerName: "X-Auth-Request-Groups" headerValue: ["sre", "platform"]

Audit log

Every stack execution logged as JSON — who ran it, what vars, success or failure, duration. Query with jq.

jq 'select(.success == false)' audit.log jq 'select(.identity["X-Auth-Request-Email"] == "alice@company.com")' audit.log

MCP server

For stdio: OS-level access control — whoever can run the binary has full access. For streamableHTTP and SSE: same access block applies per tool.

seristack mcp --type streamableHTTP \ --addr 127.0.0.1 --port 8081

Variable validation

All HTTP and MCP inputs validated before shell execution. Use allowlists — not denylists — for maximum protection.

vars: - name: env allowed_value: [staging, production] - name: version allowed_regex: regex("^[a-zA-Z0-9._-]+$")

Input Validation and Timeouts

Variable rules

Restrict incoming CLI, HTTP, and MCP inputs before commands run. Only vars declared in YAML can be overridden — undeclared keys are dropped.

  • required
  • allowed_value
  • denied_value
  • allowed_regex
  • denied_regex

Command timeouts

Each stack defines a per-command timeout using Go duration syntax. Default is 1h.

timeouts: 500ms timeouts: 30s timeouts: 5m timeouts: 1h timeouts: 1h30m timeouts: 2.5h

Support the Project

Star and contribute

If Seristack saves you from building custom internal automation APIs or MCP servers, consider starring the repository, opening issues, or contributing stacks and docs.

Issues

For new feature, discussion, vulnerabilties please report the issue.