Browse docs (19)

Agent Skills Guide

2,559 words Β· 13 min read Β· 15 sections

Overview

Skills are how you teach MicroGemAgent to respond to your infrastructure. A skill is a reusable unit the agent can read for guidance, run as code, or fire automatically when an incident matches a pattern. They all live in one library at /agent/skills, share stats and storage, but behave differently at runtime.

This guide explains the three skill types in depth, then gives a complete, copy-pasteable reference for every runbook action type and its parameters.

The three skill types

TypeWhat it isWhen it runsTier
πŸ“– KnowledgeA markdown playbook for human (or agent) judgment. No code executes.Matched into the agent's context automatically β€” scans semantically match your playbooks against the active problem signals, and chat finds them by meaning as well as keywords.All
⚑ ExecutableSandboxed JavaScript with platform helpers (helpers.postgres, helpers.http, …).When invoked from chat or another skill. New scripts start quarantined (approval required).Pro+
πŸ“‹ RunbookA pattern-matched action handler that calls one bundle action type (http_call, pm2_restart, …) with parameters you bind.Automatically when an incident or health-check summary matches the regex β€” subject to approval, cooldown, and the circuit breaker.All (some action types are Pro/Team)

Create any of them from /agent/skills β†’ New Skill.

Runbook anatomy

A runbook has these fields (the form at /agent/skills/new/runbook):

  • Name β€” human label, e.g. "Restart API workers on connection-refused".
  • Category β€” free-text grouping (restart, cache, rollback, …). Cosmetic.
  • Source *(optional)* β€” only fire when the triggering event came from this product (e.g. pulseguardplus). Blank = any source.
  • Trigger pattern β€” the regex that decides when this runbook is relevant (see below).
  • Trigger scope β€” which event stream the pattern is tested against.
  • Action type β€” *what the runbook does* (the executor). This is the field that determines the parameter shape.
  • Action parameters β€” the inputs for that action type. The form shows typed fields for exactly the parameters your selected action type reads (with per-field hints); an Edit as JSON toggle is there for power users. Parameters are shape-checked when you save, so a mismatch can't sneak through to execution time.
  • On success / On failure *(optional)* β€” chain a follow-up skill, e.g. restart on match, then run a health-check skill on success to confirm recovery. Chained runs pass through the same approval rails.
  • Cooldown / Circuit threshold / Circuit reset β€” the safety rails.

There's also a Test it box under the trigger pattern: paste a sample incident title and see immediately whether the runbook would fire on it (and whether your pattern is matching as a regex or falling back to substring).

Triggers: pattern, scope, and source

Trigger pattern is matched case-insensitively against the incident or health-check summary. If the string isn't a valid regex, it falls back to a plain substring match. Examples:
  • api.*(down|unresponsive|500|502|503) β€” API incidents with those signals.
  • connection refused.*postgres β€” Postgres connection failures.
  • disk.*(full|90%|95%) β€” disk-pressure alerts.

Trigger scope picks the stream:
  • incident β€” fires on incident summaries (the common case).
  • health_check β€” fires on health-check failures (more granular, pre-incident).
  • manual_only β€” never auto-fires; you click Execute by hand. Use this while testing a new runbook.

Source is an optional extra filter β€” set it to a product slug to scope the runbook to events from that product only.

> A runbook that auto-fires still passes through approval, cooldown, and the circuit breaker before anything executes. manual_only + a human click is the safest way to dry-run a new runbook.

How action type relates to parameters

This is the single most important concept, and the most common source of confusion.

The action type selects which executor runs, and each executor reads a fixed, specific set of JSON keys. Everything else in the parameters box is ignored. There are only two shapes:
Action typeReadsIgnores everything else
http_call{ url, method, headers, body, contentType, timeout }βœ“
every other (platform) action{ "target": "…" } (+ optional pinnedData)βœ“

So if you pick pm2_restart but supply an http_call-shaped body (url, method, body), the dispatcher ignores all of it, looks for target, finds none β€” which used to fail at execution time with:

