Endpoints: 28,729MCP servers: 18,413Payout addresses: 2,071Paid calls: 1,558Letters: 14Defects: 1,331counted just now
teppi

Server definition

Hash
sha256:6b3a1db84ceecb6bd5bd236b983209bd51b5e5bd26c1784585305eb995075ce2
What it is
What a remote MCP server returned when asked what it offers: 105 tools

The blob, as servednamed by its sha256

{ "instructions": "TaScan records work as signed receipts. If the user is new to TaScan or asks how it works, call tascan_quickstart first and show them the verify link it returns: that is a real receipt a named policy verified. Completed means someone said it was done; verified means a policy checked it and signed the result. Use tascan_find to locate projects, lists and tasks by name before creating new ones.", "tools": [ { "description": "Add one or more subtasks to a task (bulk). Subtasks support typed responses: \"number\" for per-set data (reps, weight, distance), \"text\" for notes, \"choice\" for options, \"checkbox\" for simple steps. Set-logging example: task \"Bench Press\" with subtasks Set 1/Set 2/Set 3 each response_type \"number\" — each completed set stores its value and timestamp, giving per-set timing for progression tracking.", "inputSchema": { "properties": { "subtasks": { "description": "Array of subtasks to create", "items": { "properties": { "description": { "description": "Optional detail", "type": "string" }, "requires_photo": { "description": "Require photo on completion", "type": "boolean" }, "response_config": { "description": "For \"choice\": {options: [...]}. For \"number\"/\"text\": {placeholder}.", "type": "object" }, "response_type": { "description": "Default checkbox. \"number\" for per-set values. \"choice\" needs response_config.options. \"link\" = the worker submits a URL. \"url\" = the worker visits a preset URL and confirms. \"file\" = the worker uploads a file.", "enum": [ "checkbox", "number", "text", "choice", "link", "url", "file" ], "type": "string" }, "sort_order": { "description": "Explicit position (defaults to end, in array order)", "type": "number" }, "title": { "description": "Subtask title (e.g. \"Set 1\")", "type": "string" } }, "required": [ "title" ], "type": "object" }, "type": "array" }, "task_id": { "description": "Parent task ID", "type": "string" } }, "required": [ "task_id", "subtasks" ], "type": "object" }, "name": "tascan_add_subtasks", "outputSchema": null }, { "description": "Add one or more tasks to an event (task list). Supports bulk creation. IMPORTANT: Set response_type correctly — use \"text\" for info collection (names, phones, emails, notes), \"photo\" for visual verification (inspections, serial numbers, damage checks), \"checkbox\" only for simple confirmations. NOTE: To dispatch tasks to an AI agent use tascan_dispatch_to_agent instead. Writing into an agent inbox list requires the agent:dispatch permission (agent:dispatch:code for CODE:/SHELL: titles) — without it the call is refused.", "inputSchema": { "properties": { "idempotency_key": { "description": "B1: optional replay key (up to 1024 chars, no braces) sent verbatim as the Idempotency-Key header instead of a fresh one per call — a retried call with the SAME key replays the original response instead of creating the tasks twice.", "type": "string" }, "list_id": { "description": "Task list (event) ID", "type": "string" }, "tasks": { "description": "Array of tasks to create", "items": { "properties": { "assigned_to": { "description": "Worker to assign this task to — pass the worker UUID (validated against your org and stored as the worker's name, which is how the worker portal matches \"my tasks\"). A plain name string is also accepted as-is.", "type": "string" }, "description": { "description": "Task description", "type": "string" }, "is_safety_checkpoint": { "description": "Safety-critical task flag", "type": "boolean" }, "required_equipment": { "description": "Equipment this task depends on (free text, e.g. \"88 lb kettlebells\")", "type": "string" }, "requires_photo": { "description": "Require photo on completion", "type": "boolean" }, "response_config": { "description": "Response configuration. For \"choice\": {options: [\"A\",\"B\",\"C\"]}. For \"text\": {placeholder, multiline}. For \"number\": {placeholder}. For \"date\": {label, include_text}.", "type": "object" }, "response_type": { "description": "CRITICAL: \"text\" for names, phones, emails, notes, addresses, any free-form input. \"photo\" for tasks needing photographic proof (inspections, serial numbers, packed cases). \"checkbox\" ONLY for simple yes/no confirmations. \"number\" for numeric values. \"date\" for dates. \"choice\" for multiple-choice (needs response_config.options). \"link\" = the worker SUBMITS a URL (auto-verified by an http probe). \"url\" = the worker VISITS a preset URL and confirms. \"file\" = the worker uploads a file. Most info-collection tasks should be \"text\", most verification tasks should be \"photo\".", "enum": [ "checkbox", "photo", "text", "number", "date", "choice", "link", "url", "file" ], "type": "string" }, "sort_order": { "description": "Explicit sort position (defaults to end of list, in array order)", "type": "number" }, "subtasks": { "description": "Subtasks created with the task. Example set logging: [{title:\"Set 1\",response_type:\"number\"},{title:\"Set 2\",response_type:\"number\"},{title:\"Set 3\",response_type:\"number\"}]", "items": { "properties": { "requires_photo": { "type": "boolean" }, "response_config": { "description": "Same shape as task response_config", "type": "object" }, "response_type": { "description": "Typed subtask response. \"number\" for per-set values (reps/weight), \"text\" for notes, \"choice\" needs response_config.options. \"link\" = the worker submits a URL. \"url\" = the worker visits a preset URL and confirms. \"file\" = the worker uploads a file. Default checkbox.", "enum": [ "checkbox", "number", "text", "choice", "link", "url", "file" ], "type": "string" }, "title": { "description": "Subtask title (e.g. \"Set 1\")", "type": "string" } }, "required": [ "title" ], "type": "object" }, "type": "array" }, "title": { "description": "Task title", "type": "string" } }, "required": [ "title" ], "type": "object" }, "type": "array" } }, "required": [ "list_id", "tasks" ], "type": "object" }, "name": "tascan_add_tasks", "outputSchema": null }, { "description": "Step 1 of the Closed-Loop Autonomous Operations Protocol. Retrieves full issue context including worker info, message thread, project history, and recent similar issues. Use this data to reason about the root cause and generate a remediation plan. Also supports server-side AI analysis via POST (calls Anthropic API directly).", "inputSchema": { "properties": { "issue_id": { "description": "Issue ID to analyze", "type": "string" }, "server_side_ai": { "description": "If true, the server calls Anthropic API directly for AI analysis (default: false — returns raw data for MCP client to analyze)", "type": "boolean" } }, "required": [ "issue_id" ], "type": "object" }, "name": "tascan_analyze_issue", "outputSchema": null }, { "description": "Apply a pre-built template to a task list, adding all template tasks", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID", "type": "string" }, "template_slug": { "description": "Template slug (e.g. \"conference-load-in\", \"warehouse-receiving\")", "type": "string" } }, "required": [ "list_id", "template_slug" ], "type": "object" }, "name": "tascan_apply_template", "outputSchema": null }, { "description": "Run an AI condition assessment of an asset from a photo. The model scores 0-100 with the asset's full assessment history in context, so it reads degradation over time — returning the Condition Delta Score vs the previous assessment, defects, wear indicators, maintenance recommendations, and a degradation trajectory. Sensor-free predictive maintenance.", "inputSchema": { "properties": { "asset_id": { "description": "Asset ID (from tascan_register_asset or tascan_list_assets)", "type": "string" }, "photo_url": { "description": "Public URL of the assessment photo", "type": "string" }, "worker_name": { "description": "Who took the photo (optional)", "type": "string" } }, "required": [ "asset_id", "photo_url" ], "type": "object" }, "name": "tascan_assess_condition", "outputSchema": null }, { "description": "FULL Closed-Loop Autonomous Operations Protocol in one call. Server-side AI analyzes the issue, generates remediation tasks, creates a task list, and dispatches to the worker — all without human intervention. This executes Patent Claim 7: autonomous operations from issue detection through physical-world instruction delivery.", "inputSchema": { "properties": { "issue_id": { "description": "Issue ID to auto-resolve", "type": "string" } }, "required": [ "issue_id" ], "type": "object" }, "name": "tascan_auto_resolve", "outputSchema": null }, { "description": "Cancel a scheduled text that has not been sent yet (status pending). A row already sending, sent, failed or cancelled is refused (409) — a sent text cannot be recalled.", "inputSchema": { "properties": { "id": { "description": "The scheduled_sms row id from tascan_schedule_sms / tascan_list_scheduled_sms", "type": "string" } }, "required": [ "id" ], "type": "object" }, "name": "tascan_cancel_scheduled_sms", "outputSchema": null }, { "description": "Claim a fan-out seat task as a LOCAL subagent run (POST /runs/claim -> claim_agent_run(p_runner='local')). Only admitted when instance starts with \"<your registered agent_id>:\" -- the seat's own coord.agent_id, set when the fan-out was created (tascan_create_fanout seats[i].runner='local'). Any other instance is refused, claimed false with reason seat_not_yours -- this tool never claims a seat that is not yours, and never claims a cloud (research) seat at all (refused not_routable). Never mints a completion or a receipt by itself -- claiming only opens the run; work happens after, and tascan_finish_run is what leaves the signed receipt. Requires agent:dispatch:code. A foreign or unknown task_id is 404, never 403 (S2: another org's task never even appears to exist).", "inputSchema": { "properties": { "instance": { "description": "Your claim identity, \"<agent_id>:<anything>\" -- e.g. \"researcher-07:host-1234\". Must start with the seat's own registered agent_id or the claim is refused seat_not_yours.", "type": "string" }, "task_id": { "description": "The seat task ID (UUID) -- from tascan_create_fanout's seats[] or tascan_get_fanout (view=status/report).", "type": "string" }, "ttl_seconds": { "description": "Optional lease length in seconds (60-86400, default 1800). Extend it later with tascan_heartbeat_run instead of claiming a longer one up front.", "type": "integer" } }, "required": [ "task_id", "instance" ], "type": "object" }, "name": "tascan_claim_run", "outputSchema": null }, { "description": "Complete a subtask, optionally recording a typed response_value (e.g. the weight or reps for that set). Each completion is timestamped, so consecutive set completions yield per-set durations. Returns progress including all_subtasks_complete — when true, complete the parent task with tascan_complete_task.", "inputSchema": { "properties": { "notes": { "description": "Optional notes", "type": "string" }, "response_value": { "description": "Typed response value (for number/text/choice subtasks), e.g. \"165\"", "type": "string" }, "subtask_id": { "description": "Subtask ID to complete", "type": "string" }, "worker_id": { "description": "Worker performing the completion (optional)", "type": "string" } }, "required": [ "subtask_id" ], "type": "object" }, "name": "tascan_complete_subtask", "outputSchema": null }, { "description": "Complete an ORDINARY task on behalf of a worker. Inserts a completion record and timer event. Use this to simulate or record task completions via the API. Coordination-cycle tasks (a CODE:/REVIEW: build or review, a Decision / Question / Integrate / Parked card on a project Decisions list — tasks that carry `coord`) are refused with 403 for every key tier: builds and reviews are completed by their runner, decisions only by the human on the worker page.", "inputSchema": { "properties": { "notes": { "description": "Optional completion notes", "type": "string" }, "response_value": { "description": "Response value (for text/number/choice tasks)", "type": "string" }, "task_id": { "description": "Task ID to complete", "type": "string" }, "worker_id": { "description": "Worker ID performing the completion", "type": "string" } }, "required": [ "task_id", "worker_id" ], "type": "object" }, "name": "tascan_complete_task", "outputSchema": null }, { "description": "Get an asset's longitudinal condition history — score trend over time, every assessment with grade, delta, findings, and who assessed it. The per-serial-number condition ledger.", "inputSchema": { "properties": { "asset_id": { "description": "Asset ID", "type": "string" } }, "required": [ "asset_id" ], "type": "object" }, "name": "tascan_condition_history", "outputSchema": null }, { "description": "Control a running fan-out (POST /coord/fanouts/:id/control). pause holds every unclaimed seat and stops the orphan pass from re-firing them; resume releases them again; cancel supersedes every unclaimed task and closes once quiescent; close_barrier drops unsettled or named exclude_seats and forces the synth barrier now instead of waiting for more seats; retry_synth (migration 232) mints a new synth revision from the current synth's own stored inputs, correctly ordered, when every one of its failed runs is input_ref_mismatch -- refused otherwise (not_synthesizing, no_synth_task, no_failed_runs, not_input_ref_mismatch). No amend and no answer in phase 1. Every action mints a signed control-child completion FIRST, as the org's own system worker (coord_fanout_control_receipt) — never coord_dispatcher_action, so a control action can never sign into another org's Chief of Staff identity. idempotency_key replays the prior outcome (replayed:true) and applies nothing twice; a replayed resume after a later pause leaves the fan-out paused. Refused fanout_closed once the roll-up has closed. Requires agent:dispatch:code.", "inputSchema": { "properties": { "action": { "description": "pause, resume, cancel, close_barrier or retry_synth. No amend, no answer (phase 1).", "enum": [ "pause", "resume", "cancel", "close_barrier", "retry_synth" ], "type": "string" }, "exclude_seats": { "description": "close_barrier only: 1-based seat numbers to drop from the barrier instead of waiting for them to settle.", "items": { "type": "integer" }, "type": "array" }, "fanout_id": { "description": "Fan-out id (UUID) — the T_F root.", "type": "string" }, "idempotency_key": { "description": "Optional replay key (<= 200 chars). The same key returns the prior outcome (replayed:true) and applies nothing a second time.", "type": "string" }, "reason": { "description": "Optional free-text reason (<= 4000 chars), recorded on the control child's completion.", "type": "string" } }, "required": [ "fanout_id", "action" ], "type": "object" }, "name": "tascan_control_fanout", "outputSchema": null }, { "description": "Start an unattended build-review-decide cycle (protocol v0.2). Queues T1 CODE: (or SHELL:) with your build_brief on the AI Inbox and T2 REVIEW: with your review_brief, born blocked on T1. T1 (2026-09-24 throughput): kind=review_only mints T1 as CAPTURE: instead — the executor stores the bundle from the repo at HEAD without a model call and the review runs on that; dry_run=true runs the dispatch PREFLIGHT only (nothing queued) and prints every problem at once (codes title_too_long, brief_rule, brief_names_unbundled_path, artifact_over_cap, migration_as_context (tascan repo only), idempotency_replay, kind_invalid — bad kind, bad revisable_by, review_only + task_type SHELL/RESEARCH, review_only + max_questions 0), then what the API could NOT check (unchecked[]: artifact_missing_at_head always — only the executor sees the repo, and a CAPTURE naming a missing path fails with \"[artifact_missing_at_head]\" in its error; artifact_over_cap for any path without a byte count — pass artifact_bytes; idempotency_replay only if its lookup failed) and warnings[] (a build_brief naming a context file outside the bundle); a real create that the API refuses prints the same problems[] list (when the transport hands the tool only the first problem's text, the tool re-runs the preflight and prints the whole list). The local executor builds, stores the exact bytes of artifact_paths as a bundle (build_ref = sha256 over the manifest), the independent reviewer reviews THAT bundle, an approve verdict mints a Decision task for the human authority (one SMS), Approve mints an Integrate task for the deploy id. Revise verdicts spawn revisions (cap max_revisions, default 3); reject, human Reject, scope violations or exhausted revisions PARK the cycle (a Parked task with Resume with notes / Close). REQUIRES agent:dispatch:code. Duplicate protection: the same idempotency_key, or (keyless) the same briefs + paths on a live root, within 24 h is refused by the preflight as idempotency_replay (400, nothing queued, the existing root_id in the problem) and printed as DUPLICATE with that root_id; only a replay the preflight could not see (a race) comes back from the RPC as 200 created=false, printed the same way. Optional `reviews[]` attaches a multi-lens review panel (design item 14a) in place of the single OpenAI review — one review task mints per lens and every blocking lens must approve before the Decision task mints. Track with tascan_get_cycle_report (root_id). Nothing spawns a cycle on its own.", "inputSchema": { "properties": { "artifact_bytes": { "additionalProperties": { "type": "integer" }, "description": "Optional {path: bytes} for artifact_paths — the byte length of each file in your checkout. The API cannot read the repo, so artifact_over_cap (262144-byte reviewable cap per file) is only checked for paths you give a byte count; every other path is reported under unchecked (artifact_over_cap, unchecked_at_api) — never guessed from an earlier stored bundle. Same on dry_run and the real create.", "type": "object" }, "artifact_paths": { "description": "Repo-relative paths the build binds (1-64). Exactly these files are stored as the bundle and hashed into build_ref; files the executor touches OUTSIDE them fail the scope check and park the cycle. No .., not absolute, no drive letter, no backslash.", "items": { "type": "string" }, "type": "array" }, "build_brief": { "description": "The executor prompt (1-40000 chars). Executed verbatim by the local Claude Code runner as a CODE:/SHELL: task — write it as a complete instruction, name the files, forbid nothing the runner already forbids (deploy/commit/push are refused by its context).", "type": "string" }, "checkpoint_description": { "description": "Optional description template for the Decision task; the build_ref, preview and findings summary are appended.", "type": "string" }, "checkpoint_title": { "description": "Optional title template for the Decision task (default \"Decision: <title>\").", "type": "string" }, "dry_run": { "description": "true = PREFLIGHT only: the API validates the whole dispatch and returns every problem at once (code, path, detail) plus the unchecked[] list (what only the executor / the RPC can decide) and warnings[] — nothing is queued, no idempotency key is consumed. Recommended before every real create. Default false.", "type": "boolean" }, "idempotency_key": { "description": "Optional caller key (≤ 200 chars). The same key within 24 h is refused as idempotency_replay (nothing queued) and printed as DUPLICATE with the existing root_id — safe to retry after a lost answer.", "type": "string" }, "integrate_description": { "description": "Optional description template for the Integrate task.", "type": "string" }, "integrate_title": { "description": "Optional title template for the Integrate task (default \"Integrate: <title>\").", "type": "string" }, "kind": { "description": "Cycle kind (default build). review_only = no model builds anything: T1 is \"CAPTURE: <title>\", a local-executor task that stores artifact_paths from the repo at HEAD as the bundle (same build_ref, size cap and scope check as a CODE build) and completes in seconds; T2 REVIEW then reviews that bundle. Use it to get an independent review of documents or of code already committed by hand. Stored as coord.kind_of_cycle on the root.", "enum": [ "build", "review_only" ], "type": "string" }, "max_cost_micro_usd": { "description": "Per-cycle spend cap summed over every attempt, in micro-USD (default 5000000 = USD 5). A claim that could overrun it is refused (budget_exhausted).", "type": "integer" }, "max_questions": { "description": "Questions a runner may ask per task before the attempt fails (default 3).", "type": "integer" }, "max_revisions": { "description": "Revision cap (default 3): at most max_revisions + 1 builds and reviews.", "type": "integer" }, "preview_url": { "description": "Optional https preview link shown on the Decision task.", "type": "string" }, "project_id": { "description": "Working project (UUID). Its Decisions and Agent Questions lists are created on the first cycle (coord_ensure_lists). Requires the org human authority to be configured (coord_set_authority) — otherwise 403.", "type": "string" }, "repo": { "description": "Which codebase on the executor the build runs in — an alias from the executor's allowlist (tascan-agent/repos.json), e.g. \"tascan\" (default), \"merchskipper\", \"inkskipper\", \"rangerlizzy\", \"cardvault\", \"take1\", \"fitcheck\", \"safegrid\", \"eternity\", \"maniacs\". artifact_paths are relative to that repo. An unknown alias is refused by the executor (repo_unknown) and the cycle parks.", "type": "string" }, "review_brief": { "description": "The reviewer prompt (1-40000 chars). The reviewer reads the stored bundle (tascan_get_build / tascan_get_build_file), the task text and the filtered trail; it returns approve, revise, reject or needs_input as strict JSON bound to the build_ref. Still required even when `reviews[]` is given (kept as T2's legacy description text).", "type": "string" }, "reviews": { "description": "Optional multi-lens review panel (design item 14a) instead of today's single OpenAI review_brief lens — 1-8 entries, each: {lens: slug matching ^[a-z][a-z0-9-]{0,39}$ unique per array (e.g. \"code-correctness\", \"security\", \"ui-ux\"), brief: 1-8000 chars of cycle-specific context for that lens, provider: \"openai\"|\"anthropic\"|\"gemini\", model?: 1-100 chars, blocking?: boolean (default true — at least one entry must be blocking or the whole array is refused), max_tool_calls?: integer (openai only)}. One REVIEW: task mints per lens, all blocked on T1; the Decision task mints only once every blocking lens has approved the same build. Omit for today's single OpenAI code review.", "items": { "properties": { "blocking": { "description": "Default true. At least one entry in the array must be blocking.", "type": "boolean" }, "brief": { "description": "Cycle-specific context for this lens (1-8000 chars).", "type": "string" }, "lens": { "description": "Slug, ^[a-z][a-z0-9-]{0,39}$, unique in the array.", "type": "string" }, "max_tool_calls": { "description": "Optional, provider openai only.", "type": "integer" }, "model": { "description": "Optional, 1-100 chars.", "type": "string" }, "provider": { "enum": [ "openai", "anthropic", "gemini" ], "type": "string" } }, "required": [ "lens", "brief", "provider" ], "type": "object" }, "type": "array" }, "revisable_by": { "description": "review_only cycles only — who fixes a revise verdict. dispatcher (default): the cycle parks on revise as today and you re-dispatch. executor: a revise spawns a revision CAPTURE task (up to max_revisions) that is born blocked on a question task \"Revise the documents, then answer to release\" addressed to you — fix the files in the repo, answer that question (tascan_post_message kind=answer), and the capture re-runs on the fixed HEAD. Build cycles always revise through the executor regardless of this field.", "enum": [ "dispatcher", "executor" ], "type": "string" }, "task_type": { "description": "T1 prefix (default CODE). CAPTURE is never caller-settable: kind=review_only makes T1 \"CAPTURE:\" itself. With kind=review_only the value is sent as given — CODE is accepted (T1 is still CAPTURE), SHELL / RESEARCH are refused by the API as kind_invalid.", "enum": [ "CODE", "SHELL", "RESEARCH" ], "type": "string" }, "title": { "description": "Short human title (1-200 chars). T1 becomes \"CODE: <title>\" (\"CAPTURE: <title>\" when kind=review_only), T2 \"REVIEW: <title>\".", "type": "string" } }, "required": [ "project_id", "title", "build_brief", "review_brief", "artifact_paths" ], "type": "object" }, "name": "tascan_create_cycle", "outputSchema": null }, { "description": "Create a new event (task list) within a project. Supports team_mode (shared completions) and multi_instance (each worker gets isolated copy — great for surveys, onboarding, info collection). team_mode and multi_instance cannot both be true.", "inputSchema": { "properties": { "assigned_worker_ids": { "description": "Worker UUIDs to assign to this event. Each gets a personal tap-to-open link. Note: a worker holds one event assignment per project — assigning moves them.", "items": { "type": "string" }, "type": "array" }, "description": { "description": "Event description", "type": "string" }, "multi_instance": { "description": "Multi-instance — each worker gets isolated copy", "type": "boolean" }, "name": { "description": "Event name", "type": "string" }, "project_id": { "description": "Project ID", "type": "string" }, "team_mode": { "description": "Team mode — shared completions", "type": "boolean" } }, "required": [ "project_id", "name" ], "type": "object" }, "name": "tascan_create_event", "outputSchema": null }, { "description": "Create a fan-out: 1-30 seats (RESEARCH by default, or LOCAL subagent seats) plus one synthesizer under ONE cycle root T_F (POST /coord/fanouts). Zero Decision cards, zero Parked cards, zero pages per seat -- only a control action or the closing roll-up reaches a human. Requires an API key with agent:dispatch:code -- an admin session has no dispatch budget (key_required). dry_run true runs the same validation plus the ceiling/cap pre-check and returns {dry_run:true, plan_sha256, seats, problems:[]} WITHOUT consuming budget or creating anything -- a real preflight, not a real create. Otherwise consumes seats.length + 1 dispatch units BEFORE the authoritative create; a refusal only the RPC can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Fails closed fanout_ceiling_unset until the owner sets a ceiling; over_ceiling when cap exceeds it. idempotency_key replays duplicate within 24h on the same plan, else idempotency_body_mismatch. Leaves fanout_created; every seat, the synth and the roll-up leave their own signed completion. Track with tascan_get_fanout.", "inputSchema": { "properties": { "breaker_k": { "description": "Paid (non-infrastructure) seat failures before the breaker pauses the fan-out (2-5, default 2). An expired run never counts.", "type": "integer" }, "canary": { "description": "How many seats release immediately; the rest stay held on T_F until the first canary settles done. Default min(2, seats.length).", "type": "integer" }, "cap": { "description": "This fan-out's total micro-USD budget, synth reserve included. Refused over_ceiling if it exceeds the org's fan-out spending ceiling.", "type": "integer" }, "deadline_min": { "description": "Minutes before an idle seat is dropped and the barrier re-evaluated, and before a stuck synthesizing fan-out closes deadline (10-1440, default 240).", "type": "integer" }, "dry_run": { "description": "true runs the same validation plus the ceiling/cap pre-check and returns {dry_run:true, plan_sha256, seats, problems:[]} WITHOUT consuming budget or creating a fan-out -- a real preflight, not a real create.", "type": "boolean" }, "idempotency_key": { "description": "Optional replay key (<= 200 chars). The same key within 24h on the same plan returns duplicate:true with the existing fanout_id; on a different plan it is refused idempotency_body_mismatch.", "type": "string" }, "min_ok": { "description": "Minimum seats that must finish done before the synth barrier can close. Default ceil(seats.length / 2).", "type": "integer" }, "project_id": { "description": "Working project (UUID). The fan-out root T_F is minted on its Questions list (coord_ensure_lists).", "type": "string" }, "seat_defaults": { "description": "Shared defaults applied when a seat names no brief of its own.", "properties": { "brief": { "description": "Default seat prompt (1-40000 chars), used by any seat that names no brief of its own.", "type": "string" }, "est_micro_usd": { "description": "Positive integer micro-USD estimate per seat, used by the RPC's cap_below_plan check.", "type": "integer" }, "review_est_micro_usd": { "description": "Non-negative integer micro-USD estimate per seat review. Must be > 0 when seat_review is per_seat.", "type": "integer" } }, "required": [ "est_micro_usd" ], "type": "object" }, "seat_review": { "description": "per_seat mints one review per seat (allowed for at most 10 seats); none skips seat review. Default per_seat for <=10 seats, none above that.", "enum": [ "per_seat", "none" ], "type": "string" }, "seats": { "description": "1-30 seats. Each names the agent that runs it; brief/role fall back to seat_defaults when omitted.", "items": { "properties": { "agent_id": { "description": "A registered agent_registry id in this org, matching ^[a-z][a-z0-9-]{0,39}$. Never a system-* worker.", "type": "string" }, "brief": { "description": "This seat's own prompt (1-40000 chars). Falls back to seat_defaults.brief when omitted -- one of the two is required.", "type": "string" }, "role": { "description": "Optional label for this seat (1-100 chars), e.g. \"topic A\".", "type": "string" }, "runner": { "description": "Default \"research\" (the cloud runner claims it). \"local\" names a registered local/subagent agent_id -- only that agent, claiming as itself (tascan_claim_run instance starting with \"<agent_id>:\"), can claim the seat; it is never webhook-fired.", "enum": [ "research", "local" ], "type": "string" } }, "required": [ "agent_id" ], "type": "object" }, "type": "array" }, "synth": { "description": "The synthesizer that runs once the barrier closes, reading every done seat's stored output as DATA.", "properties": { "brief": { "description": "The synthesizer's prompt (1-40000 chars).", "type": "string" }, "max_cost_micro_usd": { "description": "Positive integer micro-USD reserved for the synth run; reserved out of cap up front, released back into the seat budget only at barrier close.", "type": "integer" } }, "required": [ "brief", "max_cost_micro_usd" ], "type": "object" }, "title": { "description": "Short human title (1-200 chars). T_F becomes \"FANOUT: <title>\"; seats become \"RESEARCH: [seat-NN] <title>\"; the synth becomes \"RESEARCH: [synth] <title>\".", "type": "string" } }, "required": [ "project_id", "title", "seats", "synth", "cap" ], "type": "object" }, "name": "tascan_create_fanout", "outputSchema": null }, { "description": "Create a client invoice and get its shareable link. Two ways to bill: (a) pass explicit line_items, or (b) pass project_id or task_list_ids plus hourly_rate (quarter-hour billing from first→last verified completion per list) or flat_rate_per_list, and TaScan builds one line per list from VERIFIED work (\"<list> — 7/7 tasks verified · Sep 1 · 1.25h\"); lists with no completions are skipped. A single-list invoice also mints a client-facing Service Report (acknowledge → pay) and links it. Returns invoice number, totals, url, and the work it billed.", "inputSchema": { "properties": { "attach_service_report": { "description": "Mint + link a Service Report for single-list invoices (default true)", "type": "boolean" }, "billing": { "description": "Billing rules for auto line items. mode: hourly (default when hourly_rate given) | day_rate | flat. Overtime/double time are computed PER WORK DAY from verified completions: hours over overtime_after_hours (default 8) bill at overtime_multiplier (1.5×), hours over double_time_after_hours (12) at double_time_multiplier (2×); set overtime:false to disable. per_diem adds one line × work days (or per_diem_days). expenses are pass-through lines.", "properties": { "day_rate": { "type": "number" }, "double_time_after_hours": { "type": "number" }, "double_time_multiplier": { "type": "number" }, "expenses": { "items": { "properties": { "amount": { "type": "number" }, "description": { "type": "string" }, "quantity": { "type": "number" } }, "required": [ "description", "amount" ], "type": "object" }, "type": "array" }, "flat_rate_per_list": { "type": "number" }, "hourly_rate": { "type": "number" }, "min_hours": { "type": "number" }, "mode": { "enum": [ "hourly", "day_rate", "flat" ], "type": "string" }, "overtime": { "type": "boolean" }, "overtime_after_hours": { "type": "number" }, "overtime_multiplier": { "type": "number" }, "per_diem": { "description": "Dollars per work day", "type": "number" }, "per_diem_days": { "type": "number" } }, "type": "object" }, "client_email": { "type": "string" }, "client_name": { "description": "Bill-to name (person or company)", "type": "string" }, "client_phone": { "type": "string" }, "company_name": { "description": "Your company name on the attached Service Report (defaults to the org name)", "type": "string" }, "due_date": { "description": "YYYY-MM-DD (default: 30 days out)", "type": "string" }, "flat_rate_per_list": { "description": "Dollars per list for auto line items (used when no hourly_rate)", "type": "number" }, "hourly_rate": { "description": "Dollars per hour for auto line items", "type": "number" }, "line_items": { "description": "Explicit lines instead of auto-billing", "items": { "properties": { "description": { "type": "string" }, "quantity": { "type": "number" }, "unit_price": { "type": "number" } }, "required": [ "description", "unit_price" ], "type": "object" }, "type": "array" }, "min_hours": { "description": "Minimum billable hours per list (e.g. 1)", "type": "number" }, "notes": { "description": "Payment terms / thank-you shown on the invoice", "type": "string" }, "payment_options": { "description": "Pay-how-you-like buttons on the invoice (defaults to the org's saved handles). Keys: venmo (@handle), cashapp ($cashtag), paypal (paypal.me name), zelle (phone/email), applecash (phone), other (free text e.g. \"cash or check\"). Stripe card checkout is separate and only shows when the org has invoice_payments enabled.", "properties": { "applecash": { "type": "string" }, "cashapp": { "type": "string" }, "other": { "type": "string" }, "paypal": { "type": "string" }, "venmo": { "type": "string" }, "zelle": { "type": "string" } }, "type": "object" }, "project_id": { "description": "Bill every list in this project (auto line items)", "type": "string" }, "status": { "description": "Default sent", "enum": [ "draft", "sent" ], "type": "string" }, "task_list_ids": { "description": "Bill just these lists (auto line items)", "items": { "type": "string" }, "type": "array" }, "tax_rate": { "description": "Fraction, e.g. 0.0825 for 8.25%", "type": "number" } }, "required": [ "client_name" ], "type": "object" }, "name": "tascan_create_invoice", "outputSchema": null }, { "description": "Create a new TaScan project (top-level container for events)", "inputSchema": { "properties": { "location": { "description": "Project location / venue", "type": "string" }, "name": { "description": "Project name", "type": "string" } }, "required": [ "name" ], "type": "object" }, "name": "tascan_create_project", "outputSchema": null }, { "description": "Create a new worker (taskee) in the organization", "inputSchema": { "properties": { "email": { "description": "Email", "type": "string" }, "name": { "description": "Worker name", "type": "string" }, "phone": { "description": "Phone number", "type": "string" } }, "required": [ "name" ], "type": "object" }, "name": "tascan_create_worker", "outputSchema": null }, { "description": "Create a geofenced work zone. Delivery zones route workers who open the project Site Gate (geo.html?project=...) to this zone's task list when GPS places them inside the radius. Set enforce_on_list=true to zone-lock the task list — workers cannot start it from outside the zone.", "inputSchema": { "properties": { "alert_on_breach": { "description": "Email + SMS the admin on containment-exit / restricted-enter (default true)", "type": "boolean" }, "auto_clock_in": { "description": "Writes a shift_start when the WORKER PAGE, while open, sees the phone enter the zone; detection is pull-based, there is no background geofencing. For a background-free presence event use a gate NFC/QR scan.", "type": "boolean" }, "auto_clock_out": { "description": "Writes a shift_end when the WORKER PAGE, while open, sees the phone leave the zone; detection is pull-based, there is no background geofencing. For a background-free presence event use a gate NFC/QR scan.", "type": "boolean" }, "description": { "description": "Shown to workers on the Site Gate page", "type": "string" }, "enforce_on_list": { "description": "Zone-lock the task list — it cannot be started from outside the radius", "type": "boolean" }, "enter_message": { "description": "What the worker sees / is texted on entry (default is generated from the rule)", "type": "string" }, "kind": { "description": "What the fence MEANS. work_site: expected here (auto clock-in, list on enter). hazard: enter allowed under conditions — required_ppe + photo checkpoint verified by AI vision, the OSHA row. containment: must stay inside; leaving = breach. restricted: must stay out; entering = breach. Default work_site.", "enum": [ "work_site", "hazard", "containment", "restricted" ], "type": "string" }, "lat": { "description": "Zone center latitude", "type": "number" }, "lng": { "description": "Zone center longitude", "type": "number" }, "name": { "description": "Zone name (e.g. \"Stage Left\", \"Loading Dock\")", "type": "string" }, "notify_email": { "description": "Alert recipient override — defaults to all org admins", "type": "string" }, "notify_on_enter": { "description": "Email the manager when a worker enters this zone (danger areas)", "type": "boolean" }, "notify_on_exit": { "description": "Email the manager when a worker leaves this zone (accountability — sign in then disappear)", "type": "boolean" }, "polygon": { "description": "Polygon/rectangle zone instead of a circle: vertices as [[lat,lng], ...], at least 3. lat/lng/radius_m are then computed (centroid + bounding radius) — still pass lat/lng but they are overridden.", "items": { "items": { "type": "number" }, "type": "array" }, "type": "array" }, "ppe_photo_required": { "description": "Hazard zones: pop a photo checkpoint on entry (default true when required_ppe is set)", "type": "boolean" }, "project_id": { "description": "Project this zone belongs to", "type": "string" }, "radius_m": { "description": "Radius in meters (default 150, min 10, max 100000)", "type": "number" }, "required_ppe": { "description": "Hazard zones: PPE the worker must show at entry (pick-list so the audit reads the same words)", "items": { "enum": [ "hard_hat", "safety_glasses", "hi_vis_vest", "gloves", "steel_toe_boots", "hearing_protection", "harness", "respirator", "face_shield" ], "type": "string" }, "type": "array" }, "sms_worker_on_enter": { "description": "Text the worker the rule/list on entry, even if the app is closed", "type": "boolean" }, "sms_worker_on_exit": { "description": "Text the worker on exit", "type": "boolean" }, "task_list_id": { "description": "Task list the Site Gate routes workers to when they are inside this zone", "type": "string" }, "task_list_on_enter": { "description": "Task list dispatched to the worker (in-app + SMS) when they cross into the zone", "type": "string" } }, "required": [ "name", "lat", "lng" ], "type": "object" }, "name": "tascan_create_zone", "outputSchema": null }, { "description": "Mint a time-limited, NARROWER child API key (POST /delegations, roadmap #11) — only read/write scopes may be requested; full, agent:dispatch, agent:dispatch:code, device:admin, delegate and webhooks:manage are always refused by name (I-6). TTL defaults to 1 hour (3600s), clamps to [60 seconds, 24 hours], and clamps further to THIS key's own expiry if it has one — a delegated key can never outlive its grantor. The child's tier is always a SUBSET of this key's own effective tier, never wider or lateral. Requires the delegate permission (owner-only to grant, requires full). The returned raw key is shown to you exactly ONCE — it is never stored server-side and cannot be retrieved again (I-10). Revoking this key (or any ancestor) cascades immediately to every key it delegated.", "inputSchema": { "properties": { "resource_constraints": { "description": "Optional free-form narrowing (e.g. project/list ids) recorded on the child key as metadata.", "type": "object" }, "scopes": { "description": "Scopes to request for the child key — read and/or write only.", "items": { "enum": [ "read", "write" ], "type": "string" }, "type": "array" }, "ttl_seconds": { "description": "How long the child key lives, in seconds (default 3600 = 1h; clamped to [60, 86400] and to this key's own expiry).", "type": "number" } }, "required": [ "scopes" ], "type": "object" }, "name": "tascan_delegate_to_agent", "outputSchema": null }, { "description": "Delete an event (task list) and all its tasks and completions. This action is irreversible.", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID to delete", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_delete_event", "outputSchema": null }, { "description": "Delete a project and all its events, tasks, and completions. This action is irreversible.", "inputSchema": { "properties": { "project_id": { "description": "Project ID to delete", "type": "string" } }, "required": [ "project_id" ], "type": "object" }, "name": "tascan_delete_project", "outputSchema": null }, { "description": "Delete a subtask and its completions. This action is irreversible.", "inputSchema": { "properties": { "subtask_id": { "description": "Subtask ID to delete", "type": "string" } }, "required": [ "subtask_id" ], "type": "object" }, "name": "tascan_delete_subtask", "outputSchema": null }, { "description": "Delete a specific task and its completions. This action is irreversible.", "inputSchema": { "properties": { "task_id": { "description": "Task ID to delete", "type": "string" } }, "required": [ "task_id" ], "type": "object" }, "name": "tascan_delete_task", "outputSchema": null }, { "description": "Tombstone a worker record (is_active=false). REFUSES if the worker has any task/subtask completions or payments — merge those into the real worker with tascan_merge_workers instead. Never hard-deletes.", "inputSchema": { "properties": { "worker_id": { "description": "Worker ID to delete", "type": "string" } }, "required": [ "worker_id" ], "type": "object" }, "name": "tascan_delete_worker", "outputSchema": null }, { "description": "Step 3 of the Closed-Loop Autonomous Operations Protocol. Dispatches remediation to the worker via MULTI-CHANNEL delivery: (1) issue thread message, (2) in-app notification, (3) progress feed update, (4) SMS if phone on file, (5) optional remediation task list creation. Closes the loop from digital AI analysis to physical worker execution.", "inputSchema": { "properties": { "ai_agent": { "description": "Name of the AI agent dispatching (default: TaScan AI)", "type": "string" }, "instruction": { "description": "Clear, actionable instruction for the worker to execute", "type": "string" }, "issue_id": { "description": "Issue ID this instruction relates to", "type": "string" }, "recommendation_summary": { "description": "One-line summary for the task list description", "type": "string" }, "remediation_tasks": { "description": "Optional array of tasks to create as a remediation task list. Each: { title, description, response_type, requires_photo, is_safety_checkpoint, sort_order }", "items": { "type": "object" }, "type": "array" }, "send_sms": { "description": "Send SMS to worker (default: true if phone on file)", "type": "boolean" }, "worker_id": { "description": "Target worker ID (defaults to the worker who reported the issue)", "type": "string" } }, "required": [ "issue_id", "instruction" ], "type": "object" }, "name": "tascan_dispatch_instruction", "outputSchema": null }, { "description": "PREFERRED tool for sending work to an AI agent. Dispatches a task to the agent's inbox — picked up and executed automatically. No list ID needed. REQUIRES the agent:dispatch permission on this connection (CODE:/SHELL: tasks also require agent:dispatch:code) — reconnect and tick the agent checkbox(es) if refused. Routing is by TITLE PREFIX only: CODE: SHELL: PLAN: MCP: → local Claude Code on Mike's PC; RESEARCH: WRITE: REVIEW: → cloud; no prefix (DEFAULT) → local while the PC agent is alive, else cloud. The cloud agent refuses CODE/SHELL/PLAN/MCP. Use \"agent\" param to target a specific agent (default: claude-code-local). Use tascan_list_agents to discover available agents; track progress with tascan_get_task (its \"agent\" block).", "inputSchema": { "properties": { "agent": { "description": "Agent ID or name to dispatch to (default: claude-code-local). Use tascan_list_agents to see options. An unknown agent is an error, never a silent fallback.", "type": "string" }, "priority": { "description": "Priority level (default: normal). The urgent marker is placed AFTER the routing prefix so it never breaks routing.", "enum": [ "normal", "urgent" ], "type": "string" }, "task": { "description": "The full task text. START it with CODE: SHELL: PLAN: MCP: RESEARCH: WRITE: or REVIEW: for routing (prefix-only — nothing may precede it), or leave it unprefixed (DEFAULT). The whole text is stored in the task description; the first 140 chars become the title.", "type": "string" } }, "required": [ "task" ], "type": "object" }, "name": "tascan_dispatch_to_agent", "outputSchema": null }, { "description": "Record a chief-of-staff dispatcher action on a coordination cycle as a receipt (protocol v0.2 D6, POST /coord/cycles/:root/dispatcher-actions): hand_review_approve, hand_review_revise, park, bundle_recovery, migration_apply, deploy or decision. Mints a completed task + completion under the Chief of Staff worker and a dispatcher_action ledger event on the root. kind=deploy additionally requires evidence.deploy_id (a Netlify deploy id) and composes the same integrate-as-note every root gets with coord_record_integration when the root is authorized — one call that does both records. Requires agent:dispatch.", "inputSchema": { "properties": { "evidence": { "description": "Optional evidence object (serializes to at most 8000 chars). For kind=deploy this must include deploy_id: 24 lowercase hex, optionally prefixed deployed: and/or followed by a build-ref hex prefix.", "type": "object" }, "kind": { "description": "Which dispatcher action this is.", "enum": [ "hand_review_approve", "hand_review_revise", "park", "bundle_recovery", "migration_apply", "deploy", "decision" ], "type": "string" }, "root_id": { "description": "The cycle root task id (tascan_list_cycles / tascan_create_cycle).", "type": "string" }, "summary": { "description": "Human-readable summary (1-4000 chars) — becomes the recorded completion notes.", "type": "string" } }, "required": [ "root_id", "kind", "summary" ], "type": "object" }, "name": "tascan_dispatcher_action", "outputSchema": null }, { "description": "Read or author a task's evidence policy (protocol v0.2 V9b, GET|PUT /evidence/policy/:task_id — one route, two methods, so one tool). action=get evaluates the pinned policy against the evidence ledger so far: whether it is usable and satisfied, and its progress (read tier). action=set authors/updates a policy in your org's namespace when definition is given (definition.require is a non-empty array of requirement objects; definition.min_count, when set, must be an integer from 1 through definition.require.length) or, when definition is omitted, pins the task to an existing active policy_id (write tier).", "inputSchema": { "properties": { "action": { "description": "get = GET (evaluate, read tier). set = PUT (author/pin, write tier).", "enum": [ "get", "set" ], "type": "string" }, "definition": { "description": "action=set only, optional: policy definition to create or update — require (array, required), min_count, window, any_of, allow_fallback. Omit to pin the task to the existing active policy_id instead.", "type": "object" }, "policy_id": { "description": "action=set only, required: lowercase letters/digits/underscore/dot, starting with a letter, up to 80 chars, e.g. loto_v1.", "type": "string" }, "task_id": { "description": "Task ID (UUID) in your organization.", "type": "string" }, "version": { "description": "action=set only: optional version for a new/updated policy definition (default 1). Ignored when only pinning an existing policy.", "type": "integer" } }, "required": [ "action", "task_id" ], "type": "object" }, "name": "tascan_evidence_policy", "outputSchema": null }, { "description": "Cross-entity search: find projects, task lists, tasks, workers, or condition assets by name in one call — with ids and parent context to disambiguate. Use this instead of walking projects→lists→tasks or guessing ids from display names.", "inputSchema": { "properties": { "query": { "description": "Search text (min 2 chars, case-insensitive substring)", "type": "string" }, "type": { "description": "Optional: restrict to one entity type", "enum": [ "project", "list", "task", "worker", "asset" ], "type": "string" } }, "required": [ "query" ], "type": "object" }, "name": "tascan_find", "outputSchema": null }, { "description": "Find candidate same-person worker records with per-signal match detail (Patent 4 §6.25(b) signals: phone reuse, name similarity, GPS pattern correlation). Turns identity fragmentation from an accidental discovery into a monitorable metric, and feeds the merge workflow its candidate list.", "inputSchema": { "properties": { "include_orphans": { "description": "Also consider org-less (orphan) worker records — off by default", "type": "boolean" }, "name": { "description": "Or: search duplicates by display name", "type": "string" }, "threshold": { "description": "Min confidence 0-1 (default 0.15)", "type": "number" }, "worker_id": { "description": "Anchor worker to find duplicates OF (preferred — enables phone + GPS signals)", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_find_duplicate_workers", "outputSchema": null }, { "description": "Finish a claimed local run (POST /runs/:run_id/finish). outcome='completed' stores `document` (and optional `verification`) as the seat's own build artifacts under EXACTLY the artifact_paths the fan-out named for this seat, hashes them into build_ref, and finishes the run -- this mints a real task_completions row and a SIGNED TASCAN RECEIPT for your work (tascan_get_receipt), the same as any other build; `document` is your deliverable and IS what gets hashed, so send the real content, not a summary. Zero changes to coord_fanout_settle / the barrier / the roll-up -- your completion releases the next held seat and, once every seat settles, feeds the fan-out's own synthesizer and rollup exactly like a cloud research seat's would. outcome='failed' finishes the run failed with your `error` text and stores nothing. Requires agent:dispatch:code. A run outside your org, or already finished, is refused (404 / the RPC's own not_live).", "inputSchema": { "properties": { "cost_micro_usd": { "description": "Optional micro-USD cost to record against the cycle's own budget (default 0 -- a Claude Code subscription seat has no per-call API cost to report).", "type": "integer" }, "document": { "description": "Required when outcome is completed. The seat's deliverable -- hashed as build_ref, stored verbatim under the seat's own artifact_paths.", "type": "string" }, "error": { "description": "Required when outcome is failed -- why (up to 4000 chars).", "type": "string" }, "instance": { "description": "The SAME instance string you claimed with.", "type": "string" }, "outcome": { "description": "'completed' stores your document and mints a signed completion; 'failed' stores nothing.", "enum": [ "completed", "failed" ], "type": "string" }, "run_id": { "description": "The run ID from tascan_claim_run's response.", "type": "string" }, "verification": { "description": "Optional second document (a short verification/self-check note) -- stored as the seat's second artifact_path when the fan-out named two.", "type": "string" } }, "required": [ "run_id", "instance", "outcome" ], "type": "object" }, "name": "tascan_finish_run", "outputSchema": null }, { "description": "Generate a QR code for a task list (event) that workers can scan to access tasks", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_generate_qr", "outputSchema": null }, { "description": "Mint a shareable report and get its link. Types: completion (full proof-of-work for one list: tasks, responses, subtasks, photos, GPS + place names, timing, QR pair), service (client-facing version of a list with YOUR company branding and a Client Acknowledgment button — the ack files into the list thread), project (every list in a project rolled up), evidence (compliance Evidence Pack; admin sign-in required to view). Links are stable — the same list/project returns the same link. Optionally text the link to a phone through the TaScan SMS lane.", "inputSchema": { "properties": { "company_name": { "description": "Service report branding (defaults to the org name)", "type": "string" }, "list_id": { "description": "Required for completion / service", "type": "string" }, "message": { "description": "Service report: a note to the client shown under the header", "type": "string" }, "project_id": { "description": "Required for project / evidence", "type": "string" }, "send_note": { "description": "Short intro for the text, e.g. \"Here is your report from Love Productions:\"", "type": "string" }, "send_to_phone": { "description": "Text the link to this number (E.164 or 10-digit US)", "type": "string" }, "show_issues": { "description": "Service report: include reported issues (default false)", "type": "boolean" }, "show_workers": { "description": "Service report: show worker names (default true)", "type": "boolean" }, "type": { "enum": [ "completion", "service", "project", "evidence" ], "type": "string" } }, "required": [ "type" ], "type": "object" }, "name": "tascan_generate_report", "outputSchema": null }, { "description": "Read THIS credential's own per-key action budget (GET /budget): daily limits (sms, invites, payment-request cents per day and per request, dispatch, human pages) and today's spend against them. A NULL limit (or no budget row at all) means unlimited on that counter. A key can only ever see its OWN budget, never another key's (I-3, no tool or key ever reads another key's row). Read tier.", "inputSchema": { "properties": {}, "type": "object" }, "name": "tascan_get_budget", "outputSchema": null }, { "description": "Manifest of a stored build bundle by build_ref (protocol v0.2 build_artifacts): the exact files the executor produced for the cycle's artifact_paths, each with sha256, byte length and whether text content is stored (binary or over-cap files keep the sha only). build_ref = sha256 over the manifest, computed in the database once; the reviewer reviews THESE bytes, the human approves THIS ref, the integrate task records THIS ref. Read tier. Use tascan_get_build_file to read a file. Truncated at 12000 chars. Reading the manifest is discovery, not a read of any file.", "inputSchema": { "properties": { "build_ref": { "description": "sha256:<64 hex> (or the bare 64 hex) — from tascan_get_task (coord.build_ref / agent.runs[].build_ref) or tascan_get_cycle_report.", "type": "string" } }, "required": [ "build_ref" ], "type": "object" }, "name": "tascan_get_build", "outputSchema": null }, { "description": "Store an already-computed diff for one file of a build bundle against a base commit (protocol v0.2 item 6, POST /coord/builds/:build_ref/diff — the parser has no GET for this path; a deployed function ships no git object database, so tascan-agent/deployer.js computes the diff text with its own persistent worktree and this route only validates + stores it via coord_set_artifact_diff). build_sha256 must equal the artifact's own stored sha256 or the call is refused; storing a diff replaces that file's stored full content with the diff going forward. There is currently no REST route that reads a stored diff back (GET /builds/:build_ref and /builds/:build_ref/file do not surface it) — this tool only writes one. Requires agent:dispatch.", "inputSchema": { "properties": { "base_ref": { "description": "The commit-ish the diff was computed against (1-200 chars).", "type": "string" }, "base_sha256": { "description": "Optional 64-hex sha256 of the file at base_ref.", "type": "string" }, "build_ref": { "description": "sha256:<64 hex> (or the bare 64 hex) of the build the diff is about.", "type": "string" }, "build_sha256": { "description": "64-hex sha256 of the file at build_ref/path — must match the stored artifact's own sha256.", "type": "string" }, "path": { "description": "Repo-relative path from the build manifest (tascan_get_build).", "type": "string" }, "text": { "description": "The already-computed diff text (up to 262144 characters). This tool never computes a diff itself.", "type": "string" }, "truncated": { "description": "True if text is itself a truncated diff.", "type": "boolean" } }, "required": [ "build_ref", "path", "base_ref", "text", "build_sha256" ], "type": "object" }, "name": "tascan_get_build_diff", "outputSchema": null }, { "description": "Read one file from a stored build bundle by build_ref and path (protocol v0.2 build_artifacts) — the exact bytes the executor produced, not a working-tree read. Returns up to 12000 chars per call with offset/limit paging (next_offset when truncated), plus the file's sha256 and byte length. Binary or over-cap files return no content (the sha256 still binds them). Read tier; this is what the independent reviewer reads. The header lines (path, build, sha256, chars a-b of total) are the record a reviewer's read is bound to; read every chunk until the range covers the whole file.", "inputSchema": { "properties": { "build_ref": { "description": "sha256:<64 hex> (or the bare 64 hex).", "type": "string" }, "limit": { "description": "Characters to return (1-12000, default 12000).", "type": "integer" }, "offset": { "description": "Character offset to start from (default 0).", "type": "integer" }, "path": { "description": "Repo-relative path exactly as listed by tascan_get_build.", "type": "string" } }, "required": [ "build_ref", "path" ], "type": "object" }, "name": "tascan_get_build_file", "outputSchema": null }, { "description": "The audit report of one coordination cycle by its root task id (protocol v0.2, get_cycle_report): every step task (build, review, checkpoint, integrate, question, parked) with its revision and state, every execution attempt with runner, outcome, build_ref and usage/cost, every completion (receipt id = completion id, receipt hash), every reviewer verdict, every human decision and answer, the full trail (messages), the ledger events and the hash-chain verdict per task, plus spend against the cap. A computed summary (stage, attempts, verdicts, decisions, receipts, spend, chains_ok) comes first; pass full=true for the complete JSON (large). Read tier. This is the ONLY per-cycle notification surface: cycle steps do not e-mail or text anyone except the one checkpoint / human-question SMS.", "inputSchema": { "properties": { "full": { "description": "true = the complete report JSON (tasks, runs, completions, messages, events, bundles, chains) after the summary, capped at 12000 chars. Default: summary only.", "type": "boolean" }, "root_id": { "description": "The cycle root = the T1 build task id (returned by tascan_create_cycle; a non-root cycle task returns its root_id in the error).", "type": "string" } }, "required": [ "root_id" ], "type": "object" }, "name": "tascan_get_cycle_report", "outputSchema": null }, { "description": "Get one device by id: kind, name, status, location zone, credential rotation timestamps, revocation reason, and the last 20 evidence_events ids it produced. Never returns a credential hash.", "inputSchema": { "properties": { "device_id": { "description": "Device ID", "type": "string" } }, "required": [ "device_id" ], "type": "object" }, "name": "tascan_get_device", "outputSchema": null }, { "description": "Get details of a specific event (task list) including its tasks", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_get_event", "outputSchema": null }, { "description": "Read a fan-out (GET /coord/fanouts/:id?view=). view=status (default): state, seat counts, spend, cap, synth_deadline_at, poll_after_s. view=report: the full cycle report (get_cycle_report) — every seat, review and control step. view=rollup: the exact roll-up response_value plus its leaves (path, sha256, completion_id) once closed. view=verify: the server recomputes rollup_ref over the frozen leaves and returns ok / mismatches — the same check scripts/verify-fanout.js performs independently from another machine, which is the trusted proof; this view is a convenience, not a substitute. A foreign org's fanout_id answers 404, never 403, so another org's fan-out never even appears to exist. Read tier, no dispatch permission required.", "inputSchema": { "properties": { "fanout_id": { "description": "Fan-out id (UUID) — the T_F root, from tascan_create_fanout or tascan_list_cycles.", "type": "string" }, "view": { "description": "status (default), report, rollup or verify.", "enum": [ "status", "report", "rollup", "verify" ], "type": "string" } }, "required": [ "fanout_id" ], "type": "object" }, "name": "tascan_get_fanout", "outputSchema": null }, { "description": "Get details of a specific project", "inputSchema": { "properties": { "project_id": { "description": "Project ID", "type": "string" } }, "required": [ "project_id" ], "type": "object" }, "name": "tascan_get_project", "outputSchema": null }, { "description": "Fetch the signed Action Receipt (Ed25519 JWS) for one completed task by completion_id (tascan_get_task -> completions[].id). Returns a readable summary (what, who, verification, evidence hashes, outcome, ledger chain) plus receipt_id/serial/kid, the compact JWS and the public verify URL. Verify offline against the JWKS or online by POSTing a JSON body whose jws field holds the compact receipt. Read outcome and verification separately: outcome completed = the executor returned and a result was recorded; verification.result = the verdict of a named policy; all-null verification with reason no_policy_run = no policy ran. Never treat outcome=completed as success without a policy verdict you trust (protocol 8.3 C11). Verifier: 6.8. profile=public returns the separately signed public export profile (protocol 6.10): it withholds the raw org, list, project, worker, run and trace ids (each a 16-hex id_hash) and storage locators, and binds to the full receipt - the form for anyone outside the org. Read tier.", "inputSchema": { "properties": { "completion_id": { "description": "task_completions.id (UUID) - from tascan_get_task -> completions[].id", "type": "string" }, "profile": { "description": "full (default) = the org view with the unsigned private block; public = the separately signed public export profile: no raw org, list, project, worker, run or trace id (each is a 16-hex id_hash), no storage locators, plus a binding to the full receipt it was derived from - the form to hand to anyone outside the org", "enum": [ "full", "public" ], "type": "string" } }, "required": [ "completion_id" ], "type": "object" }, "name": "tascan_get_receipt", "outputSchema": null }, { "description": "Get completion report for a task list (event) including task status, completions, workers, and photos. Set include_responses to also return the actual submitted response data (numbers, text, choices) for each completed task plus a per-task photos list with fetchable signed URLs (short-lived, ~1h) for the photo evidence.", "inputSchema": { "properties": { "include_responses": { "description": "Include the actual submitted response values for each completed task (default false — keeps the payload light)", "type": "boolean" }, "list_id": { "description": "Task list (event) ID", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_get_report", "outputSchema": null }, { "description": "Scan accountability data. Two modes: (1) tag_id — scans of a registered NFC tag; (2) task_list_id or project_id — every QR/link page-open stamp: when the code was scanned, GPS + IP + channel (qr/nfc/sms/email/link), who the scanner turned out to be, and the scan→start delta (how long between scanning and actually identifying + starting work — the sign-in-and-vanish metric).", "inputSchema": { "properties": { "limit": { "description": "Max results (default 50, max 200)", "type": "number" }, "project_id": { "description": "Project ID — page-scan mode, all lists in the project", "type": "string" }, "since": { "description": "ISO timestamp — only scans after this", "type": "string" }, "source": { "description": "Filter page scans by channel: qr | nfc | sms | email | link | unknown", "type": "string" }, "tag_id": { "description": "NFC tag registry ID (from tascan_list_tags) — tag mode", "type": "string" }, "task_list_id": { "description": "Task list ID — page-scan mode", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_get_scan_history", "outputSchema": null }, { "description": "Check delivery status of a previously sent TaScan SMS by its Twilio SID (returned by tascan_send_sms). Shows queued/sent/delivered/undelivered/failed plus carrier error codes.", "inputSchema": { "properties": { "twilio_sid": { "description": "Twilio message SID (SM...) from tascan_send_sms", "type": "string" } }, "required": [ "twilio_sid" ], "type": "object" }, "name": "tascan_get_sms_status", "outputSchema": null }, { "description": "Get details of a specific task including completions and subtasks. Each completion carries photo_url (raw storage path, stable) and photo_signed_url (short-lived fetchable URL, ~1h; null when no photo) so you can actually view the photo evidence. Tasks dispatched to an AI agent also carry an \"agent\" block (state claimed|running|completed|failed|expired|released, attempts, current run with runner/trace_id/error) — the only place agent failures are reported. A completion with status \"completed\" means the executor returned and its result was recorded (a model refusal, a wrong answer or an administrative note all \"complete\"); it does NOT mean the requested result was accepted. Acceptance is the completion evidence_check / the receipt verification.result under a named policy, and in v0.1 no policy exists for agent tasks (exact-output and rubric policies are v0.2) — check the recorded response text yourself before treating an agent completion as success (protocol §2.6, §3.2, §8.3 C11).", "inputSchema": { "properties": { "task_id": { "description": "Task ID", "type": "string" } }, "required": [ "task_id" ], "type": "object" }, "name": "tascan_get_task", "outputSchema": null }, { "description": "Read a task's trail messages (protocol v0.2 trail_messages, GET /tasks/:id/messages): question, answer, handoff and note/discussion entries, last 100, newest last (reading order). Optionally filter to a comma-separated set of kinds. Read tier. Post with tascan_post_message.", "inputSchema": { "properties": { "kinds": { "description": "Optional comma-separated kind filter, e.g. question,answer,handoff,note (discussion is stored as note; both names are accepted).", "type": "string" }, "task_id": { "description": "Task ID (UUID).", "type": "string" } }, "required": [ "task_id" ], "type": "object" }, "name": "tascan_get_task_trail", "outputSchema": null }, { "description": "Read your organization's usage and quota snapshot for a billing period (GET /usage): SMS, email and AI call counts against their plan limits, the 100-receipt-per-month hard stop (used, allowance, hard_stop), the rate-limit window (60 requests per minute), and coordination-cycle spend in micro-USD for build roots created in that period. period defaults to the current UTC month (YYYY-MM). by_key additionally breaks coordination spend down per dispatch-scoped API key, refused (403 owner_required) to anything but an owner admin session -- a tsk_ key never gets it. Read tier.", "inputSchema": { "properties": { "by_key": { "description": "Break coordination spend down per dispatch-scoped API key -- owner admin session only.", "type": "boolean" }, "period": { "description": "Billing period as YYYY-MM (default: current UTC month).", "type": "string" } }, "type": "object" }, "name": "tascan_get_usage", "outputSchema": null }, { "description": "Ungated, plain read of one worker row: name, contact, org, points, streaks, timestamps. (tascan_get_worker_passport is the rich stats view; this is the boring lookup.)", "inputSchema": { "properties": { "worker_id": { "description": "Worker ID", "type": "string" } }, "required": [ "worker_id" ], "type": "object" }, "name": "tascan_get_worker", "outputSchema": null }, { "description": "Get a worker's verified work passport — task counts, lists worked, photos submitted, GPS-verified hours, points, streaks, and earned merit badges, all computed from real completion data (not self-reported). Includes the shareable profile URL.", "inputSchema": { "properties": { "worker_id": { "description": "Worker ID", "type": "string" } }, "required": [ "worker_id" ], "type": "object" }, "name": "tascan_get_worker_passport", "outputSchema": null }, { "description": "Extend a claimed local run's lease and mark it running (POST /runs/:run_id/heartbeat -> heartbeat_agent_run). ok false with reason not_live means the run is no longer yours -- the sweep expired it, or it was never yours to begin with -- STOP, do not finish it. Never mints a completion or a receipt. Requires agent:dispatch:code. A run outside your org is 404, never 403.", "inputSchema": { "properties": { "extend_seconds": { "description": "Optional: push expires_at out to now + this many seconds (60-86400) if that is later than the current lease -- never shortens it.", "type": "integer" }, "instance": { "description": "The SAME instance string you claimed with -- a mismatch answers not_live.", "type": "string" }, "run_id": { "description": "The run ID from tascan_claim_run's response.", "type": "string" } }, "required": [ "run_id", "instance" ], "type": "object" }, "name": "tascan_heartbeat_run", "outputSchema": null }, { "description": "Invite a marketplace worker to a task list — the consented intro. TaScan texts the worker from its own number (\"<Your org> wants you for <list>. Reply YES to share your contact and get the list, or NO to pass.\"). On YES the worker appears in your org with their name + phone, receives the list link, and you get a text + a thread message. On NO or silence (7 days) you never learn who they were. Use the worker_id from tascan_search_marketplace.", "inputSchema": { "properties": { "list_id": { "description": "Task list you want them on", "type": "string" }, "message": { "description": "Optional short intro prepended to the text (max 240 chars)", "type": "string" }, "worker_id": { "description": "worker_id from a marketplace card", "type": "string" } }, "required": [ "worker_id", "list_id" ], "type": "object" }, "name": "tascan_invite_worker", "outputSchema": null }, { "description": "List all registered AI agents with their capabilities, inbox IDs, and status. Like reading input labels on a video matrix — discover which agents are available and what they can do before dispatching work.", "inputSchema": { "properties": {}, "required": [], "type": "object" }, "name": "tascan_list_agents", "outputSchema": null }, { "description": "List registered condition-ledger assets with their latest condition scores. Use to recover an asset_id for tascan_assess_condition or tascan_condition_history.", "inputSchema": { "properties": { "project_id": { "description": "Filter by project", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_assets", "outputSchema": null }, { "description": "List coordination-cycle roots in the organization (protocol v0.2, GET /coord/cycles): root id, title, status, task_type, project, build_ref, deploy_id and the T2 review id, newest first. Filter by project_id and/or status. Read tier — a reviewer's read-only key can call this too. Follow up with tascan_get_cycle_report root_id=... for the full audit trail of any row.", "inputSchema": { "properties": { "limit": { "description": "Max rows to return (default 50, max 200).", "type": "integer" }, "project_id": { "description": "Optional project UUID to filter to one project's cycles.", "type": "string" }, "status": { "description": "Optional cycle status to filter on (e.g. active, parked, authorized, integrated) — lowercase letters and underscores only, 1-20 chars.", "type": "string" } }, "type": "object" }, "name": "tascan_list_cycles", "outputSchema": null }, { "description": "List delegated child keys (GET /delegations): this key's own direct children (id, label, scopes, active/revoked, depth, expires_at) — never the raw credential. An admin session sees every delegated key in the org. Read tier.", "inputSchema": { "properties": {}, "type": "object" }, "name": "tascan_list_delegations", "outputSchema": null }, { "description": "List registered devices (RFID portals, barcode guns, PLCs, cameras, robots, tools, sensors) in the organization. Filter by status (active/revoked) or kind; paginate with an opaque cursor. Never returns a credential hash.", "inputSchema": { "properties": { "cursor": { "description": "Opaque cursor from a previous response next_cursor", "type": "string" }, "kind": { "description": "Filter by device kind", "enum": [ "rfid_portal", "barcode", "nfc_reader", "tool", "plc", "camera", "robot", "sensor", "other" ], "type": "string" }, "limit": { "description": "Max rows to return (1-200, default 50)", "type": "number" }, "status": { "description": "Filter by device status", "enum": [ "active", "revoked" ], "type": "string" } }, "type": "object" }, "name": "tascan_list_devices", "outputSchema": null }, { "description": "List all events (task lists) within a project", "inputSchema": { "properties": { "project_id": { "description": "Project ID", "type": "string" } }, "required": [ "project_id" ], "type": "object" }, "name": "tascan_list_events", "outputSchema": null }, { "description": "List marketplace invites you have sent and their status (pending / accepted / declined / expired / failed). Accepted invites include the worker's name and phone — that is the consent boundary; pending and declined never do.", "inputSchema": { "properties": { "status": { "enum": [ "pending", "accepted", "declined", "expired", "failed" ], "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_invites", "outputSchema": null }, { "description": "List invoices for the org (newest first) with status, client, total, due date and share link. Filter by status (draft/sent/paid/overdue/cancelled) or project.", "inputSchema": { "properties": { "project_id": { "type": "string" }, "status": { "enum": [ "draft", "sent", "paid", "overdue", "cancelled" ], "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_invoices", "outputSchema": null }, { "description": "List all issues for a task list (event). Returns open, acknowledged, and resolved issues with severity, type, and category. Use this to discover issues that need AI analysis via tascan_analyze_issue.", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_list_issues", "outputSchema": null }, { "description": "List gig payments and their lifecycle status: awaiting_completion (pledged, work not verified yet), ready_to_pay (verified — pay link sent to payer), paid, canceled. Filter by task list or status.", "inputSchema": { "properties": { "status": { "description": "Filter by status", "enum": [ "awaiting_completion", "ready_to_pay", "paid", "canceled" ], "type": "string" }, "task_list_id": { "description": "Filter by task list", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_payments", "outputSchema": null }, { "description": "List all TaScan projects in the organization", "inputSchema": { "properties": {}, "type": "object" }, "name": "tascan_list_projects", "outputSchema": null }, { "description": "List existing report links for a list or project (completion / service / project / evidence), newest first, with client acknowledgment status for service reports.", "inputSchema": { "properties": { "list_id": { "type": "string" }, "project_id": { "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_reports", "outputSchema": null }, { "description": "List your org's scheduled texts (default: pending + sending, soonest first; status=sent|failed|cancelled to see history). Each row shows send_at, status, attempts, the Twilio sid once sent, and the last error for a failed row.", "inputSchema": { "properties": { "status": { "description": "Filter by status (default pending + sending)", "enum": [ "pending", "sending", "sent", "failed", "cancelled" ], "type": "string" } }, "type": "object" }, "name": "tascan_list_scheduled_sms", "outputSchema": null }, { "description": "List the subtasks of a task, including completion state, stored response values, and completion timestamps (per-set timing).", "inputSchema": { "properties": { "task_id": { "description": "Parent task ID", "type": "string" } }, "required": [ "task_id" ], "type": "object" }, "name": "tascan_list_subtasks", "outputSchema": null }, { "description": "List all registered NFC tags in the organization with their linked projects/task lists and scan counts", "inputSchema": { "properties": {}, "type": "object" }, "name": "tascan_list_tags", "outputSchema": null }, { "description": "List all tasks in an event (task list)", "inputSchema": { "properties": { "list_id": { "description": "Task list (event) ID", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_list_tasks", "outputSchema": null }, { "description": "List available task templates (built-in and saved)", "inputSchema": { "properties": { "category": { "description": "Filter by category (e.g. \"live-events\", \"hospitality\", \"logistics\")", "type": "string" } }, "type": "object" }, "name": "tascan_list_templates", "outputSchema": null }, { "description": "Read a task completion's verification verdicts and job queue (Verification Layer V2, GET /completions/:completion_id/verifications): completion_verifications rows (state, method, verifier, policy, confidence, finding) plus verification_jobs rows (state, attempts, last_error, result). Read tier.", "inputSchema": { "properties": { "completion_id": { "description": "task_completions.id (UUID) — from tascan_get_task -> completions[].id.", "type": "string" } }, "required": [ "completion_id" ], "type": "object" }, "name": "tascan_list_verifications", "outputSchema": null }, { "description": "List workers (taskees) in the organization. Supports filtering by name/email/phone substring, contact-info presence, and last-activity date. Each row includes completion_count (total task completions).", "inputSchema": { "properties": { "active_since": { "description": "ISO date/datetime — only workers with last_active_at on/after this", "type": "string" }, "has_email": { "description": "true/false — same for email", "type": "boolean" }, "has_phone": { "description": "true = only workers with a phone on file; false = only without", "type": "boolean" }, "include_inactive": { "description": "true = also include inactive workers (e.g. tombstones left by a merge or delete) — useful for auditing right after tascan_merge_workers / tascan_delete_worker", "type": "boolean" }, "query": { "description": "Substring match on name, email, or phone", "type": "string" } }, "type": "object" }, "name": "tascan_list_workers", "outputSchema": null }, { "description": "List geofenced work zones, optionally filtered by project. Shows center, radius, routing target, and zone-lock status.", "inputSchema": { "properties": { "project_id": { "description": "Filter by project", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_list_zones", "outputSchema": null }, { "description": "Merge duplicate worker records into one canonical identity (Patent 4 identity consolidation). Reassigns every reference (completions, timer events, points, payments, rosters — 31 columns across 31 tables), backfills missing phone/email on the primary, sums points, and tombstones the duplicates (merged_into + is_active=false — NEVER hard-deletes). ALWAYS run with dry_run=true first and show Mike the counts; pass dry_run=false only after explicit confirmation.", "inputSchema": { "properties": { "dry_run": { "description": "true (default) = report reassignment counts only, change nothing. false = execute atomically.", "type": "boolean" }, "duplicate_worker_ids": { "description": "Worker IDs to fold into the primary (max 20)", "items": { "type": "string" }, "type": "array" }, "primary_worker_id": { "description": "The canonical worker that survives (usually the one with a phone)", "type": "string" } }, "required": [ "primary_worker_id", "duplicate_worker_ids" ], "type": "object" }, "name": "tascan_merge_workers", "outputSchema": null }, { "description": "Read organization-wide analytics: view org (GET /analytics/org, the get_org_analytics rollup) or view resolutions (GET /analytics/resolutions, paginated AI issue-resolution history, filterable by severity, category, and pattern-detected). Read tier.", "inputSchema": { "properties": { "category": { "description": "resolutions only: filter by issue_category.", "type": "string" }, "limit": { "description": "resolutions only: page size (default 50, max 200).", "type": "integer" }, "offset": { "description": "resolutions only: page offset.", "type": "integer" }, "pattern": { "description": "resolutions only: true to filter to pattern_detected rows only.", "type": "boolean" }, "severity": { "description": "resolutions only: filter by classification_severity.", "type": "string" }, "view": { "description": "Which analytics surface to read.", "enum": [ "org", "resolutions" ], "type": "string" } }, "required": [ "view" ], "type": "object" }, "name": "tascan_org_analytics", "outputSchema": null }, { "description": "Post one evidence event into the evidence ledger (protocol v0.2 V9a, POST /evidence): an actor did an action to an object at a point in time, optionally with a location and provenance. idempotency_key is required — the same (org, idempotency_key) always returns the same row, never a second insert. Optionally correlate the event to a task or task list. Write tier; a device credential (structurally different from an API key) is not reachable through this MCP connection, so device_id is never set here.", "inputSchema": { "properties": { "action": { "description": "What happened, e.g. inspected, scanned, calibrated.", "type": "string" }, "actor": { "description": "Who did it.", "properties": { "id": { "description": "The actor's id.", "type": "string" }, "kind": { "description": "worker requires an active, unmerged worker id in your organization; agent/device ids are recorded as given.", "enum": [ "worker", "agent", "device" ], "type": "string" } }, "required": [ "kind", "id" ], "type": "object" }, "correlation": { "description": "Optional correlation hint.", "properties": { "task_id": { "description": "A task UUID in your organization to correlate this evidence to.", "type": "string" }, "task_list_id": { "description": "A task list UUID in your organization to correlate this evidence to (used when task_id is absent or does not resolve).", "type": "string" } }, "type": "object" }, "idempotency_key": { "description": "Required, 1-200 chars. The same key on the same org replays the same stored row.", "type": "string" }, "location": { "description": "Optional location.", "properties": { "lat": { "type": "number" }, "lng": { "type": "number" }, "zone_id": { "description": "Optional geofence zone UUID.", "type": "string" } }, "type": "object" }, "object": { "description": "What it happened to.", "properties": { "kind": { "description": "What kind of thing object.ref names.", "enum": [ "asset", "tag", "serial", "url" ], "type": "string" }, "ref": { "description": "The object reference (asset id, tag id, serial number, or URL).", "type": "string" } }, "required": [ "kind", "ref" ], "type": "object" }, "occurred_at": { "description": "ISO timestamp for when the event actually happened.", "type": "string" }, "provenance": { "description": "Optional provenance object. provenance.kind first_party_scan is written only by the scan_events trigger and is refused from a caller; provenance.signature triggers device-signature verification.", "type": "object" } }, "required": [ "actor", "action", "object", "occurred_at", "idempotency_key" ], "type": "object" }, "name": "tascan_post_evidence", "outputSchema": null }, { "description": "Post a message on a task trail (protocol v0.2 trail_messages): kind question, answer, handoff or discussion. A message never completes a task, never satisfies a gate and never pages anyone. The actor is stamped from your credential (key:<id>, actor_type \"key\" — a credential, never a human), never from the body; the executor and the reviewer consume a key's answers only when the key holds agent:dispatch. On an ordinary task this is write tier. On a CYCLE task (one with coord) it needs agent:dispatch (agent:dispatch:code when the task, or the asker a question task stands for, is CODE:/SHELL:) because the text can become executor prompt or reviewer input. kind=answer on a dispatcher-addressed question task answers it through coord_answer_question and releases the blocked asker; a human-addressed question is answered only on the worker page (403 here). finding (reviewer runner) and decision (human completion) cannot be posted. Body ≤ 8000 chars; idempotency_key makes a replay return the same message.", "inputSchema": { "properties": { "addressee": { "description": "Optional, kind=question only: who the question is for (recorded; nobody is paged).", "enum": [ "human", "dispatcher" ], "type": "string" }, "body": { "description": "The message text (1-8000 chars). Treated as DATA by every reader; on a cycle task it may be prepended to the executor prompt as TRAIL INPUT.", "type": "string" }, "build_ref": { "description": "Optional sha256:<64 hex> the message is about (defaults to the cycle task's bound build).", "type": "string" }, "idempotency_key": { "description": "Optional replay key (≤ 200 chars): the same key on the same task returns the same message id.", "type": "string" }, "kind": { "description": "question = a question for the record (does not block anything); answer = answers a dispatcher question task and releases the asker; handoff = hand work or context to the next agent; discussion = a note.", "enum": [ "question", "answer", "handoff", "discussion" ], "type": "string" }, "reply_to": { "description": "Optional message id this replies to.", "type": "string" }, "task_id": { "description": "Task ID (UUID). For an answer: the QUESTION task id (tascan_get_task on the asker shows coord.blocked_by).", "type": "string" } }, "required": [ "task_id", "kind", "body" ], "type": "object" }, "name": "tascan_post_message", "outputSchema": null }, { "description": "One call that gives a chat client (ChatGPT, Claude) a whole TaScan project in about 2,000 words: the project, every task list with task counts, open decisions and questions, the last 5 coordination cycles with verdicts and spend, the latest 5 receipts, and total spend — returned as Markdown (capped at 12,000 chars). Read tier. Use it before asking a human to paste anything.", "inputSchema": { "properties": { "project_id": { "description": "Project ID (UUID).", "type": "string" } }, "required": [ "project_id" ], "type": "object" }, "name": "tascan_project_digest", "outputSchema": null }, { "description": "Query one task's submitted responses across every list in a project — e.g. the same exercise repeated across many workout lists returns one chronological progression series instead of N report lookups. Match by task title pattern or exact task ID. Subtask completions interleave into the same series labeled 'Task › Subtask' (e.g. per-set values Set 1/2/3 with their own timestamps), so set-level progression chains across lists automatically.", "inputSchema": { "properties": { "limit": { "description": "Max responses to return (default 200, max 500)", "type": "number" }, "project_id": { "description": "Project ID", "type": "string" }, "task": { "description": "Task title pattern (case-insensitive substring) or exact task ID", "type": "string" } }, "required": [ "project_id", "task" ], "type": "object" }, "name": "tascan_query_responses", "outputSchema": null }, { "description": "One action to a genuinely verified receipt (POST /quickstart). Under your org it reuses-or-creates the project \"TaScan Quickstart\", its list \"Quickstart\" and the worker \"Quickstart executor\", adds a NEW task \"Reply with the exact text: <expected>\", completes it with your key, has the named policy quickstart_exact_output v1 compare the response to the expected text (verified or refuted, signed into the receipt), and publishes the receipt's public profile. expected defaults to \"VERIFIED\" (max 200 chars); response defaults to expected — pass a different response to see a refuted receipt. Returns the receipt URL and the public verify URL. Write tier.", "inputSchema": { "properties": { "expected": { "description": "The exact text the task asks for (default \"VERIFIED\", max 200 chars).", "type": "string" }, "response": { "description": "The response to submit (default: the expected text). A different value is refuted.", "type": "string" } }, "type": "object" }, "name": "tascan_quickstart", "outputSchema": null }, { "description": "Step 2 of the Closed-Loop Autonomous Operations Protocol. Post an AI-generated recommendation to an issue thread. Accepts both a text recommendation and an optional structured_recommendation object with task definitions for auto-dispatch. The recommendation is persisted in the AI audit trail.", "inputSchema": { "properties": { "ai_agent": { "description": "Name of the AI agent posting (default: TaScan AI)", "type": "string" }, "issue_id": { "description": "Issue ID to recommend a fix for", "type": "string" }, "recommendation": { "description": "The AI-generated recommendation text (clear, actionable instructions)", "type": "string" }, "structured_recommendation": { "description": "Optional structured recommendation with tasks for auto-dispatch. Format: { recommendation_summary, confidence_score, tasks: [{ title, description, response_type, requires_photo, is_safety_checkpoint, sort_order }], estimated_duration_minutes, required_responder_role }", "type": "object" } }, "required": [ "issue_id", "recommendation" ], "type": "object" }, "name": "tascan_recommend_fix", "outputSchema": null }, { "description": "D4: the dispatcher records the Netlify deploy id for an authorized cycle — Integrate cards stop landing on Mike for something a key can prove instead (protocol v0.2, migration 181, coord_record_integration). Requires agent:dispatch. The root must be `authorized` (its checkpoint already Approved) with an open Integrate task; deploy_id must be a real Netlify deploy id — 24 lowercase hex, optionally \"deployed:<id>\" and/or a trailing build-ref hex prefix (\"Deploy\" and anything else is refused, bad_deploy_id). On success the root flips to `integrated`, the existing \"Integrated: deploy …\" trail note is posted, and the completion is stamped with your key as the actor (source api:key:<id>) — never as a human on the page. Idempotent: replaying the SAME deploy_id after the root is already integrated returns the same completion (replayed:true); a DIFFERENT deploy_id after integration is refused (409) without changing anything. A human may still complete the Integrate card on the worker page as an ops fallback, but only with a real deploy id too.", "inputSchema": { "properties": { "deploy_id": { "description": "The Netlify deploy id: 24 lowercase hex, optionally prefixed \"deployed:\" and/or followed by a space and a ≥12-hex prefix of the build_ref.", "type": "string" }, "note": { "description": "Optional note (≤ 2000 chars) recorded alongside the completion — e.g. what changed in this deploy.", "type": "string" }, "root_id": { "description": "The cycle root = the T1 build task id (tascan_get_cycle_report / tascan_create_cycle). Must currently be authorized (checkpoint Approved, Integrate task open).", "type": "string" } }, "required": [ "root_id", "deploy_id" ], "type": "object" }, "name": "tascan_record_integration", "outputSchema": null }, { "description": "Register a new AI agent in the agent registry. The agent will appear in tascan_list_agents and can receive dispatched tasks. Self-registration for AI agents joining the TaScan network. REQUIRES the agent:dispatch permission (defining a dispatch target is a dispatch permission); inbox_id must be a task list (event) in your organization.", "inputSchema": { "properties": { "capabilities": { "description": "Task type prefixes this agent handles (e.g. [\"RESEARCH\", \"WRITE\"])", "items": { "type": "string" }, "type": "array" }, "description": { "description": "What this agent does", "type": "string" }, "id": { "description": "Unique agent ID (e.g. \"my-agent-1\")", "type": "string" }, "inbox_id": { "description": "Task list ID this agent monitors for new tasks", "type": "string" }, "location": { "description": "Where the agent runs (e.g. \"AWS us-east-1\")", "type": "string" }, "model": { "description": "Model powering this agent (e.g. \"claude-sonnet-4-6\")", "type": "string" }, "name": { "description": "Display name (e.g. \"Research Bot\")", "type": "string" }, "type": { "description": "Agent type", "enum": [ "local", "cloud", "hybrid" ], "type": "string" }, "worker_id": { "description": "TaScan worker ID for this agent", "type": "string" } }, "required": [ "id", "name", "type", "inbox_id", "capabilities" ], "type": "object" }, "name": "tascan_register_agent", "outputSchema": null }, { "description": "Register a physical asset (equipment, structure, vehicle, machine) in the condition ledger so it can be assessed over time. Each asset gets a longitudinal condition history with AI scoring and degradation trajectory.", "inputSchema": { "properties": { "asset_type": { "description": "Type (e.g. \"LED processor\", \"forklift\", \"scaffold\")", "type": "string" }, "description": { "description": "Context the AI assessor should know", "type": "string" }, "location_description": { "type": "string" }, "name": { "description": "Asset name (e.g. \"LED Wall Processor #3\")", "type": "string" }, "project_id": { "type": "string" }, "serial_number": { "description": "Serial number or asset tag (unique per org)", "type": "string" } }, "required": [ "name" ], "type": "object" }, "name": "tascan_register_asset", "outputSchema": null }, { "description": "Register a physical NFC tag to a project, task list, or specific task. When someone taps the tag, TaScan routes them to the linked resource. Tags use NTAG215 chips and are programmed with NFC Tools Pro.", "inputSchema": { "properties": { "location_description": { "description": "Physical location of the tag", "type": "string" }, "project_id": { "description": "Project ID", "type": "string" }, "tag_hardware_id": { "description": "NFC tag hardware serial number (e.g., \"04:CB:6C:51:CE:2A:81\")", "type": "string" }, "tag_name": { "description": "Friendly name (e.g., \"Ballroom A Door\", \"Breaker Panel 3\")", "type": "string" }, "target_type": { "description": "What this tag points to", "enum": [ "project", "task_list", "task" ], "type": "string" }, "task_id": { "description": "Task ID (required for task targets)", "type": "string" }, "task_list_id": { "description": "Task list ID (required for task_list/task targets)", "type": "string" } }, "required": [ "tag_hardware_id", "tag_name", "target_type" ], "type": "object" }, "name": "tascan_register_tag", "outputSchema": null }, { "description": "Reply to a task list WITH a task list — the two-way tasking primitive. Creates a new list linked into the parent's thread, aimed back at whoever sent the original (e.g. \"Grant access — pick a window\" with response_type date, or an info request with response_type text). The org gets pinged; the thread shows in both the worker portal and Simple Mode. Use tascan_get_thread-style follow-up via tascan_list_projects/tascan_get_report to read answers.", "inputSchema": { "properties": { "author_name": { "description": "Who is replying (shown in the thread)", "type": "string" }, "parent_list_id": { "description": "The list being replied to", "type": "string" }, "tasks": { "description": "Items the recipient answers — each becomes a typed task", "items": { "properties": { "description": { "type": "string" }, "response_config": { "type": "object" }, "response_type": { "description": "\"date\" for scheduling windows, \"text\" for info requests, \"choice\" needs response_config.options. \"link\" = the worker submits a URL. \"url\" = the worker visits a preset URL and confirms. \"file\" = the worker uploads a file.", "enum": [ "checkbox", "text", "number", "date", "choice", "photo", "link", "url", "file" ], "type": "string" }, "title": { "type": "string" } }, "required": [ "title" ], "type": "object" }, "type": "array" }, "title": { "description": "Reply list title (e.g. \"Before I can start...\")", "type": "string" } }, "required": [ "parent_list_id", "title", "tasks" ], "type": "object" }, "name": "tascan_reply_with_list", "outputSchema": null }, { "description": "Pledge a payment on a task list: when the list is verified complete (every task done + photo evidence on photo-required tasks), the payer automatically receives a Stripe pay link that routes the money DIRECTLY to the worker (0% TaScan fee). No money moves and no card is stored at pledge time. The worker must have completed payout onboarding (Get Paid on their profile).", "inputSchema": { "properties": { "amount_cents": { "description": "Amount in cents ($1 min, $10,000 max)", "type": "number" }, "idempotency_key": { "description": "B1: optional replay key (up to 1024 chars, no braces) sent verbatim as the Idempotency-Key header instead of a fresh one per call — a retried call with the SAME key replays the original pledge instead of creating a second one.", "type": "string" }, "memo": { "description": "What the payment is for (shown to the payer)", "type": "string" }, "payer_email": { "description": "Who pays — receives the pay link on verification", "type": "string" }, "payer_name": { "type": "string" }, "task_list_id": { "description": "Task list the payment is tied to", "type": "string" }, "worker_id": { "description": "Worker who gets paid", "type": "string" } }, "required": [ "task_list_id", "worker_id", "amount_cents", "payer_email" ], "type": "object" }, "name": "tascan_request_payment", "outputSchema": null }, { "description": "Enqueue an autonomous verification job for a task completion (Verification Layer V2 + V7 doc_check, POST /completions/:completion_id/verification-jobs): http_probe checks a URL (params url, and optionally expect_status, expect_content_type, expect_sha256), doc_check runs a named policy against params.url and params.policy_id. Read the result with tascan_list_verifications once the job runs. Write tier.", "inputSchema": { "properties": { "check_type": { "description": "Which autonomous check to run.", "enum": [ "http_probe", "doc_check" ], "type": "string" }, "completion_id": { "description": "task_completions.id (UUID) — from tascan_get_task -> completions[].id.", "type": "string" }, "idempotency_key": { "description": "Optional replay key (up to 200 chars).", "type": "string" }, "params": { "description": "For http_probe: url, and optionally expect_status, expect_content_type, expect_sha256. For doc_check: url and policy_id, where policy_id names an active doc_check policy.", "type": "object" }, "run_at": { "description": "Optional ISO timestamp to schedule the job for (default now).", "type": "string" } }, "required": [ "completion_id", "check_type", "params" ], "type": "object" }, "name": "tascan_request_verification", "outputSchema": null }, { "description": "Revoke a delegated child key immediately (DELETE /delegations/:key_id) — self-revoke, revoke by an ancestor key, or by an admin session of the org; any other caller is refused. Revoking cascades to every key IT delegated, in turn (the database trigger, not application code). Idempotent: revoking an already-revoked key reports already_revoked, no error.", "inputSchema": { "properties": { "key_id": { "description": "The delegated key id to revoke (from tascan_list_delegations)", "type": "string" } }, "required": [ "key_id" ], "type": "object" }, "name": "tascan_revoke_delegation", "outputSchema": null }, { "description": "Revoke a device credential immediately — the kill switch for a lost, stolen, or decommissioned device (RFID portal, barcode gun, PLC, camera, robot, tool, sensor). Its next evidence post is refused. Idempotent: revoking an already-revoked device reports already_revoked and mints no second receipt. Requires the device:admin permission (owner-only, needs full, never reachable through OAuth).", "inputSchema": { "properties": { "device_id": { "description": "Device ID to revoke", "type": "string" }, "reason": { "description": "Why this device is being revoked (up to 500 characters)", "type": "string" } }, "required": [ "device_id" ], "type": "object" }, "name": "tascan_revoke_device", "outputSchema": null }, { "description": "Schedule a transactional TaScan SMS for a future time (up to 90 days out): the text is sent by TaScan's own scheduler (every 5 minutes) through the same guarded lane as tascan_send_sms — recipient must be a worker of your org or a phone the org already knows, STOP opt-outs honoured, burst limits and the SMS quota apply, the \"TaScan:\" prefix is added, and a list_id appends a tap-to-open checklist link. Use this for reminders (e.g. \"log your out time\" each show night) — nothing outside TaScan needs to stay awake. Returns the scheduled row id; cancel with tascan_cancel_scheduled_sms while it is still pending. The same idempotency_key within an org returns the existing row instead of a duplicate.", "inputSchema": { "properties": { "idempotency_key": { "description": "Optional caller key (≤ 200 chars) — replays return the existing scheduled row", "type": "string" }, "include_link": { "description": "Append the list link (default true when list_id is given)", "type": "boolean" }, "list_id": { "description": "Optional task list ID — appends the tap-to-open checklist link", "type": "string" }, "message": { "description": "Message text (1-400 chars, links stripped). Transactional and work-related only.", "type": "string" }, "phone": { "description": "Raw phone (E.164) — must already belong to a worker or roster entry of your org", "type": "string" }, "send_at": { "description": "When to send — ISO 8601 with a timezone offset, e.g. \"2026-09-25T18:30:00-07:00\" (Las Vegas is -07:00 in September). Delivery happens on the next 5-minute tick at or after this time.", "type": "string" }, "worker_id": { "description": "Worker ID — texts their phone on file (preferred over raw phone)", "type": "string" } }, "required": [ "send_at", "message" ], "type": "object" }, "name": "tascan_schedule_sms", "outputSchema": null }, { "description": "Search the cross-org Worker Marketplace: workers who opted in (discoverable=true on their passport), ranked by passkey trust tier + verified completion volume. Skills are AI-inferred from REAL completed work, not resumes — each carries a verified_task_count and a civilian_equivalent job title. Returns sanitized public cards only (first name + last initial, skills, stats, passport URL) — never phone, email, or org membership.", "inputSchema": { "properties": { "available": { "description": "Only workers who marked themselves available on their passport", "type": "boolean" }, "city": { "description": "Filter by the worker's opt-in home city, e.g. \"Las Vegas\"", "type": "string" }, "limit": { "description": "Max cards (default 25, max 50)", "type": "number" }, "min_completions": { "description": "Only workers with at least this many verified completions", "type": "number" }, "q": { "description": "Skill, category, name, or civilian job title — e.g. \"forklift\", \"LED wall\", \"AV technician\"", "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_search_marketplace", "outputSchema": null }, { "description": "Send a transactional TaScan SMS text to a worker (by worker_id, using their phone on file) or to a raw phone number. Optionally attach a task list — the recipient gets a tap-to-open checklist link. Sends from TaScan's carrier-registered A2P number (or the org's own Twilio if BYOK). Counts against the org's monthly SMS quota unless BYOK. Messages are auto-prefixed with \"TaScan:\" per carrier registration; transactional/work-related content only, no marketing.", "inputSchema": { "properties": { "idempotency_key": { "description": "B1: optional replay key (up to 1024 chars, no braces) sent verbatim as the Idempotency-Key header instead of a fresh one per call — a retried call with the SAME key replays the original response instead of sending a second text.", "type": "string" }, "include_link": { "description": "When a list_id is given, append the tap-to-open link to the SMS body (default true). Set false to send the message text alone — the link is still returned for you to share another way.", "type": "boolean" }, "list_id": { "description": "Optional task list ID — appends a tap-to-open worker checklist link", "type": "string" }, "message": { "description": "Message text. Transactional and work-related only.", "type": "string" }, "phone": { "description": "Raw phone number (e.g. \"+17025551234\") — used when no worker_id given", "type": "string" }, "worker_id": { "description": "Worker ID — sends to their phone on file (preferred over raw phone)", "type": "string" } }, "required": [ "message" ], "type": "object" }, "name": "tascan_send_sms", "outputSchema": null }, { "description": "Send a branded TaScan task notification email via SendGrid. Can notify anyone about a specific task list or task. Includes QR code, task summary, and \"Open in TaScan\" button.", "inputSchema": { "properties": { "include_qr": { "description": "Include QR code for the task list in the email (default: true)", "type": "boolean" }, "list_id": { "description": "Task list (event) ID", "type": "string" }, "message": { "description": "Optional custom message to include in the email body", "type": "string" }, "subject": { "description": "Custom email subject (defaults to auto-generated)", "type": "string" }, "task_id": { "description": "Optional specific task ID to highlight", "type": "string" }, "to_email": { "description": "Recipient email address", "type": "string" }, "to_name": { "description": "Recipient display name", "type": "string" } }, "required": [ "to_email", "list_id" ], "type": "object" }, "name": "tascan_send_task_email", "outputSchema": null }, { "description": "Identify exactly which TaScan server and schema this MCP session is talking to. Call this FIRST when diagnosing anything — it makes \"dev server masquerading as production\" and \"is my fix deployed yet\" one tool call instead of an inference.", "inputSchema": { "properties": {}, "required": [], "type": "object" }, "name": "tascan_server_info", "outputSchema": null }, { "description": "Update an event / task list (name, description, team_mode, multi_instance, timer_mode). team_mode and multi_instance cannot both be true.", "inputSchema": { "properties": { "assigned_worker_ids": { "description": "Worker UUIDs to assign to this event (additive — workers not named are left alone). Each gets a personal tap-to-open link. Note: a worker holds one event assignment per project — assigning moves them.", "items": { "type": "string" }, "type": "array" }, "description": { "description": "New description", "type": "string" }, "list_id": { "description": "Task list (event) ID", "type": "string" }, "multi_instance": { "description": "Multi-instance — each worker gets isolated copy", "type": "boolean" }, "name": { "description": "New name", "type": "string" }, "team_mode": { "description": "Team mode — shared completions", "type": "boolean" }, "timer_mode": { "description": "Timer mode (auto or manual)", "type": "string" } }, "required": [ "list_id" ], "type": "object" }, "name": "tascan_update_event", "outputSchema": null }, { "description": "Update an invoice: mark it paid (records paid_at), overdue, cancelled, or edit client details / notes / due date.", "inputSchema": { "properties": { "client_email": { "type": "string" }, "client_name": { "type": "string" }, "client_phone": { "type": "string" }, "due_date": { "type": "string" }, "invoice_id": { "type": "string" }, "notes": { "type": "string" }, "paid_at": { "description": "ISO timestamp (default now) when status = paid", "type": "string" }, "status": { "enum": [ "draft", "sent", "paid", "overdue", "cancelled" ], "type": "string" } }, "required": [ "invoice_id" ], "type": "object" }, "name": "tascan_update_invoice", "outputSchema": null }, { "description": "Update a project (name, location, status, dates)", "inputSchema": { "properties": { "end_date": { "description": "End date (ISO)", "type": "string" }, "location": { "description": "New location", "type": "string" }, "name": { "description": "New name", "type": "string" }, "project_id": { "description": "Project ID", "type": "string" }, "start_date": { "description": "Start date (ISO)", "type": "string" }, "status": { "description": "Status", "enum": [ "active", "archived" ], "type": "string" } }, "required": [ "project_id" ], "type": "object" }, "name": "tascan_update_project", "outputSchema": null }, { "description": "Update a subtask (title, description, response_type, response_config, requires_photo, sort_order).", "inputSchema": { "properties": { "description": { "type": "string" }, "requires_photo": { "type": "boolean" }, "response_config": { "type": "object" }, "response_type": { "description": "\"link\" = the worker submits a URL. \"url\" = the worker visits a preset URL and confirms. \"file\" = the worker uploads a file.", "enum": [ "checkbox", "number", "text", "choice", "link", "url", "file" ], "type": "string" }, "sort_order": { "type": "number" }, "subtask_id": { "description": "Subtask ID", "type": "string" }, "title": { "type": "string" } }, "required": [ "subtask_id" ], "type": "object" }, "name": "tascan_update_subtask", "outputSchema": null }, { "description": "Update a task (title, description, response_type, flags, sort_order). A task that sits in an AI agent inbox is agent input (the runner executes title + description), so ANY edit to it needs the agent:dispatch permission — agent:dispatch:code when the task is or becomes CODE:/SHELL:.", "inputSchema": { "properties": { "assigned_to": { "description": "Worker to assign this task to — pass the worker UUID (validated against your org and stored as the worker's name, which is how the worker portal matches \"my tasks\"). A plain name string is also accepted as-is. Pass null to clear.", "type": "string" }, "description": { "description": "New description", "type": "string" }, "is_safety_checkpoint": { "description": "Safety-critical flag", "type": "boolean" }, "required_equipment": { "description": "Equipment this task depends on (free text)", "type": "string" }, "requires_photo": { "description": "Require photo", "type": "boolean" }, "response_config": { "description": "Response configuration. For \"choice\": {options: [...]}. See tascan_add_tasks.", "type": "object" }, "response_type": { "description": "See tascan_add_tasks for guidance. \"text\" for info collection, \"photo\" for visual proof, \"checkbox\" for yes/no only, \"link\" for the worker submitting a URL, \"url\" for the worker visiting a preset URL and confirming, \"file\" for the worker uploading a file.", "enum": [ "checkbox", "photo", "text", "number", "date", "choice", "link", "url", "file" ], "type": "string" }, "sort_order": { "description": "Sort position", "type": "number" }, "task_id": { "description": "Task ID", "type": "string" }, "title": { "description": "New title", "type": "string" } }, "required": [ "task_id" ], "type": "object" }, "name": "tascan_update_task", "outputSchema": null }, { "description": "Update a worker profile (name, phone, email)", "inputSchema": { "properties": { "email": { "description": "New email", "type": "string" }, "name": { "description": "New name", "type": "string" }, "phone": { "description": "New phone", "type": "string" }, "worker_id": { "description": "Worker ID", "type": "string" } }, "required": [ "worker_id" ], "type": "object" }, "name": "tascan_update_worker", "outputSchema": null }, { "description": "Update a geofenced zone — move the center, resize the radius, change the routing target, toggle zone-lock, or deactivate it (is_active=false).", "inputSchema": { "properties": { "alert_on_breach": { "type": "boolean" }, "auto_clock_in": { "description": "Writes a shift_start when the WORKER PAGE, while open, sees the phone enter the zone; detection is pull-based, there is no background geofencing. For a background-free presence event use a gate NFC/QR scan.", "type": "boolean" }, "auto_clock_out": { "description": "Writes a shift_end when the WORKER PAGE, while open, sees the phone leave the zone; detection is pull-based, there is no background geofencing. For a background-free presence event use a gate NFC/QR scan.", "type": "boolean" }, "enforce_on_list": { "type": "boolean" }, "enter_message": { "type": "string" }, "is_active": { "type": "boolean" }, "kind": { "enum": [ "work_site", "hazard", "containment", "restricted" ], "type": "string" }, "lat": { "type": "number" }, "lng": { "type": "number" }, "name": { "type": "string" }, "notify_email": { "type": "string" }, "notify_on_enter": { "type": "boolean" }, "notify_on_exit": { "type": "boolean" }, "polygon": { "description": "Replace geometry with a polygon ([[lat,lng],...], ≥3 vertices); pass null to revert to a circle", "items": { "items": { "type": "number" }, "type": "array" }, "type": "array" }, "ppe_photo_required": { "type": "boolean" }, "radius_m": { "type": "number" }, "required_ppe": { "items": { "enum": [ "hard_hat", "safety_glasses", "hi_vis_vest", "gloves", "steel_toe_boots", "hearing_protection", "harness", "respirator", "face_shield" ], "type": "string" }, "type": "array" }, "sms_worker_on_enter": { "type": "boolean" }, "sms_worker_on_exit": { "type": "boolean" }, "task_list_id": { "type": "string" }, "task_list_on_enter": { "type": "string" }, "zone_id": { "description": "Zone ID", "type": "string" } }, "required": [ "zone_id" ], "type": "object" }, "name": "tascan_update_zone", "outputSchema": null }, { "description": "Independently verify a TaScan Action Receipt JWS (protocol 6.8, POST /receipts/verify): size, envelope, signature, issuer origin, key lifecycle, hashing profile, value semantics, schema and chain check, with an online issued/serial check for the reference issuer. Public route: no TaScan scope is required by the API itself, though this MCP connection still needs some valid key to place any tools/call. Works for both the full and the public export profile. Keys come only from the issuer's own well-known key document (https://app.tascan.io/.well-known/tascan-receipt-keys.json for the reference issuer, or the equivalent well-known path for a foreign one) — this tool never supplies keys itself. Never verifies locally — always calls the reference verifier.", "inputSchema": { "properties": { "jws": { "description": "The compact JWS to verify (from tascan_get_receipt's output, or any TaScan-format receipt).", "type": "string" } }, "required": [ "jws" ], "type": "object" }, "name": "tascan_verify_receipt", "outputSchema": null }, { "description": "Hazard-zone compliance audit (OSHA / insurance): every zone crossing, PPE checkpoint verdict (complied / failed with what was missing / skipped), and breach, plus injury reports cross-referenced with the worker's last PPE checkpoint before the injury. Scope by project or zone, optionally by worker and date range. Same rows the printable Evidence Pack shows.", "inputSchema": { "properties": { "project_id": { "type": "string" }, "since": { "description": "ISO date/time lower bound", "type": "string" }, "until": { "description": "ISO date/time upper bound", "type": "string" }, "worker_id": { "type": "string" }, "zone_id": { "type": "string" } }, "required": [], "type": "object" }, "name": "tascan_zone_compliance", "outputSchema": null } ] }
Verify it yourselfcurl -s https://api.teppi.xyz/v1/evidence/sha256:6b3a1db84ceecb6bd5bd236b983209bd51b5e5bd26c1784585305eb995075ce2 | sha256sum