{
  "data": {
    "category": {
      "area": "agent-runtime",
      "capabilities": [
        "hitl.approve",
        "hitl.ask",
        "hitl.handoff",
        "hitl.channels",
        "hitl.audit"
      ],
      "description": "Services that pause an agent to ask a person: approve an action, answer a question or take over a task, over Slack, email or a web inbox, then resume the agent with the answer. Compared on channels, routing, timeouts and audit.",
      "indexed": [
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/ausdata-abs-mcp.json",
          "kind": "mcp",
          "name": "abs-mcp",
          "slug": "ausdata-abs-mcp",
          "url": "https://www.anchorterminal.com/tools/ausdata-abs-mcp"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/adako-ads.json",
          "kind": "mcp",
          "name": "Adako: ad ops for AI assistants",
          "slug": "adako-ads",
          "url": "https://www.anchorterminal.com/tools/adako-ads"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/heera-agentimus.json",
          "kind": "mcp",
          "name": "agentimus",
          "slug": "heera-agentimus",
          "url": "https://www.anchorterminal.com/tools/heera-agentimus"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/blockventurechaincapital-bvcc-agent-wallet.json",
          "kind": "mcp",
          "name": "bvcc-agent-wallet",
          "slug": "blockventurechaincapital-bvcc-agent-wallet",
          "url": "https://www.anchorterminal.com/tools/blockventurechaincapital-bvcc-agent-wallet"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/clize.json",
          "kind": "mcp",
          "name": "Clize",
          "slug": "clize",
          "url": "https://www.anchorterminal.com/tools/clize"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/elicitly.json",
          "kind": "mcp",
          "name": "Elicitly",
          "slug": "elicitly",
          "url": "https://www.anchorterminal.com/tools/elicitly"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/lassare-ask.json",
          "kind": "mcp",
          "name": "Lassare",
          "slug": "lassare-ask",
          "url": "https://www.anchorterminal.com/tools/lassare-ask"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/1pass-logi-approval.json",
          "kind": "mcp",
          "name": "logi-approval",
          "slug": "1pass-logi-approval",
          "url": "https://www.anchorterminal.com/tools/1pass-logi-approval"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/monnet-mcp.json",
          "kind": "mcp",
          "name": "monnet.ai MCP server",
          "slug": "monnet-mcp",
          "url": "https://www.anchorterminal.com/tools/monnet-mcp"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/proof-mcp-server.json",
          "kind": "mcp",
          "name": "Proof Holdings",
          "slug": "proof-mcp-server",
          "url": "https://www.anchorterminal.com/tools/proof-mcp-server"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/selda.json",
          "kind": "mcp",
          "name": "Selda",
          "slug": "selda",
          "url": "https://www.anchorterminal.com/tools/selda"
        },
        {
          "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/socialchamp-mcp.json",
          "kind": "mcp",
          "name": "Social Champ",
          "slug": "socialchamp-mcp",
          "url": "https://www.anchorterminal.com/tools/socialchamp-mcp"
        }
      ],
      "indexedCount": 12,
      "json": "https://www.anchorterminal.com/categories/human-in-the-loop.json",
      "name": "Human approval \u0026 handoff",
      "slug": "human-in-the-loop",
      "test": "An agent asks for approval of a risky action over two channels and gets one approval, one rejection and one timeout. We check the routing, what the approver sees, how the answer reaches the agent and what is logged.",
      "title": "Human approval and handoff for AI agents",
      "toolCount": 7,
      "tools": [
        "temporal",
        "trigger-dev",
        "inngest",
        "permit-mcp-gateway",
        "orkes-conductor",
        "pushary",
        "gotohuman"
      ],
      "url": "https://www.anchorterminal.com/categories/human-in-the-loop"
    },
    "tools": [
      {
        "slug": "temporal",
        "name": "Temporal",
        "vendor": "Temporal Technologies",
        "vendorUrl": "https://temporal.io",
        "kind": "platform",
        "category": "human-in-the-loop",
        "summary": "Open-source durable execution platform with SDKs in Go, Java, Python, TypeScript, .NET, PHP, Ruby and Rust, run yourself or on Temporal Cloud.",
        "url": "https://www.anchorterminal.com/tools/temporal",
        "markdownUrl": "https://www.anchorterminal.com/tools/temporal.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/temporal.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/temporal.json",
        "repo": "https://github.com/temporalio/temporal",
        "license": "MIT",
        "transports": [
          "http"
        ],
        "packages": [
          {
            "registry": "pypi",
            "name": "temporalio"
          },
          {
            "registry": "npm",
            "name": "@temporalio/client"
          }
        ],
        "auth": "mixed",
        "authNotes": "Temporal Cloud clients and workers authenticate with an API key or mTLS certificates per namespace. A self-hosted server has whatever auth you configure.",
        "pricing": "usage",
        "pricingNotes": "Temporal Cloud bills Actions, storage and a plan. Developer has no base fee and adds 10 per cent of usage spend. Business is the greater of $500 a month or 10 per cent of usage, with 2.5 million Actions, 2.5 GB active and 100 GB retained storage included. Enterprise and Mission Critical are priced annually through sales. Actions cost $50 per million, and from Business up the price steps down with volume to $25 per million between 100 and 200 million. Active storage is $0.042 and retained $0.00105 per GB-hour (https://docs.temporal.io/cloud/pricing). Every Signal and every timer, including the implicit one behind a wait with a timeout, counts as an Action (https://docs.temporal.io/evaluate/cloud/actions). New Cloud accounts get $150 of credits for 90 days, and the pricing page says a card is required (https://temporal.io/pricing). Self-hosting is free under MIT.",
        "priceSummary": "$0.05 / 1k calls",
        "where": "local",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": null,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://docs.temporal.io/design-patterns/approval",
        "llmsTxt": "https://docs.temporal.io/llms.txt",
        "openapi": "https://github.com/temporalio/api/blob/master/openapi/openapiv3.yaml",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "hitl.audit",
          "agent.durable",
          "automation.workflows",
          "automation.code"
        ],
        "tags": [
          "hosted",
          "self-hosted",
          "open-source",
          "llms-txt",
          "python",
          "typescript",
          "enterprise"
        ],
        "lastRelease": "2026-09-15",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 77.2,
          "grade": "BB",
          "agentReady": true,
          "rank": 21,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 1,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 85,
            "maintenance": 90,
            "payments": 20,
            "reliability": 85,
            "schema": 91,
            "security": 86,
            "transparency": 70
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Waits of any length with a timeout survive worker restarts and deploys. No reviewer inbox, notifications or routing, so the human side is all your code.",
          "strengths": [
            "Waits of any length with a timeout survive worker restarts and deploys",
            "Each workflow's event history is an audit trail of every signal, without extra logging",
            "Contractual SLA of 99.9 per cent per namespace, 99.99 with High Availability",
            "Namespace-scoped API keys with RBAC, expiry warnings and a read-only role",
            "MIT-licensed server and SDKs in eight languages, with OpenAPI for the HTTP API"
          ],
          "weaknesses": [
            "No reviewer inbox, notifications or routing, so the human side is all your code",
            "Needs running workers and a Temporal service before the first approval",
            "Signals and timers are billed Actions on Cloud, and the $150 trial credit needs a card",
            "History caps of 51,200 events or 50 MB per run push long agent loops towards Continue-As-New",
            "Control-plane audit logs leave out data-plane events such as workflow starts and terminations"
          ],
          "agentNotes": [
            "Put the decision in a typed Signal payload (approver, decision, comments, timestamp) instead of a bare boolean",
            "Always wait with a timeout and treat the timeout path as a rejection or an escalation on purpose",
            "Use the workflow ID as the approval ID, so the reviewer's tool only needs one value to send the Signal",
            "Use an Update instead of a Signal when the approver's tool needs an acknowledgement back",
            "Expect `ResourceExhausted` under load and let the SDK retry it, since signals are throttled last"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 8,
          "avgRating": 3.6,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "BB",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 77.2
            }
          ],
          "editorialScores": {
            "ergonomics": 85,
            "maintenance": 90,
            "payments": 20,
            "reliability": 85,
            "schema": 91,
            "security": 86,
            "transparency": 75
          },
          "provenanceScore": 65
        },
        "connect": {
          "install": "pip install temporalio"
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/temporal"
        },
        "alsoIn": [
          "workflow-automation"
        ],
        "area": "agent-runtime",
        "unitPrices": [
          {
            "item": "Actions, first 5 million",
            "unit": "1k-calls",
            "usd": 0.05,
            "note": "$50 per million. Each Signal and timer is an Action"
          },
          {
            "item": "Business plan minimum",
            "unit": "month",
            "usd": 500,
            "note": "Or 10 per cent of usage if higher, 2.5 million Actions included"
          }
        ],
        "provenance": {
          "legalEntity": "Temporal Technologies Inc.",
          "domain": "temporal.io",
          "domainRegistered": "",
          "endpointOnVendorDomain": true,
          "terms": "",
          "privacy": "https://temporal.io/global-privacy-policy",
          "statusPage": "https://status.temporal.io",
          "changelog": "https://github.com/temporalio/temporal/releases",
          "securityTxt": "unknown",
          "checked": "2026-10-01",
          "notes": [
            "The legal entity is from the server's MIT licence and the docs footer.",
            "status.temporal.io runs on Atlassian Statuspage with components for 14 AWS regions, 6 GCP regions and 8 global services. Its history page renders with JavaScript and we read only the recent incidents on the front page.",
            "Server v1.32.0 is on a commit dated 2026-09-10, with patch releases v1.31.3 (2026-09-14) and v1.30.7 (2026-09-15). A v1.33.0 release candidate was tagged on 2026-09-29.",
            "The privacy policy (updated 2026-04-22) names Temporal Technologies Inc., 2337 148th Ave NE #1335, Bellevue, WA 98007. We couldn't read the terms, security.txt or RDAP on 2026-10-01."
          ],
          "score": 65
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/temporal.json",
        "live": {
          "slug": "temporal",
          "vendorStatus": {
            "page": "https://status.temporal.io",
            "indicator": "none",
            "summary": "All Systems Operational",
            "checkedAt": "2026-10-05T00:54:06.983429941Z"
          },
          "versions": [
            {
              "registry": "github",
              "name": "temporalio/temporal",
              "version": "v1.32.0",
              "released": "2026-09-11",
              "seenAt": "2026-10-04T16:41:45.737977886Z"
            },
            {
              "registry": "npm",
              "name": "@temporalio/client",
              "version": "1.24.0",
              "seenAt": "2026-10-04T16:41:44.913799491Z"
            },
            {
              "registry": "pypi",
              "name": "temporalio",
              "version": "1.34.0",
              "released": "2026-09-30",
              "seenAt": "2026-10-04T16:41:44.726624016Z"
            }
          ],
          "githubStars": 23462,
          "npmWeekly": 5211272,
          "pypiWeekly": 8895388,
          "securityTxt": {
            "url": "https://temporal.io/.well-known/security.txt",
            "state": "valid",
            "expires": "2027-01-15T00:00:00Z",
            "checkedAt": "2026-10-04T15:15:43.220669153Z"
          },
          "llmsTxt": {
            "url": "https://docs.temporal.io/llms.txt",
            "ok": true,
            "status": 200,
            "checkedAt": "2026-10-04T15:18:17.819947998Z"
          },
          "domain": {
            "domain": "temporal.io",
            "checkedAt": "2026-10-04T13:09:39.916747902Z"
          },
          "pages": [
            {
              "url": "https://docs.temporal.io/cloud/pricing",
              "kind": "pricing",
              "status": 304,
              "checkedAt": "2026-10-04T15:44:07.868726677Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "4977c222b082"
            },
            {
              "url": "https://temporal.io/pricing",
              "kind": "pricing",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:27.02559255Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "afba575b2b42"
            },
            {
              "url": "https://temporal.io/global-privacy-policy",
              "kind": "privacy",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:24.921177834Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "f55eba2b4fc3"
            }
          ],
          "updatedAt": "2026-10-05T00:54:06.983429941Z"
        }
      },
      {
        "slug": "trigger-dev",
        "name": "Trigger.dev",
        "vendor": "Trigger.dev",
        "vendorUrl": "https://trigger.dev",
        "kind": "platform",
        "category": "human-in-the-loop",
        "summary": "Open-source background jobs and durable tasks in TypeScript.",
        "url": "https://www.anchorterminal.com/tools/trigger-dev",
        "markdownUrl": "https://www.anchorterminal.com/tools/trigger-dev.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/trigger-dev.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/trigger-dev.json",
        "repo": "https://github.com/triggerdotdev/trigger.dev",
        "license": "Apache-2.0",
        "transports": [
          "http",
          "stdio"
        ],
        "remoteUrl": "https://api.trigger.dev",
        "packages": [
          {
            "registry": "npm",
            "name": "@trigger.dev/sdk"
          },
          {
            "registry": "npm",
            "name": "trigger.dev"
          }
        ],
        "auth": "mixed",
        "authNotes": "Server-side calls use the environment secret key as a Bearer token. `wait.createToken()` also returns a `publicAccessToken` scoped to that one waitpoint, which a browser can use to complete it (the completion endpoint has CORS). The `token.url` callback is for server-to-server use and has no CORS headers. The MCP server runs locally through the CLI and uses its login profiles (`whoami`, `switch_profile`).",
        "pricing": "freemium",
        "pricingNotes": "Free $0 with $5 of usage a month, 20 concurrent runs, 5 team members and 1-day log retention. Hobby $10 a month with $10 of usage, 50 concurrent runs and 7-day logs. Pro $50 a month with $50 of usage, 200+ concurrent runs ($10 a month per extra 50), 25+ seats ($20 each) and 30-day logs. Enterprise is custom, with a SOC 2 report, SSO and RBAC. Compute is billed per second by machine, from $0.0000169 (Micro) and $0.0000338 (Small 1x, the default) to $0.00068 (Large 2x), plus $0.000025 per run ($0.25 per 10,000). Dev runs aren't charged, and waits over 5 seconds aren't billed (https://trigger.dev/pricing, https://trigger.dev/docs/how-to-reduce-your-spend). Self-hosting is free under Apache-2.0.",
        "priceSummary": "Freemium",
        "where": "both",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": 31,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://trigger.dev/docs/wait-for-token",
        "llmsTxt": "https://trigger.dev/docs/llms.txt",
        "openapi": "https://raw.githubusercontent.com/triggerdotdev/trigger.dev/main/docs/v3-openapi.yaml",
        "registryName": "io.github.triggerdotdev/trigger.dev",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "agent.durable",
          "automation.workflows",
          "automation.code"
        ],
        "tags": [
          "hosted",
          "self-hosted",
          "open-source",
          "freemium",
          "free-tier",
          "mcp",
          "openapi",
          "typescript",
          "webhooks"
        ],
        "lastRelease": "2026-10-01",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 74.8,
          "grade": "BB",
          "agentReady": true,
          "rank": 46,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 2,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 79,
            "maintenance": 90,
            "payments": 40,
            "reliability": 75,
            "schema": 91,
            "security": 73,
            "transparency": 74
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Tokens complete from a backend, a pre-signed callback URL or the browser with a token scoped to one waitpoint. 10-minute default timeout on tokens.",
          "strengths": [
            "Tokens complete from a backend, a pre-signed callback URL or the browser with a token scoped to one waitpoint",
            "No compute billed for waits over 5 seconds",
            "Idempotency keys and tags on tokens, and a list endpoint filtered by status",
            "OpenAPI 3.1 spec, llms.txt and a release on 2026-10-01",
            "Apache-2.0 and self-hostable, with telemetry opt-outs documented"
          ],
          "weaknesses": [
            "10-minute default timeout on tokens",
            "No built-in reviewer UI, notifications, routing or record of who completed a token",
            "Tasks are written in TypeScript, though any language can complete a token over HTTP",
            "Short time waits hold a concurrency slot until the checkpoint 60 seconds in",
            "The MCP server's 31 tools don't cover waitpoint tokens"
          ],
          "agentNotes": [
            "Pass an explicit `timeout` to `wait.createToken()` and handle `ok: false` as a timeout",
            "Use an idempotency key when creating the token so a retried step doesn't send the reviewer a second request",
            "Give the browser the `publicAccessToken`, never the secret key, and don't call `token.url` from client code",
            "Tag tokens with the user or task ID so pending approvals can be listed per reviewer",
            "Start the MCP server with `--readonly` when the agent only needs to inspect runs"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 8,
          "avgRating": 3.6,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "BB",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 74.8
            }
          ],
          "editorialScores": {
            "ergonomics": 79,
            "maintenance": 90,
            "payments": 40,
            "reliability": 75,
            "schema": 91,
            "security": 73,
            "transparency": 73
          },
          "provenanceScore": 75
        },
        "connect": {
          "install": "npm install @trigger.dev/sdk",
          "http": "curl -X POST https://api.trigger.dev/api/v1/waitpoints/tokens -H \"Authorization: Bearer $TRIGGER_SECRET_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"timeout\":\"24h\",\"tags\":[\"approval:refund-1042\"]}'",
          "claudeCode": "claude mcp add trigger -- npx trigger.dev@latest mcp",
          "config": {
            "mcpServers": {
              "trigger": {
                "args": [
                  "trigger.dev@latest",
                  "mcp"
                ],
                "command": "npx"
              }
            }
          }
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/trigger-dev"
        },
        "alsoIn": [
          "workflow-automation"
        ],
        "area": "agent-runtime",
        "provenance": {
          "legalEntity": "API Hero Ltd",
          "domain": "trigger.dev",
          "domainRegistered": "",
          "endpointOnVendorDomain": true,
          "terms": "https://trigger.dev/legal",
          "privacy": "https://trigger.dev/legal/privacy",
          "statusPage": "https://status.trigger.dev",
          "changelog": "https://trigger.dev/changelog",
          "securityTxt": "unknown",
          "checked": "2026-10-01",
          "notes": [
            "status.trigger.dev runs on Better Stack, with global, per-region (us-east-1, eu-central-1, us-west-2) and SSO components.",
            "SECURITY.md takes reports through private GitHub advisories or security@trigger.dev.",
            "v4.7.0 was released on 2026-10-01 and v4.6.4 on 2026-09-22.",
            "The repository's server.json names io.github.triggerdotdev/trigger.dev at version 4.0.3. We couldn't query the registry.",
            "The privacy policy (updated 2025-12-23) names API Hero Ltd trading as Trigger.dev, Altrincham, United Kingdom, ICO registration ZB547039, and links a DPA at trigger.dev/legal/dpa. We couldn't read the live security.txt or RDAP on 2026-10-01."
          ],
          "score": 75
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/trigger-dev.json",
        "live": {
          "slug": "trigger-dev",
          "probe": {
            "target": "https://api.trigger.dev",
            "method": "get",
            "lastAt": "2026-10-05T00:57:29.629964783Z",
            "lastOk": true,
            "lastStatus": 200,
            "lastMs": 341,
            "authRequired": false,
            "uptime24h": 100,
            "uptime30d": 100,
            "p50ms24h": 439,
            "p95ms24h": 544,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 109
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 248
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 271
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 272
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 11
              }
            ]
          },
          "vendorStatus": {
            "page": "https://status.trigger.dev",
            "indicator": "unknown",
            "summary": "no machine-readable status found",
            "checkedAt": "2026-10-04T21:40:31.839911185Z"
          },
          "versions": [
            {
              "registry": "github",
              "name": "triggerdotdev/trigger.dev",
              "version": "v4.7.2",
              "released": "2026-10-02",
              "seenAt": "2026-10-04T16:42:15.858024116Z"
            },
            {
              "registry": "npm",
              "name": "@trigger.dev/sdk",
              "version": "4.7.2",
              "seenAt": "2026-10-04T16:42:13.646259814Z"
            },
            {
              "registry": "npm",
              "name": "trigger.dev",
              "version": "4.7.2",
              "seenAt": "2026-10-04T16:42:14.609508507Z"
            }
          ],
          "githubStars": 16466,
          "npmWeekly": 1281205,
          "securityTxt": {
            "url": "https://trigger.dev/.well-known/security.txt",
            "state": "valid",
            "expires": "2027-09-01T00:00:00Z",
            "checkedAt": "2026-10-04T15:15:40.075165979Z"
          },
          "llmsTxt": {
            "url": "https://trigger.dev/docs/llms.txt",
            "ok": true,
            "status": 200,
            "checkedAt": "2026-10-04T15:18:18.347440339Z"
          },
          "domain": {
            "domain": "trigger.dev",
            "registered": "2022-12-01",
            "source": "https://pubapi.registry.google/rdap/domain/trigger.dev",
            "checkedAt": "2026-10-04T13:03:37.236967627Z"
          },
          "pages": [
            {
              "url": "https://trigger.dev/changelog",
              "kind": "changelog",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:31.0596486Z",
              "changedAt": "2026-10-03T15:36:27.564584064Z",
              "fingerprint": "803b8a76b025"
            },
            {
              "url": "https://trigger.dev/pricing",
              "kind": "pricing",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:37.400389416Z",
              "changedAt": "2026-10-03T15:36:33.845714939Z",
              "fingerprint": "40bffe455cee"
            },
            {
              "url": "https://trigger.dev/legal/privacy",
              "kind": "privacy",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:35.354788303Z",
              "changedAt": "2026-10-03T15:36:31.851078695Z",
              "fingerprint": "74a6e4e19e26"
            },
            {
              "url": "https://trigger.dev/legal",
              "kind": "terms",
              "status": 200,
              "checkedAt": "2026-10-04T15:48:33.443165414Z",
              "changedAt": "2026-10-03T15:36:29.956580316Z",
              "fingerprint": "6b3e48482aff"
            }
          ],
          "updatedAt": "2026-10-05T00:57:29.629964783Z"
        }
      },
      {
        "slug": "inngest",
        "name": "Inngest",
        "vendor": "Inngest",
        "vendorUrl": "https://www.inngest.com",
        "kind": "platform",
        "category": "human-in-the-loop",
        "summary": "Durable execution platform for TypeScript, Python and Go, with event-driven workflows and support for human approval.",
        "url": "https://www.anchorterminal.com/tools/inngest",
        "markdownUrl": "https://www.anchorterminal.com/tools/inngest.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/inngest.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/inngest.json",
        "repo": "https://github.com/inngest/inngest",
        "license": "SSPL with delayed Apache-2.0 (server), Apache-2.0 (SDKs)",
        "transports": [
          "http",
          "streamable-http"
        ],
        "remoteUrl": "https://inn.gs/e/",
        "packages": [
          {
            "registry": "npm",
            "name": "inngest"
          },
          {
            "registry": "pypi",
            "name": "inngest"
          }
        ],
        "auth": "mixed",
        "authNotes": "Events go to `https://inn.gs/e/\u003cevent key\u003e`, so the event key sits in the URL path. Your app's serve endpoint checks requests with a signing key. The REST API and the Cloud MCP at `api.inngest.com/mcp` take an API key (`sk-inn-api-...`) as a Bearer token, and the Cloud MCP won't accept signing keys.",
        "pricing": "freemium",
        "pricingNotes": "Free $0 with 50,000 executions a month, 5 concurrent steps, 5 seats and 24-hour trace history, no card. Pro from $99 a month with 1 million executions, 100 concurrent steps, 15 seats and 7-day traces, then $50 per extra million. Business from $499 a month with 10 million executions, 500 concurrent steps, 30 seats and 14-day traces. Enterprise is priced on request. One execution is one run plus one per step, so a run with 5 steps costs 6, and Free pauses execution at the quota instead of billing overage (https://www.inngest.com/pricing).",
        "priceSummary": "$99 / mo",
        "where": "hosted",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": null,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://www.inngest.com/docs/ai-patterns/human-in-the-loop",
        "llmsTxt": "https://www.inngest.com/llms.txt",
        "openapi": "https://api-docs.inngest.com/api-specs/v2.json",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "agent.durable",
          "automation.workflows",
          "automation.code"
        ],
        "tags": [
          "hosted",
          "self-hosted",
          "source-available",
          "freemium",
          "free-tier",
          "no-card",
          "mcp",
          "llms-txt",
          "typescript",
          "python",
          "enterprise"
        ],
        "lastRelease": "2026-09-22",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 66.3,
          "grade": "B",
          "agentReady": false,
          "rank": 160,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 3,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 76,
            "maintenance": 88,
            "payments": 40,
            "reliability": 57,
            "schema": 89,
            "security": 60,
            "transparency": 56
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Waits are durable and cost nothing while suspended, with runs up to 30 days on Free and 366 on Business. No reviewer inbox, Slack app or email, so the human side is your code.",
          "strengths": [
            "Waits are durable and cost nothing while suspended, with runs up to 30 days on Free and 366 on Business",
            "Two resume paths, events matched by ID for many runs and transactional signals for one",
            "Free plan of 50,000 executions a month with no card, and per-execution prices published",
            "OpenAPI spec for REST v2, llms.txt and a dated changelog",
            "SOC 2 Type II, a paid bounty and Apache-2.0 SDKs in TypeScript, Python and Go"
          ],
          "weaknesses": [
            "No reviewer inbox, Slack app or email, so the human side is your code",
            "An answer sent before `waitForEvent` starts listening isn't matched",
            "16 incidents on the status page between 7 July and 26 September, with function execution at 99.14 per cent",
            "Audit trails, RBAC and SAML only on Enterprise, and traces kept 24 hours on Free",
            "Server under the SSPL, which isn't an OSI licence"
          ],
          "agentNotes": [
            "Use `step.waitForSignal()` when one run waits for one answer, and `waitForEvent` only when one answer resumes many runs",
            "Register the wait before you send the approval request, or check the external state first, since early events are missed",
            "Use a unique approval ID per tool call and `match` on it, so parallel approvals resolve independently",
            "Treat `null` or `undefined` as a timeout and decide on purpose whether that rejects, approves or escalates",
            "Set an event `id` when sending the answer, so a retried send is dropped within 24 hours"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 2,
          "avgRating": 2.5,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "B",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 66.3
            }
          ],
          "editorialScores": {
            "ergonomics": 76,
            "maintenance": 88,
            "payments": 40,
            "reliability": 57,
            "schema": 89,
            "security": 60,
            "transparency": 52
          },
          "provenanceScore": 60
        },
        "connect": {
          "install": "npm install inngest",
          "http": "curl -X POST \"https://inn.gs/e/$INNGEST_EVENT_KEY\" \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\":\"agent/approval.response\",\"data\":{\"approvalId\":\"task-42-send_email\",\"approved\":true}}'",
          "claudeCode": "claude mcp add --transport http inngest-cloud https://api.inngest.com/mcp --header \"Authorization: Bearer $INNGEST_API_KEY\""
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/inngest"
        },
        "alsoIn": [
          "workflow-automation"
        ],
        "area": "agent-runtime",
        "unitPrices": [
          {
            "item": "Pro plan",
            "unit": "month",
            "usd": 99,
            "note": "From $99, 1 million executions, 100 concurrent steps, 15 seats"
          },
          {
            "item": "Business plan",
            "unit": "month",
            "usd": 499,
            "note": "From $499, 10 million executions, 500 concurrent steps, 30 seats"
          },
          {
            "item": "Extra executions on Pro",
            "unit": "1k-calls",
            "usd": 0.05,
            "note": "$50 per million executions, tiered down to $0.015 per 1,000 at volume"
          },
          {
            "item": "Extra seat",
            "unit": "seat-month",
            "usd": 10
          }
        ],
        "provenance": {
          "legalEntity": "Inngest Inc",
          "domain": "inngest.com",
          "domainRegistered": "",
          "endpointOnVendorDomain": false,
          "terms": "https://www.inngest.com/terms",
          "privacy": "https://www.inngest.com/privacy",
          "statusPage": "https://status.inngest.com",
          "changelog": "https://www.inngest.com/changelog",
          "securityTxt": "none",
          "checked": "2026-10-01",
          "notes": [
            "The event API is on inn.gs, a separate domain. The REST API and Cloud MCP are on api.inngest.com.",
            "The terms give Inngest Inc at 821 Howard St, San Francisco, and the privacy policy (updated 2026-04-03) an address at 600 California St, San Francisco.",
            "https://www.inngest.com/.well-known/security.txt returned 404 on 2026-10-01. The security page names security@inngest.com and a bounty, and the trust centre is at trust.inngest.com.",
            "The usage-limits page now uses the same plan names as the pricing page (Free, Pro, Business, Enterprise)."
          ],
          "score": 60
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/inngest.json",
        "live": {
          "slug": "inngest",
          "probe": {
            "target": "https://inn.gs/e/",
            "method": "get",
            "lastAt": "2026-10-05T00:57:21.930164992Z",
            "lastOk": true,
            "lastStatus": 404,
            "lastMs": 290,
            "authRequired": false,
            "uptime24h": 100,
            "uptime30d": 100,
            "p50ms24h": 296,
            "p95ms24h": 331,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 109
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 248
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 271
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 272
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 11
              }
            ]
          },
          "vendorStatus": {
            "page": "https://status.inngest.com",
            "indicator": "none",
            "summary": "All Systems Operational",
            "checkedAt": "2026-10-05T00:53:54.230427234Z"
          },
          "versions": [
            {
              "registry": "github",
              "name": "inngest/inngest",
              "version": "v1.45.1",
              "released": "2026-09-17",
              "seenAt": "2026-10-04T16:30:17.798203821Z"
            },
            {
              "registry": "npm",
              "name": "inngest",
              "version": "4.21.1",
              "seenAt": "2026-10-04T16:30:17.360851892Z"
            },
            {
              "registry": "pypi",
              "name": "inngest",
              "version": "0.5.19",
              "released": "2026-06-23",
              "seenAt": "2026-10-04T16:30:17.615210455Z"
            }
          ],
          "githubStars": 5908,
          "npmWeekly": 3079142,
          "pypiWeekly": 251067,
          "securityTxt": {
            "url": "https://inngest.com/.well-known/security.txt",
            "state": "none",
            "checkedAt": "2026-10-04T15:15:40.181853602Z"
          },
          "llmsTxt": {
            "url": "https://www.inngest.com/llms.txt",
            "ok": true,
            "status": 200,
            "checkedAt": "2026-10-04T15:17:54.82938436Z"
          },
          "domain": {
            "domain": "inngest.com",
            "registered": "2020-10-12",
            "source": "https://rdap.verisign.com/com/v1/domain/inngest.com",
            "checkedAt": "2026-10-04T13:07:14.754460124Z"
          },
          "pages": [
            {
              "url": "https://www.inngest.com/changelog",
              "kind": "changelog",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:48.34767254Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "bdfd298ff2b4"
            },
            {
              "url": "https://www.inngest.com/pricing",
              "kind": "pricing",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:50.387896235Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "b300dcb70f05"
            },
            {
              "url": "https://www.inngest.com/privacy",
              "kind": "privacy",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:52.384497946Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "70f51804be5c"
            },
            {
              "url": "https://www.inngest.com/terms",
              "kind": "terms",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:54.552360041Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "52d76880cc57"
            }
          ],
          "updatedAt": "2026-10-05T00:57:21.930164992Z"
        }
      },
      {
        "slug": "permit-mcp-gateway",
        "name": "Permit MCP Gateway",
        "vendor": "Permit.io",
        "vendorUrl": "https://www.permit.io/mcp-gateway",
        "kind": "platform",
        "category": "human-in-the-loop",
        "summary": "Hosted proxy between MCP clients and MCP servers that signs in the human behind the agent, checks each tool call against Permit.io policy and logs it.",
        "url": "https://www.anchorterminal.com/tools/permit-mcp-gateway",
        "markdownUrl": "https://www.anchorterminal.com/tools/permit-mcp-gateway.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/permit-mcp-gateway.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/permit-mcp-gateway.json",
        "transports": [
          "streamable-http"
        ],
        "remoteUrl": "https://{subdomain}.agent.security/mcp",
        "packages": [],
        "auth": "oauth",
        "authNotes": "The gateway is an OAuth 2.1 authorisation server per host. The MCP client gets a 401, reads `/.well-known/oauth-authorization-server` and opens a browser, where the user signs in with email and password, a one-time code, a passkey, Google, GitHub or Microsoft, or SAML or OIDC single sign-on, then picks the access the agent gets. Upstream OAuth (GitHub, Linear) runs through the same consent flow. Sessions expire 90 days after the last tool call.",
        "pricing": "paid",
        "pricingNotes": "Human-in-the-loop approvals are on Enterprise plans, arranged through a demo (https://docs.permit.io/permit-mcp-gateway/human-in-the-loop), and so are the customer-controlled and fully on-premises deployments. The hosted gateway is where evaluation starts, sign-up at app.agent.security. Permit's pricing page lists a free Community plan (1,000 MAU, 20 tenants, no card, 14-day audit logs, best-effort cloud uptime) and Enterprise through sales with SOC 2 Type II, HIPAA BAA and a 99.99 per cent uptime option, but no line for the MCP gateway (https://www.permit.io/pricing).",
        "priceSummary": "Paid",
        "where": "hosted",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": null,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://docs.permit.io/permit-mcp-gateway/human-in-the-loop",
        "capabilities": [
          "hitl.approve",
          "hitl.channels",
          "hitl.audit",
          "auth.oauth",
          "auth.consent",
          "auth.agent-identity",
          "auth.audit"
        ],
        "tags": [
          "hosted",
          "self-hosted",
          "mcp",
          "oauth",
          "enterprise"
        ],
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 54.5,
          "grade": "C",
          "agentReady": false,
          "rank": 321,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 4,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 83,
            "maintenance": 43,
            "payments": 10,
            "reliability": 47,
            "schema": 53,
            "security": 80,
            "transparency": 45
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "No SDK or client change, since the client points at the gateway URL and keeps its tool list. Approvals are Enterprise only, through a demo, with no published price.",
          "strengths": [
            "No SDK or client change, since the client points at the gateway URL and keeps its tool list",
            "Fails closed, with timeouts that reject and disconnects that cancel",
            "OAuth 2.1 with consent, a trust ceiling per user and admin revocation",
            "Approval history with the outcome, deciding admin and decision time, plus every call in Permit audit logs",
            "Customer-controlled and on-premises deployments keep tool traffic inside your network"
          ],
          "weaknesses": [
            "Approvals are Enterprise only, through a demo, with no published price",
            "Only gateway admins approve, so routing to the right person needs admin seats",
            "5-minute default window, extendable 5 minutes at a time, suits live sessions more than overnight review",
            "No gateway changelog, and the product changelog on Canny stopped in May 2024",
            "Rate limits exist but aren't published, and the status page doesn't list the gateway"
          ],
          "agentNotes": [
            "Expect a waiting message before an approval-gated tool returns, and don't retry the call while it waits",
            "Read the rejection reason in the error and change approach instead of calling the same tool again",
            "Treat a timeout as a rejection and ask the user to have an admin online before a batch of destructive calls",
            "Stay connected while waiting, since dropping the connection cancels the request",
            "On a 429 with `rate_limited`, back off for a few seconds and grow the wait on each retry"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 2,
          "avgRating": 2.5,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "C",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 54.5
            }
          ],
          "editorialScores": {
            "ergonomics": 83,
            "maintenance": 43,
            "payments": 10,
            "reliability": 47,
            "schema": 53,
            "security": 80,
            "transparency": 40
          },
          "provenanceScore": 50
        },
        "connect": {
          "claudeCode": "claude mcp add --transport http linear-gated \"https://YOUR-HOST.agent.security/mcp?upstream_mcp=https://mcp.linear.app/mcp\""
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/permit-mcp-gateway"
        },
        "alsoIn": [
          "agent-auth"
        ],
        "area": "agent-runtime",
        "provenance": {
          "legalEntity": "Permit Inc.",
          "domain": "permit.io",
          "domainRegistered": "",
          "endpointOnVendorDomain": false,
          "terms": "https://www.permit.io/legal/terms-and-conditions",
          "privacy": "https://www.permit.io/legal/privacy-policy",
          "statusPage": "https://permit-io.instatus.com/",
          "changelog": "",
          "securityTxt": "unknown",
          "checked": "2026-10-01",
          "notes": [
            "Gateway hosts and the admin dashboard run on agent.security (app.agent.security, \u003chost\u003e.agent.security), while policy and audit logs live on app.permit.io.",
            "The status page lists the backend, OPAL, frontend, website, PDP Deltas and PDP Data. It has no component for the gateway or agent.security.",
            "The docs changelog page says the Canny changelog has no entries after 2024-05-16 and points to SDK and PDP release notes instead.",
            "The gateway docs in permitio/docs were last changed on 2026-09-20. The human-in-the-loop page was added on 2026-05-11.",
            "The terms (updated 2026-07-01) name Permit Inc., a Delaware corporation with a registered office in Dover, Delaware. We couldn't read security.txt or RDAP on 2026-10-01."
          ],
          "score": 50
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/permit-mcp-gateway.json",
        "live": {
          "slug": "permit-mcp-gateway",
          "probe": {
            "target": "https://{subdomain}.agent.security/mcp",
            "method": "get",
            "lastAt": "2026-10-05T00:57:25.694115433Z",
            "lastOk": false,
            "lastStatus": 0,
            "lastMs": 0,
            "lastNote": "invalid character \"{\" in host name",
            "authRequired": false,
            "uptime24h": 0,
            "uptime30d": 0,
            "p50ms24h": 0,
            "p95ms24h": 0,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 0
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 0
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 0
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 0
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 0
              }
            ]
          },
          "vendorStatus": {
            "page": "https://permit-io.instatus.com",
            "indicator": "unknown",
            "summary": "no machine-readable status found",
            "checkedAt": "2026-10-04T21:40:22.877190474Z"
          },
          "securityTxt": {
            "url": "https://permit.io/.well-known/security.txt",
            "state": "none",
            "checkedAt": "2026-10-04T15:16:02.774068255Z"
          },
          "domain": {
            "domain": "permit.io",
            "checkedAt": "2026-10-04T13:04:38.037359139Z"
          },
          "pages": [
            {
              "url": "https://www.permit.io/pricing",
              "kind": "pricing",
              "status": 304,
              "checkedAt": "2026-10-04T15:51:41.531863438Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "c9ed914508e4"
            },
            {
              "url": "https://www.permit.io/legal/privacy-policy",
              "kind": "privacy",
              "status": 304,
              "checkedAt": "2026-10-04T15:51:37.367686321Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "2c4815352975"
            },
            {
              "url": "https://www.permit.io/legal/terms-and-conditions",
              "kind": "terms",
              "status": 304,
              "checkedAt": "2026-10-04T15:51:39.899345922Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "7561c6093e56"
            }
          ],
          "updatedAt": "2026-10-05T00:57:25.694115433Z"
        }
      },
      {
        "slug": "orkes-conductor",
        "name": "Orkes Conductor Human tasks",
        "vendor": "Orkes",
        "vendorUrl": "https://orkes.io",
        "kind": "platform",
        "category": "human-in-the-loop",
        "summary": "Workflow orchestration platform, built on the open-source Conductor, with a Human task that pauses a workflow, assigns a form to a user or group and resumes with the submitted answer.",
        "url": "https://www.anchorterminal.com/tools/orkes-conductor",
        "markdownUrl": "https://www.anchorterminal.com/tools/orkes-conductor.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/orkes-conductor.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/orkes-conductor.json",
        "repo": "https://github.com/conductor-oss/conductor",
        "license": "Apache-2.0 (Conductor OSS and SDKs), proprietary (Orkes Conductor)",
        "transports": [
          "http",
          "stdio"
        ],
        "remoteUrl": "https://developer.orkescloud.com/api",
        "packages": [
          {
            "registry": "pypi",
            "name": "conductor-python"
          },
          {
            "registry": "npm",
            "name": "@io-orkes/conductor-javascript"
          },
          {
            "registry": "pypi",
            "name": "conductor-mcp"
          }
        ],
        "auth": "api-key",
        "authNotes": "Create an application in Conductor to get an access key ID and secret, exchange them at `POST /api/token` for a JWT, and send that JWT in an `X-Authorization` header. Tokens can be given an expiry in milliseconds, and a negative value means no expiry. External reviewers are identified by email or group name from your own identity system.",
        "pricing": "paid",
        "pricingNotes": "Two editions on https://orkes.io/pricing. Developer Edition is free and hosted at developer.orkescloud.com, includes Human tasks, and is meant for individual developers, with no SLA, variable performance and rate limits that may change. Enterprise is priced through sales and adds up to a 99.99 per cent availability SLA, SOC 2 Type II and a technical account manager. The Cloud support policy lists 99.9 and 99.0 per cent uptime plans with service credits (https://orkes.io/cloud-support-policy/). Conductor OSS is free under Apache-2.0, but the forms, assignment policies and Human Tasks API are documented for Orkes Conductor.",
        "priceSummary": "Paid",
        "where": "both",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": 19,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://orkes.io/content/reference-docs/operators/human",
        "llmsTxt": "https://orkes.io/content/llms.txt",
        "registryName": "io.github.conductor-oss/conductor-mcp",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "hitl.handoff",
          "hitl.audit",
          "agent.durable",
          "automation.workflows"
        ],
        "tags": [
          "hosted",
          "self-hosted",
          "open-source",
          "mcp",
          "llms-txt",
          "python",
          "typescript",
          "enterprise"
        ],
        "lastRelease": "2026-09-10",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 54.2,
          "grade": "C",
          "agentReady": false,
          "rank": 327,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 5,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 69,
            "maintenance": 81,
            "payments": 20,
            "reliability": 32,
            "schema": 65,
            "security": 71,
            "transparency": 46
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Escalation chains with a time limit per assignee and a choice of leaving the task open or failing the workflow. No built-in Slack or email prompt, so alerts need a trigger policy and a second workflow.",
          "strengths": [
            "Escalation chains with a time limit per assignee and a choice of leaving the task open or failing the workflow",
            "Reviewers can be Conductor users or people in your own identity system, by email or group",
            "Human task search by state, assignee, claimant, full text and input or output fields",
            "Application keys with roles and per-resource permissions",
            "Published uptime commitments of 99.9 per cent with service credits, up to 99.99 on Enterprise"
          ],
          "weaknesses": [
            "No built-in Slack or email prompt, so alerts need a trigger policy and a second workflow",
            "Several objects to set up (form, task, workflow, application key) before the first approval",
            "Paid editions are contact sales only, and the free Developer Edition isn't for production",
            "No public status page or published API rate limits",
            "The MCP server has 19 tools but none for Human tasks, and no commit since January 2026"
          ],
          "agentNotes": [
            "Give every assignment you want to escalate from a non-zero `slaMinutes`, since 0 never expires and nothing can follow it",
            "Pick `TERMINATE` for risky actions so an unanswered approval fails the workflow instead of staying open to anyone",
            "Start approval workflows with an `idempotencyKey` and `RETURN_EXISTING`, so a retried start doesn't ask twice",
            "Refresh the JWT from `/api/token` with a set expiry instead of requesting one that never expires",
            "Fetch single doc pages, not llms.txt, which is the whole documentation in 2.57 MB"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 2,
          "avgRating": 2.5,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "C",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 54.2
            }
          ],
          "editorialScores": {
            "ergonomics": 69,
            "maintenance": 81,
            "payments": 20,
            "reliability": 32,
            "schema": 65,
            "security": 71,
            "transparency": 41
          },
          "provenanceScore": 50
        },
        "connect": {
          "http": "TOKEN=$(curl -s -X POST https://developer.orkescloud.com/api/token -H 'Content-Type: application/json' \\\n  -d \"{\\\"keyId\\\":\\\"$ORKES_KEY_ID\\\",\\\"keySecret\\\":\\\"$ORKES_KEY_SECRET\\\"}\" | jq -r .token)\ncurl -X POST https://developer.orkescloud.com/api/human/tasks/search -H \"X-Authorization: $TOKEN\" \\\n  -H 'Content-Type: application/json' -d '{\"searchType\":\"ADMIN\",\"start\":0,\"size\":10,\"states\":[\"ASSIGNED\"]}'",
          "config": {
            "mcpServers": {
              "conductor": {
                "args": [
                  "--config",
                  "/absolute/path/to/conductor-config.json"
                ],
                "command": "conductor-mcp"
              }
            }
          }
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/orkes-conductor"
        },
        "alsoIn": [
          "workflow-automation"
        ],
        "area": "agent-runtime",
        "provenance": {
          "legalEntity": "Orkes, Inc.",
          "domain": "orkes.io",
          "domainRegistered": "",
          "endpointOnVendorDomain": false,
          "terms": "https://orkes.io/cloud-services-agreement",
          "privacy": "https://orkes.io/privacy-policy",
          "statusPage": "",
          "changelog": "https://orkes.io/changelog",
          "securityTxt": "unknown",
          "checked": "2026-10-01",
          "notes": [
            "The privacy policy (last updated 2022-02-23) names Orkes, Inc. of Cupertino, California, and says data is stored on servers in the United States.",
            "The Developer Edition API runs on developer.orkescloud.com, not on orkes.io.",
            "The docs repository (orkes-io/docs) was last updated on 2026-07-06. Its static/llms.txt is the whole documentation in one 2.57 MB file.",
            "No public status page found. The Cloud support policy at orkes.io/cloud-support-policy sets uptime commitments by plan.",
            "We couldn't read security.txt or RDAP on 2026-10-01."
          ],
          "score": 50
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/orkes-conductor.json",
        "live": {
          "slug": "orkes-conductor",
          "probe": {
            "target": "https://developer.orkescloud.com/api",
            "method": "get",
            "lastAt": "2026-10-05T00:57:25.272561434Z",
            "lastOk": true,
            "lastStatus": 401,
            "lastMs": 262,
            "lastNote": "asks for credentials",
            "authRequired": true,
            "uptime24h": 100,
            "uptime30d": 100,
            "p50ms24h": 263,
            "p95ms24h": 318,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 109
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 248
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 271
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 272
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 11
              }
            ]
          },
          "versions": [
            {
              "registry": "github",
              "name": "conductor-oss/conductor",
              "version": "v3.32.5",
              "released": "2026-09-25",
              "seenAt": "2026-10-04T16:36:07.701474128Z"
            },
            {
              "registry": "npm",
              "name": "@io-orkes/conductor-javascript",
              "version": "4.0.0",
              "seenAt": "2026-10-04T16:36:05.790336459Z"
            },
            {
              "registry": "pypi",
              "name": "conductor-mcp",
              "version": "0.1.9",
              "released": "2026-02-02",
              "seenAt": "2026-10-04T16:36:06.688272298Z"
            },
            {
              "registry": "pypi",
              "name": "conductor-python",
              "version": "2.0.0",
              "released": "2026-08-03",
              "seenAt": "2026-10-04T16:36:05.600717994Z"
            }
          ],
          "githubStars": 32263,
          "npmWeekly": 27933,
          "pypiWeekly": 28881,
          "securityTxt": {
            "url": "https://orkes.io/.well-known/security.txt",
            "state": "none",
            "checkedAt": "2026-10-04T15:16:00.592647776Z"
          },
          "llmsTxt": {
            "url": "https://orkes.io/content/llms.txt",
            "ok": true,
            "status": 200,
            "checkedAt": "2026-10-04T15:18:05.791029536Z"
          },
          "domain": {
            "domain": "orkes.io",
            "checkedAt": "2026-10-04T13:08:35.313759321Z"
          },
          "pages": [
            {
              "url": "https://orkes.io/changelog",
              "kind": "changelog",
              "status": 304,
              "checkedAt": "2026-10-04T15:46:32.264083493Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "b5674561eecd"
            },
            {
              "url": "https://orkes.io/pricing",
              "kind": "pricing",
              "status": 304,
              "checkedAt": "2026-10-04T15:46:36.530450393Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "4d12810c9edd"
            },
            {
              "url": "https://orkes.io/privacy-policy",
              "kind": "privacy",
              "status": 304,
              "checkedAt": "2026-10-04T15:46:38.525982343Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "07978bbd9114"
            },
            {
              "url": "https://orkes.io/cloud-services-agreement",
              "kind": "terms",
              "status": 304,
              "checkedAt": "2026-10-04T15:46:34.533885364Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "664af8740ead"
            }
          ],
          "updatedAt": "2026-10-05T00:57:25.272561434Z"
        }
      },
      {
        "slug": "pushary",
        "name": "Pushary",
        "vendor": "Pushary",
        "vendorUrl": "https://pushary.com",
        "kind": "mcp",
        "category": "human-in-the-loop",
        "summary": "Hosted MCP server that lets a coding agent notify you and ask you a yes or no, multiple-choice or free-text question on your phone, Mac, Slack or browser, then wait for the answer.",
        "url": "https://www.anchorterminal.com/tools/pushary",
        "markdownUrl": "https://www.anchorterminal.com/tools/pushary.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/pushary.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/pushary.json",
        "repo": "https://github.com/Pushary/pushary-skill",
        "license": "MIT (skill, hooks and adapters)",
        "transports": [
          "streamable-http",
          "sse"
        ],
        "remoteUrl": "https://pushary.com/api/mcp/mcp",
        "packages": [
          {
            "registry": "npm",
            "name": "pushary"
          },
          {
            "registry": "pypi",
            "name": "hermes-plugin-pushary"
          }
        ],
        "auth": "api-key",
        "authNotes": "Bearer API key in the form `pk_xxx.sk_xxx`. `npx pushary@latest setup` pairs a phone by QR code and fingerprint and writes the credentials for you, so there's no key to copy. Claude Cowork connects through a connector link from the dashboard. Partner integrations enrol each customer through a scoped connection link instead of sharing the operator key.",
        "pricing": "paid",
        "pricingNotes": "Agent plan $9.99 a month with 5,000 notifications, Agent Pro $19.99 a month with unlimited notifications, budgets and up to 5 people, both after a 3-day trial that takes a card up front (https://pushary.com, https://github.com/Pushary/pushary-skill). Partner access for embedding approvals for your own users has no public price. Fees are non-refundable except where the law requires (https://pushary.com/terms). The browser demo at pushary.com/try needs no sign-up but uses polling and temporary state.",
        "priceSummary": "$9.99 / mo",
        "where": "hosted",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": 6,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://github.com/Pushary/pushary-skill",
        "registryName": "io.github.Pushary/pushary",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "hitl.channels",
          "hitl.audit",
          "notify.push"
        ],
        "tags": [
          "hosted",
          "mcp",
          "card-required",
          "typescript",
          "python"
        ],
        "lastRelease": "2026-10-01",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 51.4,
          "grade": "D",
          "agentReady": false,
          "rank": 350,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 6,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 76,
            "maintenance": 60,
            "payments": 10,
            "reliability": 20,
            "schema": 73,
            "security": 64,
            "transparency": 63
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Six small tools with a detailed skill that says when to ask, when to notify and when to stay quiet. No free plan, and the 3-day trial takes a card up front.",
          "strengths": [
            "Six small tools with a detailed skill that says when to ask, when to notify and when to stay quiet",
            "Every result says whether it was answered and what to do next (`answered`, `status`, `handoffAction`)",
            "Lock-screen approve and deny, plus a Mac app, Slack and browser",
            "Enforced gates through Claude Code and Hermes hooks, with file-scope proposals",
            "Privacy policy names every subprocessor with its location, and open questions are cached for at most ten minutes"
          ],
          "weaknesses": [
            "No free plan, and the 3-day trial takes a card up front",
            "Plain MCP clients get cooperative questions only, with no enforcement",
            "Wait times are set by the user's delivery mode, so an agent can't count on a long block",
            "No status page, SLA or service changelog, and the terms promise no uptime",
            "Partner use for your own customers has no public price"
          ],
          "agentNotes": [
            "Read `answered`, `status` and `handoffAction` on every result, and never treat a timeout as approval",
            "Expect `ask_user` to return at once with `answered: false` when the user's mode is notify-only or terminal-only",
            "Poll `wait_for_answer` once (it waits at most 55 seconds), then follow the handoff instead of looping",
            "Cancel a live question with `cancel_question` before asking the same thing in chat",
            "Group open decisions into one `select` question, since each push interrupts the user"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 2,
          "avgRating": 2.5,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "D",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 51.4
            }
          ],
          "editorialScores": {
            "ergonomics": 76,
            "maintenance": 60,
            "payments": 10,
            "reliability": 20,
            "schema": 73,
            "security": 64,
            "transparency": 71
          },
          "provenanceScore": 55
        },
        "connect": {
          "install": "npx pushary@latest setup",
          "claudeCode": "claude mcp add --transport http pushary https://pushary.com/api/mcp/mcp --header \"Authorization: Bearer $PUSHARY_API_KEY\"",
          "config": {
            "mcpServers": {
              "pushary": {
                "headers": {
                  "Authorization": "Bearer ${PUSHARY_API_KEY}"
                },
                "url": "https://pushary.com/api/mcp/mcp"
              }
            }
          }
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/pushary"
        },
        "area": "agent-runtime",
        "unitPrices": [
          {
            "item": "Agent plan",
            "unit": "month",
            "usd": 9.99,
            "note": "5,000 notifications a month, after a 3-day trial with a card up front"
          },
          {
            "item": "Agent Pro plan",
            "unit": "month",
            "usd": 19.99,
            "note": "Unlimited notifications, budgets, up to 5 people"
          }
        ],
        "provenance": {
          "legalEntity": "RalphNex OÜ",
          "domain": "pushary.com",
          "domainRegistered": "",
          "endpointOnVendorDomain": true,
          "terms": "https://pushary.com/terms",
          "privacy": "https://pushary.com/privacy",
          "statusPage": "",
          "changelog": "",
          "securityTxt": "unknown",
          "checked": "2026-10-01",
          "notes": [
            "The terms (updated 2026-09-27) and privacy policy (updated 2026-09-28) name RalphNex OÜ, Estonian registry code 16932562, Narva mnt 7-652, 10117 Tallinn, under Estonian law.",
            "server.json names io.github.Pushary/pushary at version 1.4.1 with streamable HTTP and SSE remotes on pushary.com. A GitHub OIDC workflow added on 2026-08-15 publishes it to the MCP registry.",
            "The site footer links Security, Privacy and Terms pages. No status page or changelog link found.",
            "The repository's first commit is from 2026-03-23 and its last from 2026-10-01. Commits are syncs from a private monorepo.",
            "We couldn't read the MCP registry, RDAP or security.txt on 2026-10-01."
          ],
          "score": 55
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/pushary.json",
        "live": {
          "slug": "pushary",
          "probe": {
            "target": "https://pushary.com/api/mcp/mcp",
            "method": "mcp-initialize",
            "lastAt": "2026-10-05T00:57:26.524607182Z",
            "lastOk": true,
            "lastStatus": 200,
            "lastMs": 100,
            "lastNote": "initialize answered",
            "authRequired": false,
            "uptime24h": 100,
            "uptime30d": 100,
            "p50ms24h": 158,
            "p95ms24h": 920,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 109
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 248
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 271
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 272
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 11
              }
            ]
          },
          "versions": [
            {
              "registry": "mcp-registry",
              "name": "io.github.Pushary/pushary",
              "version": "1.4.2",
              "seenAt": "2026-10-04T23:42:40.113054682Z"
            },
            {
              "registry": "npm",
              "name": "pushary",
              "version": "1.9.18",
              "seenAt": "2026-10-04T16:37:42.552949745Z"
            },
            {
              "registry": "pypi",
              "name": "hermes-plugin-pushary",
              "version": "0.5.9",
              "released": "2026-10-03",
              "seenAt": "2026-10-04T16:37:42.969431217Z"
            }
          ],
          "githubStars": 1,
          "npmWeekly": 2265,
          "pypiWeekly": 397,
          "securityTxt": {
            "url": "https://pushary.com/.well-known/security.txt",
            "state": "none",
            "checkedAt": "2026-10-04T15:16:01.478206426Z"
          },
          "domain": {
            "domain": "pushary.com",
            "registered": "2025-12-24",
            "source": "https://rdap.verisign.com/com/v1/domain/pushary.com",
            "checkedAt": "2026-10-04T13:08:51.503354686Z"
          },
          "pages": [
            {
              "url": "https://pushary.com/privacy",
              "kind": "privacy",
              "status": 200,
              "checkedAt": "2026-10-04T15:47:07.587749401Z",
              "changedAt": "2026-10-04T15:47:07.587749401Z",
              "fingerprint": "f265d7a7361e"
            },
            {
              "url": "https://pushary.com/terms",
              "kind": "terms",
              "status": 200,
              "checkedAt": "2026-10-04T15:47:10.240295961Z",
              "changedAt": "2026-10-04T15:47:10.240295961Z",
              "fingerprint": "7b7a5acc6350"
            }
          ],
          "mcpTools": {
            "url": "https://pushary.com/api/mcp/mcp",
            "checkedAt": "2026-10-04T22:19:54.519364621Z",
            "status": "ok",
            "protocol": "2025-11-25",
            "tools": [
              {
                "name": "send_notification",
                "title": "Send Push Notification",
                "description": "Send a one-way notification to connected devices for a requested update or a meaningful unattended result. Use ask_user when an answer is needed. Delivery follows the account policy and optional recipient filters. context adds a detail page; context.askQuestion creates a linked decision. Returns web/mobile delivery counts and a warning when no delivery channel is connected. Sends real notifications.",
                "inputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "properties": {
                    "agentName": {
                      "description": "Name of the agent sending this notification, format \"{Agent} - {project}\" (e.g. \"Claude Code - myproject\"). Shown in the notification so the user knows which session is talking. Falls back to the MCP client name if omitted.",
                      "maxLength": 100,
                      "type": "string"
                    },
                    "body": {
                      "description": "Notification body text (max 500 chars). One or two sentences the user can act on without opening anything.",
                      "maxLength": 500,
                      "minLength": 1,
                      "type": "string"
                    },
                    "context": {
                      "description": "Structured context rendered as a rich detail page when the user taps the notification. Strongly recommended for task_complete and error notifications so the user can act from their phone.",
                      "properties": {
                        "askQuestion": {
                          "description": "Embed a decision prompt on the detail page. The response includes a linkedCorrelationId; pass it to wait_for_answer to collect the answer. The embedded question expires 10 minutes after it is created.",
                          "properties": {
                            "options": {
                              "description": "The 2 to 6 choices for a select question",
                              "items": {
                                "type": "string"
                              },
                              "maxItems": 6,
                              "minItems": 2,
                              "type": "array"
                            },
                            "question": {
                              "description": "A follow-up question shown below the context (e.g. \"Retry with a different approach?\")",
                              "maxLength": 500,
                              "minLength": 1,
                              "type": "string"
                            },
                            "type": {
                              "default": "confirm",
                              "description": "Question type: confirm (yes/no), select (pick from options), or input (free text)",
                              "enum": [
                                "confirm",
                                "select",
                                "input"
                              ],
                              "type": "string"
                            }
                          },
                          "required": [
                            "question"
                          ],
                          "type": "object"
                        },
                        "details": {
                          "description": "Bullet-point details rendered as a list",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "errorFile": {
                          "description": "File path where the error occurred",
                          "type": "string"
                        },
                        "errorMessage": {
                          "description": "The error message, when type is \"error\"",
                          "type": "string"
                        },
                        "filesChanged": {
                          "description": "Paths of files that were created or modified",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "nextSteps": {
                          "description": "What the user should do next, e.g. \"Review the PR\" or \"Re-run with --force\"",
                          "type": "string"
                        },
                        "summary": {
                          "description": "Short summary of what happened, shown at the top of the detail page",
                          "type": "string"
                        },
                        "type": {
                          "description": "What kind of update this is. Use \"task_complete\" when work finished, \"error\" when something failed (delivered with high urgency), \"info\" for everything else.",
                          "enum": [
                            "task_complete",
                            "error",
                            "info"
                          ],
                          "type": "string"
                        }
                      },
                      "required": [
                        "type"
                      ],
                      "type": "object"
                    },
                    "env": {
                      "description": "Set to \"test\" from a test suite. The notification is recorded in the activity feed and nothing is delivered to a phone or browser. The X-Pushary-Env: test header does the same for every call on the connection.",
                      "enum": [
                        "test"
                      ],
                      "type": "string"
                    },
                    "externalIds": {
                      "description": "Deliver only to subscribers matching these external IDs.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "iconUrl": {
                      "description": "URL of the notification icon image",
                      "format": "uri",
                      "type": "string"
                    },
                    "imageUrl": {
                      "description": "URL of a large image shown in the notification",
                      "format": "uri",
                      "type": "string"
                    },
                    "machineId": {
                      "description": "Stable machine id of the sending agent, so two machines never collapse into one session.",
                      "maxLength": 128,
                      "type": "string"
                    },
                    "sessionId": {
                      "description": "Opaque per-session id of the sending agent, so parallel sessions are attributed separately in the activity feed.",
                      "maxLength": 128,
                      "type": "string"
                    },
                    "subscriberIds": {
                      "description": "Deliver only to these subscriber IDs. Omit all targeting fields to reach every connected device.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "tags": {
                      "description": "Deliver only to subscribers that have any of these tags.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "title": {
                      "description": "Notification title shown on the lock screen (max 100 chars). Lead with the outcome, e.g. \"Build finished\" or \"Migration failed\".",
                      "maxLength": 100,
                      "minLength": 1,
                      "type": "string"
                    },
                    "url": {
                      "description": "URL opened when the user taps the notification. Ignored if context is provided, because a context detail page URL is generated automatically.",
                      "format": "uri",
                      "type": "string"
                    }
                  },
                  "required": [
                    "title",
                    "body"
                  ],
                  "type": "object"
                },
                "outputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "additionalProperties": false,
                  "properties": {
                    "delivery": {
                      "additionalProperties": false,
                      "description": "Per-channel outcome. The two channels are independent with no cross-fallback, so each reports its own result.",
                      "properties": {
                        "mobile": {
                          "additionalProperties": false,
                          "properties": {
                            "recipients": {
                              "description": "Phones that accepted the push.",
                              "type": "number"
                            },
                            "status": {
                              "description": "Why mobile delivery reached nobody, present only when it reached nobody.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "recipients"
                          ],
                          "type": "object"
                        },
                        "web": {
                          "additionalProperties": false,
                          "properties": {
                            "recipients": {
                              "description": "Browsers that accepted the push.",
                              "type": "number"
                            },
                            "status": {
                              "description": "Why web delivery reached nobody, present only when it reached nobody.",
                              "type": "string"
                            }
                          },
                          "required": [
                            "recipients"
                          ],
                          "type": "object"
                        }
                      },
                      "required": [
                        "web",
                        "mobile"
                      ],
                      "type": "object"
                    },
                    "env": {
                      "description": "Echoed when the call was test traffic.",
                      "enum": [
                        "test"
                      ],
                      "type": "string"
                    },
                    "hint": {
                      "description": "What to do next, when there is a next step.",
                      "type": "string"
                    },
                    "linkedCorrelationId": {
                      "description": "Present only when context.askQuestion embedded a decision prompt. Pass it to wait_for_answer to collect the response.",
                      "type": "string"
                    },
                    "sent": {
                      "description": "Total devices reached, web plus mobile. Zero is a successful call that found nobody to deliver to, not an error.",
                      "type": "number"
                    },
                    "warning": {
                      "description": "Present only when the notification reached zero devices, naming what the user has to connect.",
                      "type": "string"
                    }
                  },
                  "type": "object"
                },
                "annotations": {
                  "destructiveHint": true,
                  "idempotentHint": false,
                  "openWorldHint": true,
                  "readOnlyHint": false
                }
              },
              {
                "name": "ask_user",
                "title": "Ask User a Question",
                "description": "Request an unresolved decision or missing input from the user through Pushary. Supports confirm, select and input questions. Delivery and waiting follow the account policy; a call waits at most 55 seconds and may return immediately. Returns the question state, answer when available, delivery information and handoff fields. answerUrl is optional. Use wait_for_answer to read a pending result and cancel_question to retract it. Sends a real question; it does not grant permission for other actions.",
                "inputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "properties": {
                    "action": {
                      "description": "The concrete operation about to happen, one line. Shown as the Action line. Cut to 500 chars.",
                      "minLength": 0,
                      "type": "string"
                    },
                    "actionBody": {
                      "description": "The diff (Edit/Write) or full command (Bash/apply_patch), secret-redacted and size-capped. Rendered as a collapsible detail block; never used as the push body.",
                      "maxLength": 4000,
                      "type": "string"
                    },
                    "agentName": {
                      "description": "Name of the agent asking, format \"{Agent} - {project}\" (e.g. \"Claude Code - myproject\"). Shown in the notification title so the user knows which session needs them. Falls back to the MCP client name if omitted. Cut to 100 chars.",
                      "minLength": 0,
                      "type": "string"
                    },
                    "blocker": {
                      "description": "The single gating reason the agent stopped, one line. Shown as the Blocker line. Cut to 500 chars.",
                      "minLength": 0,
                      "type": "string"
                    },
                    "callbackUrl": {
                      "description": "Webhook URL that receives a POST with the answer when the user responds, signed with the X-Pushary-Signature header. Useful when the agent process may exit before the answer arrives.",
                      "format": "uri",
                      "type": "string"
                    },
                    "context": {
                      "description": "One or two sentences about what the agent is working on, shown above the question so the user can decide without opening the terminal.",
                      "maxLength": 500,
                      "type": "string"
                    },
                    "env": {
                      "description": "Set to \"test\" from a test suite. The question is stored and returned as pending, and nothing is delivered to a phone, browser or Slack. The X-Pushary-Env: test header does the same for every call on the connection.",
                      "enum": [
                        "test"
                      ],
                      "type": "string"
                    },
                    "externalIds": {
                      "description": "Deliver only to subscribers matching these external IDs.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "intent": {
                      "description": "The user's stated task (from their last prompt), one line. Shown as the Intent line so the user can see why the agent stopped. Cut to 500 chars.",
                      "minLength": 0,
                      "type": "string"
                    },
                    "localSurfaceAvailable": {
                      "description": "MACHINE-POPULATED. false from a hook that cannot show its own approval prompt for this call, so the phone is asked every time and never spared for presence at the keyboard. Any other value is ignored. If you are a model deciding to call this tool, omit this field.",
                      "type": "boolean"
                    },
                    "machineId": {
                      "description": "Stable machine id of the asking agent, so two machines never collapse into one session.",
                      "maxLength": 128,
                      "type": "string"
                    },
                    "options": {
                      "description": "The 2 to 6 choices for a select question. Required when type is \"select\", ignored otherwise. The answered value is the chosen option string.",
                      "items": {
                        "minLength": 1,
                        "type": "string"
                      },
                      "maxItems": 6,
                      "minItems": 2,
                      "type": "array"
                    },
                    "pausedAware": {
                      "description": "MACHINE-POPULATED. true from a hook that ends a paused approval exactly as the same approval unanswered after its full wait. Any other value is ignored. If you are a model deciding to call this tool, omit this field.",
                      "type": "boolean"
                    },
                    "permissionMode": {
                      "description": "MACHINE-POPULATED. The agent runtime's own permission or approval mode for the tool call this approval gates, recorded with the decision. Any other value is ignored. If you are a model deciding to call this tool, omit this field.",
                      "maxLength": 64,
                      "type": "string"
                    },
                    "placeholder": {
                      "description": "Hint text shown inside the free-text field for input questions",
                      "maxLength": 200,
                      "type": "string"
                    },
                    "question": {
                      "description": "The question shown on the user's lock screen (500 chars; a longer one is cut). Phrase it so it is answerable at a glance; put background in context instead.",
                      "minLength": 1,
                      "type": "string"
                    },
                    "questions": {
                      "description": "ONE question, in the richer Claude-compatible shape: a header, per-option descriptions, multiSelect, and an optional write-in. Exactly one keeps already-installed clients answerable; asking several means several calls. Runtime-populated; ordinary callers should omit it and use question/type/options.",
                      "items": {
                        "properties": {
                          "allowOther": {
                            "type": "boolean"
                          },
                          "header": {
                            "maxLength": 40,
                            "type": "string"
                          },
                          "multiSelect": {
                            "type": "boolean"
                          },
                          "options": {
                            "items": {
                              "properties": {
                                "description": {
                                  "maxLength": 500,
                                  "type": "string"
                                },
                                "label": {
                                  "maxLength": 100,
                                  "minLength": 1,
                                  "type": "string"
                                }
                              },
                              "required": [
                                "label"
                              ],
                              "type": "object"
                            },
                            "maxItems": 4,
                            "minItems": 2,
                            "type": "array"
                          },
                          "question": {
                            "maxLength": 500,
                            "minLength": 1,
                            "type": "string"
                          }
                        },
                        "required": [
                          "question",
                          "multiSelect",
                          "options"
                        ],
                        "type": "object"
                      },
                      "maxItems": 1,
                      "minItems": 1,
                      "type": "array"
                    },
                    "repoKey": {
                      "description": "Stable repository identity for the working directory, e.g. \"github.com/acme/api\". Lets an approval routing rule scoped to one repository avoid governing another. Optional; omit it and only workspace-wide routing rules apply.",
                      "maxLength": 200,
                      "type": "string"
                    },
                    "requestId": {
                      "description": "MACHINE-POPULATED. The CALLER's own identifier for one logical invocation, used only when the runtime supplies no toolUseId. Mint it once, outside your retry loop, and send the same value on every attempt, so three retries of one ask become one decision. Do NOT derive it from the question text or reuse it across two deliberate asks: both collapse a real second question into the first one's answer. If you are a model deciding to call this tool, omit this field.",
                      "maxLength": 200,
                      "type": "string"
                    },
                    "scopePath": {
                      "description": "Set ONLY when this approval exists because the path falls outside the scope the user ratified via propose_scope. Approving then widens the run scope to include this exact path, so the user is not asked again for the same area.",
                      "maxLength": 200,
                      "type": "string"
                    },
                    "sessionId": {
                      "description": "Opaque per-session id of the asking agent, so parallel sessions are attributed separately.",
                      "maxLength": 128,
                      "type": "string"
                    },
                    "sessionToolAware": {
                      "description": "MACHINE-POPULATED. Set by a Pushary hook whose engine applies a session tool grant with its risky-command ceiling, so the grant is only offered where it takes effect. If you are a model deciding to call this tool, omit this field.",
                      "type": "boolean"
                    },
                    "subscriberIds": {
                      "description": "Deliver only to these subscriber IDs. Omit all targeting fields to reach every connected device.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "tags": {
                      "description": "Deliver only to subscribers that have any of these tags.",
                      "items": {
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "timeoutMs": {
                      "description": "How long this call blocks, in milliseconds (max 55000). Defaults to the site policy timeout. The question stays open for 10 minutes regardless, so a timeout here is not a refusal; follow up with wait_for_answer.",
                      "maximum": 55000,
                      "minimum": 1000,
                      "type": "integer"
                    },
                    "toolName": {
                      "description": "The tool this approval is for (e.g. \"Bash\"), so the user can choose to always-allow it.",
                      "maxLength": 100,
                      "type": "string"
                    },
                    "toolPath": {
                      "description": "MACHINE-POPULATED. Exact absolute Write file_path from the runtime, for diagnostic correlation only. Models must omit it.",
                      "format": "starts_with",
                      "maxLength": 4096,
                      "pattern": "^\\/.*",
                      "type": "string"
                    },
                    "toolTarget": {
                      "description": "Compact target of the tool call (e.g. the command head \"git push\" for Bash, or a file extension like \".ts\" for Edit/Write). Used to mine policy suggestions.",
                      "maxLength": 80,
                      "type": "string"
                    },
                    "toolUseId": {
                      "description": "MACHINE-POPULATED. The agent RUNTIME's own identifier for the tool call this approval gates, forwarded verbatim by a hook that received it. Do NOT invent, guess, derive, or reuse a value: two different questions sent under the same id collapse into one, and the second one never reaches a human. If you are a model deciding to call this tool, omit this field.",
                      "maxLength": 200,
                      "type": "string"
                    },
                    "type": {
                      "default": "confirm",
                      "description": "Question type: confirm renders yes/no buttons, select renders the options list, input renders a free-text field.",
                      "enum": [
                        "confirm",
                        "select",
                        "input"
                      ],
                      "type": "string"
                    },
                    "wait": {
                      "default": true,
                      "description": "true (default) blocks until the user answers or the timeout fires. Set false to return immediately with a pending correlationId and poll it yourself via wait_for_answer.",
                      "type": "boolean"
                    },
                    "waitEndsAt": {
                      "description": "MACHINE-POPULATED. When the agent hook stops waiting live and hands control back to the terminal. The question may remain answerable after this time. Ordinary callers should omit it.",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "type": "string"
                    }
                  },
                  "required": [
                    "question"
                  ],
                  "type": "object"
                },
                "outputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "additionalProperties": false,
                  "properties": {
                    "answerSource": {
                      "description": "Recorded answering surface, when known. Missing provenance is not proof of a phone answer; sandbox is simulated.",
                      "enum": [
                        "dashboard",
                        "mobile_app",
                        "mobile_background",
                        "decide_page",
                        "live_page",
                        "answer_link",
                        "inbox",
                        "slack",
                        "mac_app",
                        "sandbox"
                      ],
                      "type": "string"
                    },
                    "answerUrl": {
                      "description": "Optional signed-in dashboard page where the user can answer this question.",
                      "type": "string"
                    },
                    "answered": {
                      "description": "True once the user responded. Absent on the wait:false path, where nothing was awaited.",
                      "type": "boolean"
                    },
                    "correlationId": {
                      "description": "Id of the question that was created. Pass it to wait_for_answer to keep waiting, or to cancel_question to retract it.",
                      "type": "string"
                    },
                    "delivery": {
                      "additionalProperties": false,
                      "description": "Per-channel reach for the push carrying this question.",
                      "properties": {
                        "mobile": {
                          "description": "Phones the question reached.",
                          "type": "number"
                        },
                        "pending": {
                          "description": "True when delivery was still in flight when this returned, so the counts above are not final.",
                          "type": "boolean"
                        },
                        "web": {
                          "description": "Browsers the question reached.",
                          "type": "number"
                        }
                      },
                      "required": [
                        "web",
                        "mobile"
                      ],
                      "type": "object"
                    },
                    "deliveryMode": {
                      "description": "Effective delivery policy for this decision.",
                      "enum": [
                        "push_first",
                        "push_only",
                        "notify_only",
                        "terminal_only"
                      ],
                      "type": "string"
                    },
                    "env": {
                      "description": "Echoed when the call was test traffic.",
                      "enum": [
                        "test"
                      ],
                      "type": "string"
                    },
                    "expiresInSeconds": {
                      "description": "How long the question stays answerable.",
                      "type": "number"
                    },
                    "handoffAction": {
                      "description": "Race-safe directive for updated clients. Takes precedence over nextAction: cancel before asking in the current client, or stop the handoff.",
                      "enum": [
                        "cancel_then_ask_in_current_client",
                        "stop"
                      ],
                      "type": "string"
                    },
                    "held": {
                      "description": "Present when the question was stored but deliberately not delivered: test traffic, or a permission ask with no toolName and no sessionId.",
                      "enum": [
                        "test_traffic",
                        "unattributed"
                      ],
                      "type": "string"
                    },
                    "hint": {
                      "description": "What to do next, when there is a next step.",
                      "type": "string"
                    },
                    "mode": {
                      "description": "The site delivery mode that stopped this call from waiting.",
                      "enum": [
                        "notify_only",
                        "terminal_only"
                      ],
                      "type": "string"
                    },
                    "nextAction": {
                      "description": "Backward-compatible next step: poll once or ask in the current client. Follow handoffAction first when present.",
                      "enum": [
                        "wait_for_answer",
                        "ask_in_current_client"
                      ],
                      "type": "string"
                    },
                    "noDevices": {
                      "description": "True when no phone, browser, or Slack channel could receive the question. Do not wait; follow handoffAction immediately.",
                      "type": "boolean"
                    },
                    "note": {
                      "description": "Free text the user added alongside their answer.",
                      "type": "string"
                    },
                    "paused": {
                      "description": "True when nothing was sent because the last approvals in this session went unanswered. Withdraw the question, then end the call as it would end unanswered.",
                      "type": "boolean"
                    },
                    "policyTimeoutMs": {
                      "description": "Policy wait window in milliseconds. Callers must also honor their host deadline.",
                      "minimum": 0,
                      "type": "number"
                    },
                    "question": {
                      "description": "The question exactly as the user saw it.",
                      "type": "string"
                    },
                    "status": {
                      "description": "The question state. Only pending is a live unanswered wait; cancelled, expired, missing, and unavailable must not be described as timeouts.",
                      "enum": [
                        "answered",
                        "pending",
                        "cancelled",
                        "expired",
                        "missing",
                        "unavailable",
                        "notified",
                        "terminal",
                        "stopped"
                      ],
                      "type": "string"
                    },
                    "suppressed": {
                      "description": "True when the PHONE push was deliberately held because a terminal on this machine is active. It says nothing about the notch, the dashboard or Slack, which are unaffected and may still be showing this question. A caller with no screen of its own should treat it as the terminal's to answer; a caller that can render the question itself should keep waiting.",
                      "type": "boolean"
                    },
                    "timedOut": {
                      "description": "True when the initial wait ended while the question was still live. Poll once with wait_for_answer, then follow handoffAction when present, otherwise nextAction.",
                      "type": "boolean"
                    },
                    "type": {
                      "description": "The question type that was rendered.",
                      "enum": [
                        "confirm",
                        "select",
                        "input"
                      ],
                      "type": "string"
                    },
                    "value": {
                      "description": "The user's answer: \"yes\" or \"no\" for confirm, the chosen option for select, the typed text for input.",
                      "type": "string"
                    },
                    "waitEndsAt": {
                      "description": "When the agent hook stops waiting live. On an idempotent replay this is the original question's deadline, which the hook must reuse.",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$",
                      "type": "string"
                    },
                    "warning": {
                      "description": "Present only when no channel is connected, naming what the user has to connect.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "correlationId",
                    "question",
                    "type"
                  ],
                  "type": "object"
                },
                "annotations": {
                  "destructiveHint": true,
                  "idempotentHint": false,
                  "openWorldHint": true,
                  "readOnlyHint": false
                }
              },
              {
                "name": "propose_scope",
                "title": "Propose Run Scope",
                "description": "Request agreement on an unresolved or user-requested boundary for this session. Sends a real scope question and returns ratified, answered, contract and enforcement information. Only supported hooks can enforce file paths on path-bearing tool calls; promises are recorded but not enforced. Empty enforces means no automatic boundary checking. A contract never overrides host permissions or authorizes a separate action. The call waits at most 55 seconds; a pending proposal can be read with wait_for_answer.",
                "inputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "properties": {
                    "agentName": {
                      "description": "Name of the agent asking, format \"{Agent} - {project}\".",
                      "maxLength": 100,
                      "type": "string"
                    },
                    "allowedPaths": {
                      "description": "Globs you intend to change, e.g. [\"src/**\", \"docs/*.md\"]. File paths only: a word that is not a path (\"hubspot\", \"summer-campaign\") matches no file and makes every edit read as out of scope. A bare directory is expanded for you, so \"docs\" also covers \"docs/**\". Omit or leave empty to propose no path restriction, which the user is told plainly.",
                      "items": {
                        "maxLength": 200,
                        "minLength": 1,
                        "type": "string"
                      },
                      "maxItems": 40,
                      "type": "array"
                    },
                    "doneWhen": {
                      "description": "What \"finished\" means for this run, one or two lines. Carried for the human to judge against; never enforced automatically.",
                      "maxLength": 300,
                      "minLength": 1,
                      "type": "string"
                    },
                    "machineId": {
                      "description": "Stable machine id, so two machines never collapse into one session.",
                      "maxLength": 128,
                      "type": "string"
                    },
                    "offLimitsPaths": {
                      "description": "Globs you promise not to touch, e.g. [\".env*\", \"infra/**\"]. These win wherever they overlap allowedPaths. A leading \"**/\" needs a directory before it, so \"**/.env*\" is expanded for you to also cover a root \".env\".",
                      "items": {
                        "maxLength": 200,
                        "minLength": 1,
                        "type": "string"
                      },
                      "maxItems": 40,
                      "type": "array"
                    },
                    "promises": {
                      "description": "Boundaries that are not file paths: recipients, channels, spend limits, systems you will not open. For an agent whose work is not code (marketing, sales, support, operations), this is where the boundary goes. Shown to the user labelled \"Promised, not checked\" and recorded in the ledger, but NEVER enforced, because the gate judges a file path and these have none. Do not put these in allowedPaths.",
                      "items": {
                        "maxLength": 200,
                        "minLength": 1,
                        "type": "string"
                      },
                      "maxItems": 10,
                      "type": "array"
                    },
                    "sessionId": {
                      "description": "Your per-session id, as your client reports it for THIS run. Required, and it is the key the gate reads the contract back by: a value that matches no live session still returns ratified:true and enforces nothing. Never invent one, and never reuse one from another run.",
                      "maxLength": 128,
                      "minLength": 1,
                      "type": "string"
                    },
                    "timeoutMs": {
                      "description": "How long this call blocks, in milliseconds (max 55000).",
                      "maximum": 55000,
                      "minimum": 1000,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "doneWhen",
                    "sessionId"
                  ],
                  "type": "object"
                },
                "outputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "additionalProperties": false,
                  "properties": {
                    "answered": {
                      "description": "True when the user responded at all. Answered but not ratified means they declined, so ask what scope they want rather than proceeding.",
                      "type": "boolean"
                    },
                    "contract": {
                      "additionalProperties": false,
                      "description": "The scope as it is STORED and gated, echoed back so you and the server hold the same contract. Paths are the EXPANDED ones: a bare directory and a leading \"**/\" each gain the variant they would otherwise have missed, so this can contain more entries than you sent. The user was shown the paths you sent, because the added twin says the same thing to a reader; the expansion only changes what the matcher covers, never what it means.",
                      "properties": {
                        "allowedPaths": {
                          "description": "Globs the run may change, after expansion. Empty means no path restriction was proposed, which the user was told plainly.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "doneWhen": {
                          "description": "What finished means for this run, as the user saw it.",
                          "type": "string"
                        },
                        "offLimitsPaths": {
                          "description": "Globs the run promised not to touch, after expansion. These win wherever they overlap allowedPaths.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        },
                        "promises": {
                          "description": "Non-path boundaries as the user saw them. Recorded, never enforced.",
                          "items": {
                            "type": "string"
                          },
                          "type": "array"
                        }
                      },
                      "required": [
                        "allowedPaths",
                        "offLimitsPaths",
                        "doneWhen"
                      ],
                      "type": "object"
                    },
                    "correlationId": {
                      "description": "Id of the scope question. Pass it to wait_for_answer once when the first wait times out.",
                      "type": "string"
                    },
                    "enforcementNote": {
                      "description": "Present only when there is something true to say about the limits of this contract. Repeat it to the user rather than paraphrasing it.",
                      "type": "string"
                    },
                    "enforces": {
                      "description": "What this contract CONTAINS that can be checked, not a promise about what the gate on this machine will do. An EMPTY array means nothing here is checked automatically: the contract is a recorded promise, and every action stays governed by the permission policy exactly as it was before. Never tell the user a boundary is enforced when this is empty.",
                      "items": {
                        "enum": [
                          "paths"
                        ],
                        "type": "string"
                      },
                      "type": "array"
                    },
                    "handoffAction": {
                      "description": "Race-safe directive for updated clients. Takes precedence over nextAction.",
                      "enum": [
                        "cancel_then_ask_in_current_client",
                        "stop"
                      ],
                      "type": "string"
                    },
                    "hookSeen": {
                      "description": "Whether any agent hook has actually reported this sessionId. FALSE means the gate will look this contract up under a key that does not exist, so nothing will be checked no matter what ratified says: fix the session id rather than proceeding as if a scope were in force. ABSENT means the check could not run, which is not evidence either way.",
                      "type": "boolean"
                    },
                    "nextAction": {
                      "description": "Poll one live question once; otherwise ask in the current chat whether to continue without an enforced scope.",
                      "enum": [
                        "wait_for_answer",
                        "ask_in_current_client"
                      ],
                      "type": "string"
                    },
                    "note": {
                      "description": "Present only when the scope is not in force, saying what to do instead of proceeding.",
                      "type": "string"
                    },
                    "ratified": {
                      "description": "True only on an explicit yes. The contract is in force for this session only when this is true; anything else means proceed as if no scope was agreed.",
                      "type": "boolean"
                    },
                    "status": {
                      "description": "The underlying scope-question state.",
                      "enum": [
                        "answered",
                        "pending",
                        "cancelled",
                        "expired",
                        "missing",
                        "unavailable",
                        "notified",
                        "terminal",
                        "stopped"
                      ],
                      "type": "string"
                    },
                    "value": {
                      "description": "The raw answer behind ratified, \"yes\" or \"no\".",
                      "type": "string"
                    }
                  },
                  "required": [
                    "correlationId",
                    "ratified",
                    "answered",
                    "enforces",
                    "contract"
                  ],
                  "type": "object"
                },
                "annotations": {
                  "destructiveHint": true,
                  "idempotentHint": false,
                  "openWorldHint": true,
                  "readOnlyHint": false
                }
              },
              {
                "name": "wait_for_answer",
                "title": "Wait for User Answer",
                "description": "Read the answer or current state of an existing question from ask_user or send_notification. Waits up to timeoutMs, capped at 55 seconds. Returns answered, the answer when available, status and handoff information. Only pending is a live unanswered question; cancelled, expired, missing and unavailable are terminal states. Does not send another question.",
                "inputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "properties": {
                    "correlationId": {
                      "description": "The correlationId from an earlier ask_user response, or the linkedCorrelationId from a send_notification with an embedded askQuestion",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "type": "string"
                    },
                    "timeoutMs": {
                      "description": "How long this one poll blocks, in milliseconds (default 30000, max 55000). Follow handoffAction when present, otherwise nextAction.",
                      "maximum": 55000,
                      "minimum": 1000,
                      "type": "integer"
                    }
                  },
                  "required": [
                    "correlationId"
                  ],
                  "type": "object"
                },
                "outputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "additionalProperties": false,
                  "properties": {
                    "answerSource": {
                      "description": "Recorded answering surface, when known. Missing provenance is not proof of a phone answer; sandbox is simulated.",
                      "enum": [
                        "dashboard",
                        "mobile_app",
                        "mobile_background",
                        "decide_page",
                        "live_page",
                        "answer_link",
                        "inbox",
                        "slack",
                        "mac_app",
                        "sandbox"
                      ],
                      "type": "string"
                    },
                    "answered": {
                      "description": "True once the user responded. False means follow handoffAction when present, otherwise nextAction; do not guess that every unanswered state is a timeout.",
                      "type": "boolean"
                    },
                    "handoffAction": {
                      "description": "Race-safe directive for updated clients. Takes precedence over nextAction.",
                      "enum": [
                        "cancel_then_ask_in_current_client",
                        "stop"
                      ],
                      "type": "string"
                    },
                    "hint": {
                      "description": "What to do next, when there is a next step.",
                      "type": "string"
                    },
                    "nextAction": {
                      "description": "Backward-compatible next step for older clients. Follow handoffAction first when present.",
                      "enum": [
                        "wait_for_answer",
                        "ask_in_current_client"
                      ],
                      "type": "string"
                    },
                    "note": {
                      "description": "Free text the user added alongside their answer.",
                      "type": "string"
                    },
                    "status": {
                      "description": "The actual question state. Only pending is a live unanswered wait.",
                      "enum": [
                        "answered",
                        "pending",
                        "cancelled",
                        "expired",
                        "missing",
                        "unavailable"
                      ],
                      "type": "string"
                    },
                    "value": {
                      "description": "The user's answer: \"yes\" or \"no\" for confirm, the chosen option for select, the typed text for input. Present only when answered is true.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "answered",
                    "status"
                  ],
                  "type": "object"
                },
                "annotations": {
                  "destructiveHint": false,
                  "idempotentHint": true,
                  "openWorldHint": false,
                  "readOnlyHint": true
                }
              },
              {
                "name": "cancel_question",
                "title": "Cancel Pending Question",
                "description": "Retract a pending question that is no longer needed or is moving to the current client. Returns cancelled:true only when a pending question was removed. False may mean it was already answered, expired, missing or unavailable. An unavailable state includes handoffAction:stop because cancellation could not safely inspect or fence the question. Does not retract an answer already recorded.",
                "inputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "properties": {
                    "correlationId": {
                      "description": "The correlationId of the pending question to cancel, as returned by ask_user or send_notification",
                      "format": "uuid",
                      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$",
                      "type": "string"
                    },
                    "handoff": {
                      "description": "True when you are cancelling because you are about to ask the same question in the current client. For the next minute the Pushary hook then lets your own question tool through instead of sending it back to the phone. Set automatically whenever a live question is cancelled.",
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "correlationId"
                  ],
                  "type": "object"
                },
                "outputSchema": {
                  "$schema": "http://json-schema.org/draft-07/schema#",
                  "additionalProperties": false,
                  "properties": {
                    "askHandoff": {
                      "description": "True when the session was marked as handing off to the current client, so the hook will not re-ask on the phone for the next minute.",
                      "type": "boolean"
                    },
                    "cancelled": {
                      "description": "True when a still-pending question was removed. False when it was already terminal, missing, or unavailable; inspect status and handoffAction when present.",
                      "type": "boolean"
                    },
                    "correlationId": {
                      "description": "The question this result refers to, echoed back.",
                      "type": "string"
                    },
                    "handoffAction": {
                      "const": "stop",
                      "description": "Stop rather than opening another answer surface when the question state is unavailable.",
                      "type": "string"
                    },
                    "hint": {
                      "description": "What to do when cancellation could not safely inspect the question.",
                      "type": "string"
                    },
                    "status": {
                      "const": "unavailable",
                      "description": "Present when Pushary could not safely read or fence the question state.",
                      "type": "string"
                    }
                  },
                  "required": [
                    "cancelled",
                    "correlationId"
                  ],
                  "type": "object"
                },
                "annotations": {
                  "destructiveHint": true,
                  "idempotentHint": true,
                  "openWorldHint": false,
                  "readOnlyHint": false
                }
              }
            ],
            "schemaTokens": 8280,
            "changedAt": "2026-10-01T21:57:41.236598089Z",
            "check": {
              "checker": "anchor-check/1.0",
              "totalTokens": 8280,
              "counts": {
                "error": 0,
                "note": 0,
                "warn": 4
              },
              "findings": [
                {
                  "rule": "TC11",
                  "severity": "warn",
                  "tool": "ask_user",
                  "message": "2 parameters without a description: questions[].options[].description, questions[].options[].label",
                  "fix": "Describe each one: format, units, an example, and what happens when it's left out."
                },
                {
                  "rule": "TC22",
                  "severity": "warn",
                  "tool": "ask_user",
                  "message": "the definition is about 3,578 tokens",
                  "fix": "Trim the description and parameter docs, or split the tool."
                },
                {
                  "rule": "TC22",
                  "severity": "warn",
                  "tool": "propose_scope",
                  "message": "the definition is about 1,699 tokens",
                  "fix": "Trim the description and parameter docs, or split the tool."
                },
                {
                  "rule": "TC22",
                  "severity": "warn",
                  "tool": "send_notification",
                  "message": "the definition is about 1,575 tokens",
                  "fix": "Trim the description and parameter docs, or split the tool."
                }
              ]
            }
          },
          "updatedAt": "2026-10-05T00:57:26.524607182Z"
        }
      },
      {
        "slug": "gotohuman",
        "name": "gotoHuman",
        "vendor": "gotoHuman",
        "vendorUrl": "https://www.gotohuman.com",
        "kind": "http-api",
        "category": "human-in-the-loop",
        "summary": "Hosted review inbox for AI agents.",
        "url": "https://www.anchorterminal.com/tools/gotohuman",
        "markdownUrl": "https://www.anchorterminal.com/tools/gotohuman.md",
        "slimMarkdownUrl": "https://www.anchorterminal.com/tools/gotohuman.min.md",
        "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/gotohuman.json",
        "repo": "https://github.com/gotohuman/gotohuman-mcp-server",
        "license": "MIT (SDKs and MCP server)",
        "transports": [
          "http",
          "stdio"
        ],
        "remoteUrl": "https://api.gotohuman.com",
        "packages": [
          {
            "registry": "npm",
            "name": "gotohuman"
          },
          {
            "registry": "pypi",
            "name": "gotohuman"
          },
          {
            "registry": "npm",
            "name": "@gotohuman/mcp-server"
          }
        ],
        "auth": "api-key",
        "authNotes": "API key in an `x-api-key` header. The SDKs and the MCP server read `GOTOHUMAN_API_KEY`, plus an optional `GOTOHUMAN_AGENT_ID` that ties requests to an agent set up in the dashboard. Reviewers sign in to the web inbox, and Slack notifications can carry a short-lived public link instead.",
        "pricing": "freemium",
        "pricingNotes": "Free $0 a month for 1 user and up to 300 reviews a month, with the web inbox, email and Slack and a 7-day history. Team $99 a month with 6 users ($15 per extra user), review routing, the Reviews API and a 60-day history. Growth $350 a month with 20 users ($17 per extra user), several teams and a 90-day history. Business $950 a month with 50 users, 5 workspaces, audit logs and custom retention. The paid plans don't state a review cap, and there's no yearly price on the page (https://www.gotohuman.com/pricing).",
        "priceSummary": "$99 / mo",
        "where": "both",
        "x402": {
          "level": "no",
          "endpoints": []
        },
        "toolCount": 3,
        "popularity": {
          "githubStars": null,
          "npmWeekly": null,
          "pypiWeekly": null,
          "asOf": "2026-09-30"
        },
        "docsUrl": "https://docs.gotohuman.com",
        "llmsTxt": "https://docs.gotohuman.com/llms.txt",
        "capabilities": [
          "hitl.approve",
          "hitl.ask",
          "hitl.channels",
          "hitl.audit"
        ],
        "tags": [
          "hosted",
          "freemium",
          "free-tier",
          "mcp",
          "llms-txt",
          "typescript",
          "python",
          "webhooks",
          "enterprise"
        ],
        "lastRelease": "2026-09-24",
        "graded": true,
        "anchor": {
          "graded": true,
          "score": 43.9,
          "grade": "E",
          "agentReady": false,
          "rank": 407,
          "ranked": true,
          "rankOf": 452,
          "categoryRank": 7,
          "methodology": "0.3",
          "run": "2026-10-01",
          "scores": {
            "ergonomics": 62,
            "maintenance": 64,
            "payments": 30,
            "reliability": 20,
            "schema": 49,
            "security": 44,
            "transparency": 55
          },
          "pending": [
            "performance",
            "tasks"
          ],
          "assessment": {
            "confidence": "medium",
            "date": "2026-10-01"
          },
          "negative": 0,
          "verdict": "Built for agent review, with TypeScript and Python SDKs, a 3-tool MCP server, an n8n node and a Make app. No status page, published rate limits or documented error responses.",
          "strengths": [
            "Built for agent review, with TypeScript and Python SDKs, a 3-tool MCP server, an n8n node and a Make app",
            "Reviewers can edit the output before approving, and the webhook returns the edited data",
            "Web inbox, email and Slack on every plan, including the $0 one",
            "Webhooks retry up to 7 times over about 9 hours and carry an `Idempotency-Key` header",
            "Terms rule out training on customer data, and processing is mainly in the EU"
          ],
          "weaknesses": [
            "No status page, published rate limits or documented error responses",
            "No review expiry or timeout that we could find in the docs",
            "Review routing and the Reviews API start at $99 a month, audit logs at $950",
            "The API reference and the SDK guide disagree on field names and on whether `agentId` is required",
            "No security.txt, disclosure policy or own SOC 2 report"
          ],
          "agentNotes": [
            "Call `get-form-schema` before `request-human-review-with-form`, since the field data must match the review type",
            "Send `agentId` on every API request, because the API reference marks it required even though the JS SDK doesn't",
            "Pass a `webhookUrl` per request when the review type has no default, or the answer has nowhere to go",
            "Deduplicate webhook calls on the `Idempotency-Key` header, since delivery is at least once",
            "Set your own deadline on the agent side and treat silence as a rejection"
          ],
          "metrics": {
            "kind": "remote",
            "measured": false
          },
          "reviewCount": 2,
          "avgRating": 2,
          "history": [
            {
              "basis": "public evidence",
              "confidence": "medium",
              "grade": "E",
              "methodology": "0.3",
              "pending": [
                "performance",
                "tasks"
              ],
              "run": "2026-10-01",
              "runLabel": "October 2026 research run",
              "score": 43.9
            }
          ],
          "editorialScores": {
            "ergonomics": 62,
            "maintenance": 64,
            "payments": 30,
            "reliability": 20,
            "schema": 49,
            "security": 44,
            "transparency": 54
          },
          "provenanceScore": 55
        },
        "connect": {
          "http": "curl -X POST https://api.gotohuman.com/requestReview -H \"x-api-key: $GOTOHUMAN_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"formId\":\"YOUR_REVIEW_TEMPLATE_ID\",\"fields\":{\"draft\":\"Refund order 1042 in full?\"},\"meta\":{\"threadId\":\"t-1\"}}'",
          "config": {
            "mcpServers": {
              "gotoHuman": {
                "args": [
                  "-y",
                  "@gotohuman/mcp-server"
                ],
                "command": "npx",
                "env": {
                  "GOTOHUMAN_API_KEY": "${GOTOHUMAN_API_KEY}"
                }
              }
            }
          }
        },
        "letme": {
          "capability": "https://letme.dev/hitl.approve",
          "tool": "https://letme.dev/gotohuman"
        },
        "area": "agent-runtime",
        "unitPrices": [
          {
            "item": "Team plan",
            "unit": "month",
            "usd": 99,
            "note": "6 users included"
          },
          {
            "item": "Team extra user",
            "unit": "seat-month",
            "usd": 15
          },
          {
            "item": "Growth plan",
            "unit": "month",
            "usd": 350,
            "note": "20 users included"
          },
          {
            "item": "Growth extra user",
            "unit": "seat-month",
            "usd": 17
          },
          {
            "item": "Business plan",
            "unit": "month",
            "usd": 950,
            "note": "50 users, 5 workspaces, audit logs"
          }
        ],
        "provenance": {
          "legalEntity": "gotoHuman UG (haftungsbeschränkt)",
          "domain": "gotohuman.com",
          "domainRegistered": "",
          "endpointOnVendorDomain": true,
          "terms": "https://docs.gotohuman.com/terms-of-service",
          "privacy": "https://www.gotohuman.com/privacy",
          "statusPage": "",
          "changelog": "",
          "securityTxt": "none",
          "checked": "2026-10-01",
          "notes": [
            "The terms (last updated 2026-02-13) name gotoHuman UG (haftungsbeschränkt), Lydia-Rabinowitsch-Str. 14, 10557 Berlin, Germany, under German law with Berlin as venue.",
            "https://www.gotohuman.com/.well-known/security.txt returned 404 on 2026-10-01.",
            "No status page or product changelog found. The n8n node publishes release notes on GitHub.",
            "We didn't check RDAP, so the domain age is blank."
          ],
          "score": 55
        },
        "pageJsonUrl": "https://www.anchorterminal.com/tools/gotohuman.json",
        "live": {
          "slug": "gotohuman",
          "probe": {
            "target": "https://api.gotohuman.com",
            "method": "get",
            "lastAt": "2026-10-05T00:57:21.084645641Z",
            "lastOk": true,
            "lastStatus": 404,
            "lastMs": 42,
            "authRequired": false,
            "uptime24h": 100,
            "uptime30d": 100,
            "p50ms24h": 50,
            "p95ms24h": 99,
            "samples24h": 272,
            "samples30d": 911,
            "days": [
              {
                "date": "2026-10-01",
                "probes": 109,
                "ok": 109
              },
              {
                "date": "2026-10-02",
                "probes": 248,
                "ok": 248
              },
              {
                "date": "2026-10-03",
                "probes": 271,
                "ok": 271
              },
              {
                "date": "2026-10-04",
                "probes": 272,
                "ok": 272
              },
              {
                "date": "2026-10-05",
                "probes": 11,
                "ok": 11
              }
            ]
          },
          "versions": [
            {
              "registry": "npm",
              "name": "@gotohuman/mcp-server",
              "version": "0.2.2",
              "seenAt": "2026-10-04T16:29:05.156119215Z"
            },
            {
              "registry": "npm",
              "name": "gotohuman",
              "version": "0.3.6",
              "seenAt": "2026-10-04T16:29:04.586460709Z"
            },
            {
              "registry": "pypi",
              "name": "gotohuman",
              "version": "0.2.4",
              "released": "2026-06-03",
              "seenAt": "2026-10-04T16:29:04.975506279Z"
            }
          ],
          "githubStars": 52,
          "npmWeekly": 74,
          "pypiWeekly": 5,
          "securityTxt": {
            "url": "https://gotohuman.com/.well-known/security.txt",
            "state": "none",
            "checkedAt": "2026-10-04T15:15:41.255049539Z"
          },
          "llmsTxt": {
            "url": "https://docs.gotohuman.com/llms.txt",
            "ok": true,
            "status": 200,
            "checkedAt": "2026-10-04T15:17:50.969227035Z"
          },
          "domain": {
            "domain": "gotohuman.com",
            "registered": "2024-03-28",
            "source": "https://rdap.verisign.com/com/v1/domain/gotohuman.com",
            "checkedAt": "2026-10-04T13:04:49.9181988Z"
          },
          "pages": [
            {
              "url": "https://www.gotohuman.com/pricing",
              "kind": "pricing",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:32.334095061Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "dc7f398aed05"
            },
            {
              "url": "https://www.gotohuman.com/privacy",
              "kind": "privacy",
              "status": 304,
              "checkedAt": "2026-10-04T15:50:34.372419331Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "e30807da51a1"
            },
            {
              "url": "https://docs.gotohuman.com/terms-of-service",
              "kind": "terms",
              "status": 200,
              "checkedAt": "2026-10-04T15:43:39.70487297Z",
              "changedAt": "0001-01-01T00:00:00Z",
              "fingerprint": "eb3d36ed071e"
            }
          ],
          "updatedAt": "2026-10-05T00:57:21.084645641Z"
        }
      }
    ]
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/categories/human-in-the-loop",
    "json": "https://www.anchorterminal.com/categories/human-in-the-loop.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/categories/human-in-the-loop.md",
    "slim": "https://www.anchorterminal.com/categories/human-in-the-loop.min.md"
  },
  "markdown": "Services that pause an agent to ask a person: approve an action, answer a question or take over a task, over Slack, email or a web inbox, then resume the agent with the answer. Compared on channels, routing, timeouts and audit.\n\n- Tools ranked: 7 · agent-ready (BB or better): 2 · accept x402: 0 · hosted endpoints: 6 · desk reviews by the panel: 26\n- JSON: https://www.anchorterminal.com/api/v1/tools.json (list) · https://www.anchorterminal.com/api/v1/rankings.json (ranked) · https://www.anchorterminal.com/api/v1/x402.json (payable) · https://www.anchorterminal.com/api/v1/capabilities.json (by capability)\n- Grades run AA, A, BB, B, C, D, E, F · methodology: https://www.anchorterminal.com/benchmark/\n\n- Capabilities in this category: hitl.approve, hitl.ask, hitl.handoff, hitl.channels, hitl.audit\n- https://letme.dev/hitl.approve picks the top-graded tool in this list and says how to call it direct; calling through letme comes later (https://www.anchorterminal.com/letme/index.md)\n\n## Ranking\n\n| # | Tool | Vendor | Kind | Category | Grade | Score | Confidence | x402 | Auth | Where | Reviews | Page |\n| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |\n| 21 | Temporal | Temporal Technologies | Model platform | Human approval | BB | 77.2 | medium | no | OAuth or key | local | 3.6/5 (8) | https://www.anchorterminal.com/tools/temporal.md |\n| 46 | Trigger.dev | Trigger.dev | Model platform | Human approval | BB | 74.8 | medium | no | OAuth or key | hosted + local | 3.6/5 (8) | https://www.anchorterminal.com/tools/trigger-dev.md |\n| 160 | Inngest | Inngest | Model platform | Human approval | B | 66.3 | medium | no | OAuth or key | hosted | 2.5/5 (2) | https://www.anchorterminal.com/tools/inngest.md |\n| 321 | Permit MCP Gateway | Permit.io | Model platform | Human approval | C | 54.5 | medium | no | OAuth | hosted | 2.5/5 (2) | https://www.anchorterminal.com/tools/permit-mcp-gateway.md |\n| 327 | Orkes Conductor Human tasks | Orkes | Model platform | Human approval | C | 54.2 | medium | no | API key | hosted + local | 2.5/5 (2) | https://www.anchorterminal.com/tools/orkes-conductor.md |\n| 350 | Pushary | Pushary | MCP server | Human approval | D | 51.4 | medium | no | API key | hosted | 2.5/5 (2) | https://www.anchorterminal.com/tools/pushary.md |\n| 407 | gotoHuman | gotoHuman | HTTP API | Human approval | E | 43.9 | medium | no | API key | hosted + local | 2/5 (2) | https://www.anchorterminal.com/tools/gotohuman.md |\n\nScores are from public evidence against the published checklist (https://www.anchorterminal.com/benchmark/), with Performance and Task success pending. p95 latency and context cost come from our probes, which haven't run yet.\n\n## Summaries\n\n### 21. Temporal, BB (77.2)\n\nOpen-source durable execution platform with SDKs in Go, Java, Python, TypeScript, .NET, PHP, Ruby and Rust, run yourself or on Temporal Cloud. Waits of any length with a timeout survive worker restarts and deploys. No reviewer inbox, notifications or routing, so the human side is all your code.\n\n- Page: https://www.anchorterminal.com/tools/temporal · Markdown: https://www.anchorterminal.com/tools/temporal.md · JSON: https://www.anchorterminal.com/api/v1/tools/temporal.json\n- Capabilities: hitl.approve, hitl.ask, hitl.audit, agent.durable, automation.workflows, automation.code\n\n### 46. Trigger.dev, BB (74.8)\n\nOpen-source background jobs and durable tasks in TypeScript. Tokens complete from a backend, a pre-signed callback URL or the browser with a token scoped to one waitpoint. 10-minute default timeout on tokens.\n\n- Page: https://www.anchorterminal.com/tools/trigger-dev · Markdown: https://www.anchorterminal.com/tools/trigger-dev.md · JSON: https://www.anchorterminal.com/api/v1/tools/trigger-dev.json\n- Capabilities: hitl.approve, hitl.ask, agent.durable, automation.workflows, automation.code · endpoint: `https://api.trigger.dev`\n\n### 160. Inngest, B (66.3)\n\nDurable execution platform for TypeScript, Python and Go, with event-driven workflows and support for human approval. Waits are durable and cost nothing while suspended, with runs up to 30 days on Free and 366 on Business. No reviewer inbox, Slack app or email, so the human side is your code.\n\n- Page: https://www.anchorterminal.com/tools/inngest · Markdown: https://www.anchorterminal.com/tools/inngest.md · JSON: https://www.anchorterminal.com/api/v1/tools/inngest.json\n- Capabilities: hitl.approve, hitl.ask, agent.durable, automation.workflows, automation.code · endpoint: `https://inn.gs/e/`\n\n### 321. Permit MCP Gateway, C (54.5)\n\nHosted proxy between MCP clients and MCP servers that signs in the human behind the agent, checks each tool call against Permit.io policy and logs it. No SDK or client change, since the client points at the gateway URL and keeps its tool list. Approvals are Enterprise only, through a demo, with no published price.\n\n- Page: https://www.anchorterminal.com/tools/permit-mcp-gateway · Markdown: https://www.anchorterminal.com/tools/permit-mcp-gateway.md · JSON: https://www.anchorterminal.com/api/v1/tools/permit-mcp-gateway.json\n- Capabilities: hitl.approve, hitl.channels, hitl.audit, auth.oauth, auth.consent, auth.agent-identity, auth.audit · endpoint: `https://{subdomain}.agent.security/mcp`\n\n### 327. Orkes Conductor Human tasks, C (54.2)\n\nWorkflow orchestration platform, built on the open-source Conductor, with a Human task that pauses a workflow, assigns a form to a user or group and resumes with the submitted answer. Escalation chains with a time limit per assignee and a choice of leaving the task open or failing the workflow. No built-in Slack or email prompt, so alerts need a trigger policy and a second workflow.\n\n- Page: https://www.anchorterminal.com/tools/orkes-conductor · Markdown: https://www.anchorterminal.com/tools/orkes-conductor.md · JSON: https://www.anchorterminal.com/api/v1/tools/orkes-conductor.json\n- Capabilities: hitl.approve, hitl.ask, hitl.handoff, hitl.audit, agent.durable, automation.workflows · endpoint: `https://developer.orkescloud.com/api`\n\n### 350. Pushary, D (51.4)\n\nHosted MCP server that lets a coding agent notify you and ask you a yes or no, multiple-choice or free-text question on your phone, Mac, Slack or browser, then wait for the answer. Six small tools with a detailed skill that says when to ask, when to notify and when to stay quiet. No free plan, and the 3-day trial takes a card up front.\n\n- Page: https://www.anchorterminal.com/tools/pushary · Markdown: https://www.anchorterminal.com/tools/pushary.md · JSON: https://www.anchorterminal.com/api/v1/tools/pushary.json\n- Capabilities: hitl.approve, hitl.ask, hitl.channels, hitl.audit, notify.push · endpoint: `https://pushary.com/api/mcp/mcp`\n\n### 407. gotoHuman, E (43.9)\n\nHosted review inbox for AI agents. Built for agent review, with TypeScript and Python SDKs, a 3-tool MCP server, an n8n node and a Make app. No status page, published rate limits or documented error responses.\n\n- Page: https://www.anchorterminal.com/tools/gotohuman · Markdown: https://www.anchorterminal.com/tools/gotohuman.md · JSON: https://www.anchorterminal.com/api/v1/tools/gotohuman.json\n- Capabilities: hitl.approve, hitl.ask, hitl.channels, hitl.audit · endpoint: `https://api.gotohuman.com`\n\n## How we test this category\n\nAn agent asks for approval of a risky action over two channels and gets one approval, one rejection and one timeout. We check the routing, what the approver sees, how the answer reaches the agent and what is logged. This test hasn't run yet, so Task success is pending and the grades here come from the categories assessed from public evidence.\n\n## Indexed, not reviewed (12)\n\nSorted into this category from public catalogues, with facts and our own checks but no score, grade or rank (https://www.anchorterminal.com/indexed/index.md).\n\n| Listing | Kind | What it does | Why it's here |\n| --- | --- | --- | --- |\n| [abs-mcp](https://www.anchorterminal.com/tools/ausdata-abs-mcp.md) | MCP server | Query the ABS in plain English — CPI, labour force, building approvals, migration, GDP. | vendor's own |\n| [Adako: ad ops for AI assistants](https://www.anchorterminal.com/tools/adako-ads.md) | MCP server | Google, Meta, LinkedIn and ChatGPT Ads for AI assistants. Every change needs your approval. | vendor's own |\n| [agentimus](https://www.anchorterminal.com/tools/heera-agentimus.md) | MCP server | heera.it via Agentimus: AI readiness, traffic, request log, search \u0026 index reports, by approval. | vendor's own |\n| [bvcc-agent-wallet](https://www.anchorterminal.com/tools/blockventurechaincapital-bvcc-agent-wallet.md) | MCP server | Non-custodial BVCC Agent Wallet on-chain for AI agents: balances, transfers, approvals, swaps. | vendor's own |\n| [Clize](https://www.anchorterminal.com/tools/clize.md) | MCP server | Real-world actions for AI coding agents: an inbox with approval outbox, deploys, domains, payments. | vendor's own |\n| [Elicitly](https://www.anchorterminal.com/tools/elicitly.md) | MCP server | Human-in-the-loop for AI agents over MCP elicitation: confirm/form dialogs plus a capability doctor | vendor's own |\n| [Lassare](https://www.anchorterminal.com/tools/lassare-ask.md) | MCP server | Human-in-the-loop for AI coding agents — ask questions, get approvals via Slack. | vendor's own |\n| [logi-approval](https://www.anchorterminal.com/tools/1pass-logi-approval.md) | MCP server | logi Agent Approval Gate — human approval on the phone before high-risk agent actions. | vendor's own |\n| [monnet.ai MCP server](https://www.anchorterminal.com/tools/monnet-mcp.md) | MCP server | MCP server for Monnet — motions, plans, files, approvals, and the team's company brain. | vendor's own |\n| [Proof Holdings](https://www.anchorterminal.com/tools/proof-mcp-server.md) | MCP server | One API, all things verified — control, delegation, human approval, anti-impersonation. | vendor's own |\n| [Selda](https://www.anchorterminal.com/tools/selda.md) | MCP server | Find customers, research each one and draft the outreach. Nothing sends without approval. | vendor's own |\n| [Social Champ](https://www.anchorterminal.com/tools/socialchamp-mcp.md) | MCP server | Connect AI agents to Social Champ: manage channels, posts, AI content, queue, and approvals. | vendor's own |\n\n",
  "meta": {
    "attribution": "Anchor Terminal (https://www.anchorterminal.com)",
    "docs": "https://www.anchorterminal.com/docs/",
    "generatedAt": "2026-10-05",
    "license": "CC-BY-4.0",
    "method": "https://www.anchorterminal.com/benchmark/",
    "methodology": "0.3",
    "openapi": "https://www.anchorterminal.com/openapi.json",
    "preview": false,
    "run": "2026-10-01",
    "runLabel": "October 2026 research run"
  },
  "page": {
    "breadcrumbs": [
      {
        "name": "Home",
        "url": "https://www.anchorterminal.com/"
      },
      {
        "name": "Terminal",
        "url": "https://www.anchorterminal.com/tools/"
      },
      {
        "name": "Human approval \u0026 handoff",
        "url": ""
      }
    ],
    "description": "7 human approval \u0026 handoff listings ranked by the Anchor benchmark. Leader Temporal (BB). Services that pause an agent to ask a person: approve an action, answer a question or take over a task, over Slack, email or a web inbox, then resume the agent with the answer. Compared on channels, routing, timeouts and audit.",
    "facts": [
      "Temporal BB",
      "Trigger.dev BB",
      "Inngest B"
    ],
    "h1": "Human approval and handoff for AI agents",
    "image": "https://www.anchorterminal.com/assets/og/categories-human-in-the-loop.png",
    "path": "/categories/human-in-the-loop",
    "published": "",
    "section": "tools",
    "title": "Human approval and handoff for AI agents, ranked | Anchor Terminal",
    "toc": null,
    "updated": "2026-10-05",
    "url": "https://www.anchorterminal.com/categories/human-in-the-loop"
  },
  "tokens": {
    "markdown": 2750,
    "slim": 430
  },
  "version": 1
}