> Action 'pm2_restart' requires a 'target' param

The runbook editor now makes this hard to get wrong: it renders typed fields for exactly the keys your selected action type reads, and the save is shape-validated β€” missing required parameters or an invalid target format are rejected when you save, not when the runbook fires at 3am. If you edit in JSON view instead, keys the action type doesn't read are flagged as warnings.

`http_call` β€” outbound HTTP webhook

The flexible escape hatch: POST/GET/PUT/PATCH/DELETE to any URL. Use it to drive your own internal endpoints, a CI/CD webhook, PagerDuty, Cloudflare, the GitHub API β€” anything reachable over HTTP.

Parameters:
KeyRequiredNotes
urlβœ“Must be http:// or https://. Behind an SSRF guard (no internal/metadata IPs).
methodβ€”GET / POST / PUT / PATCH / DELETE. Default POST.
headers—Object of string→string, or null.
bodyβ€”String. Only sent for POST/PUT/PATCH.
contentTypeβ€”Default application/json.
timeoutβ€”Seconds, default 30, max 120.
Real example β€” restart a PM2 app via your own internal deploy service:
{
  "url": "https://ops.internal.example.com/pm2/restart",
  "method": "POST",
  "headers": { "Authorization": "Bearer YOUR_TOKEN" },
  "body": "{ \"app\": \"api\" }",
  "contentType": "application/json",
  "timeout": 30
}

The response (status, first 100 KB of body, redacted headers) is captured on the execution record. Authorization/cookie/token response headers are redacted automatically.

> Templating: http_call sends body and headers verbatim β€” there is no {{variable}} substitution from the incident. The only placeholder the agent resolves is {{SECRET:name}}, and only inside credentials (not action parameters). If you need the failing app's name in the body, use a platform action instead, or a static body.

Platform actions β€” the `target` model

Every non-http_call action runs through the platform's integration layer (SSH, the AWS/GitHub SDKs, kubectl, redis-cli, etc.) and takes a single target string. The format of target is specific to each action and is validated before execution (bad targets are rejected, not shell-injected). A few actions also accept a pinnedData object for a second argument.

Below is the complete reference, grouped by system, with a real example for each.

Process & host

// pm2_restart β€” one PM2 process. target = "process" or "host:process"
{ "target": "api" }
{ "target": "prod-1:api" }

// pm2_restart_all β€” every PM2 process on a host. target = hostname
{ "target": "prod-1.internal" }

// systemctl_restart β€” a systemd unit (needs sudo NOPASSWD on the host)
{ "target": "nginx" }

Docker

// docker_restart β€” restart a container. target = "container" or "host:container"
{ "target": "my-container" }

// docker_pull_restart β€” pull the image, then restart
{ "target": "my-container" }

// docker_compose_up β€” recreate a compose project. target = compose file path
{ "target": "/srv/app/docker-compose.yml" }

Kubernetes

// kubectl_rollout_restart β€” rolling restart.
// target = "namespace/name" or "namespace/resourceType/name"
{ "target": "production/web" }
{ "target": "production/statefulset/db" }

// kubectl_scale_deployment β€” scale to N replicas.
// target = "namespace/deployment"; replica count goes in pinnedData
{ "target": "production/web", "pinnedData": { "replicas": 3 } }

PostgreSQL

// pg_cancel_query β€” cancel a backend (SIGINT-equivalent). target = backend PID
{ "target": "12345" }

// pg_terminate_query β€” terminate a backend (harder kill). target = backend PID
{ "target": "12345" }

Redis

// redis_del_key β€” DEL a single exact key (no globs)
{ "target": "cache:session:abc123" }

// redis_flushdb β€” FLUSHDB a whole logical DB. target = db number 0-15
{ "target": "1" }

AWS

// ec2_reboot β€” reboot an instance. target = instance id
{ "target": "i-0123456789abcdef0" }

// ecs_force_deploy β€” force a new deployment. target = "cluster/service" or "service"
{ "target": "my-cluster/my-service" }

// aws_lambda_update β€” re-point an alias for instant rollback. (Team tier)
// target = "function:alias"; the version to point at goes in pinnedData
{ "target": "my-fn:prod", "pinnedData": { "targetVersion": "42" } }

// aws_rds_reboot β€” reboot an RDS instance. target = instance identifier. (Team tier)
{ "target": "my-db-instance" }

GitHub

// github_rerun_workflow β€” re-run a workflow run. target = numeric run id
{ "target": "1234567890" }

// github_rollback β€” redeploy the commit before HEAD.
// target is the literal string "previous"; the agent resolves the SHA at pin time
{ "target": "previous" }

// github_workflow_dispatch β€” trigger a new run with inputs.
// target = workflow filename or id; ref + inputs go in pinnedData
{ "target": "deploy.yml", "pinnedData": { "ref": "main", "inputs": { "env": "prod" } } }

CDN & read-only

// cloudflare_cache_purge β€” purge whole zone or specific URLs
{ "target": "everything" }
{ "target": "https://example.com/a.js, https://example.com/b.css" }

// health_check_url β€” read-only HTTP probe (the only non-destructive action type).
// Pair it with a fix: "restart, then probe /health to confirm recovery."
{ "target": "https://api.example.com/health" }

> pinnedData carries a snapshot taken when the action is proposed and re-verified at execution time (e.g. the Postgres PID still belongs to the same query, the rollback SHA hasn't moved). For runbooks you author by hand, supply it inline as shown for kubectl_scale_deployment, aws_lambda_update, and github_workflow_dispatch.

Credentials & prerequisites

Platform actions need the matching integration configured for your team (decrypted from the credential vault at execution time):

  • SSH for pm2_*, systemctl_restart, docker_* (via the host).
  • AWS keys for ec2_*, ecs_*, aws_lambda_update, aws_rds_reboot.
  • GitHub token for github_*.
  • Postgres connection for pg_*.
  • Redis connection for redis_*.
  • Cloudflare token + zone for cloudflare_cache_purge.
  • Kubernetes config for kubectl_*.

Configure these under /agent/settings (integrations). Credential strings can reference team secrets with {{SECRET:name}} (managed at /team/secrets). http_call needs nothing but a reachable URL.

Safety: cooldown & circuit breaker

Three numbers protect you from a runbook that fires too often or keeps failing:

  • Cooldown (min) β€” after a successful run, the same runbook won't re-fire for this many minutes. Stops an api down pattern from restarting a process every 60 seconds while it's still recovering.
  • Circuit threshold β€” after this many consecutive failures, the breaker opens and the runbook stops auto-firing entirely.
  • Circuit reset (min) β€” how long the breaker stays open before it allows another attempt.

Sensible defaults: cooldown 5–15, threshold 3, reset 60. A runbook skipped by either gate records a gate_skipped event so you can see why nothing happened.

Safety: trust & approval

Whether a fire needs human approval depends on three things:

1. The action type. Anything that changes state is destructive and always requires approval, regardless of trust level: http_call, pm2_restart, pm2_restart_all, ec2_reboot, ecs_force_deploy, docker_restart, docker_pull_restart, docker_compose_up, pg_cancel_query, pg_terminate_query, github_rollback, github_rerun_workflow, github_workflow_dispatch, kubectl_rollout_restart, kubectl_scale_deployment, systemctl_restart, cloudflare_cache_purge, redis_del_key, redis_flushdb, aws_lambda_update, aws_rds_reboot. The one read-only exception is health_check_url.

2. The skill's trust level & override. New executable scripts start quarantined; reviewed skills graduate to validated/trusted. A per-skill approval override can force approval always or skip it (never) β€” use never only for a genuinely idempotent, read-only http_call.

3. The team's approval mode (strict / standard / trusted), set in agent settings. strict requires approval for everything; trusted lets validated non-destructive skills run unattended.

When approval is required, the agent posts an AgentNotification with the exact action + target; a human approves or rejects, and the decision is audited.

Executable skills

Executable skills are JavaScript functions that run in a locked-down sandbox (CPU/time/memory/op limits) with a helpers object bound to your team's context:

  • helpers.postgres β€” parameterized queries (never string-interpolated SQL).
  • helpers.http β€” SSRF-guarded fetch.
  • helpers.ssh β€” run commands on a configured host.
  • helpers.aws, helpers.github, helpers.docker, helpers.pm2 β€” SDK-backed actions.
  • helpers.memory β€” read/write the agent's platform memory.
  • helpers.health β€” run health checks.
  • helpers.skills, helpers.sessions, helpers.notifications β€” read agent state.
  • helpers.proposeAction β€” propose a gated fix for approval.
  • helpers.parse, helpers.format, helpers.crypto β€” pure utilities.

Scripts are validated before they run (which helpers they call, whether any are destructive), and start in quarantine so a new script can't act unattended until you've reviewed it. Executable skills are a Pro+ capability.

Self-healing on failure: when a validated script keeps failing in production (5+ failures, >40% failure rate), it's demoted back to quarantine β€” and the agent reads the actual runtime errors and proposes a corrected version. The revision goes through the same static validator as a human edit, lands as a new entry in version history (the failing version is one click to restore), stays quarantined until it re-earns trust through clean runs, and you get a notification to review the change. If the agent judges the failures environmental (credentials, network) rather than a code bug, it tells you that instead of rewriting anything.

Knowledge skills

The simplest type: a markdown procedure. During watchdog / deep / incident scans, the agent semantically matches your playbooks against the live problem signals (unresolved incidents, failing jobs, active alerts) and reasons with your procedure in hand β€” so instead of guessing, it follows your written playbook ("if the queue is backed up, check X, then Y, then page Z"). In chat, search_skills finds them by meaning as well as keywords. No code runs, nothing needs approval, available on every tier. Great for encoding institutional knowledge the agent should apply but shouldn't automate.

Lifecycle: how a skill runs

1. Match β€” an incident/health-check summary arrives; the agent finds skills whose trigger pattern (and scope/source) match.

2. Gate β€” for runbooks: tier check β†’ daily-fix cap β†’ cooldown β†’ circuit breaker β†’ approval. Any gate can skip or pause execution (recorded as gate_skipped or awaiting_approval).

3. Execute β€” the bundle's executeAction(actionType, params) runs http_call or dispatches the platform action; executable skills run in the sandbox; knowledge skills are injected into context.

4. Record β€” status, output, duration, and helper calls are written to the execution log, streamed live to the UI over SSE while the skill runs.

Starter library

Every team is seeded with ten manual-only http_call runbooks as fill-in-the-blank shapes (placeholder example.com URLs that the SSRF guard rejects until you replace them): Restart PM2 process, Force PostgreSQL vacuum, Flush Redis cache, Drain Kubernetes node, Rotate AWS access key, Roll back last deploy, Restart Docker container, Purge Cloudflare cache, Scale ECS service, and Page on-call escalation. They're the fastest way to see a working runbook shape β€” open one, swap the URL/body for your own, and either keep it manual or give it a trigger pattern.

Quick tips

  • Test with manual_only first, then add a trigger pattern once you trust the action. Use the Test it box to check your pattern against a real incident title before saving.
  • Start from an existing skill when you can β€” every skill has a Clone button on its detail page; cloning a seeded template and swapping the target beats a blank form.
  • Describe it in chat β€” the agent can draft a runbook for you ("when the API returns 502s, restart the pm2 app api"); the draft lands in quarantine for your review.
  • timeout on http_call is in seconds (max 120), not milliseconds.
  • For anything stateful, keep the cooldown β‰₯ the time the system needs to recover, or you'll thrash.
  • Prefer a platform action over an http_call when one exists β€” you get target validation and you don't have to stand up a webhook.