Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Authorization not required, issuer https://app.tascan.io
Added "tascan_get_org" and "tascan_list_connectors"; changed the definition of "tascan_create_project", "tascan_list_projects" and "tascan_update_project" (106 tools before, 108 now)
Create a new TaScan project (top-level container for events). number is optional (the next P-number is assigned when omitted; a number already used in the org is refused 409). external_refs links customer job numbers.{"properties":{"external_refs":{"description":"Up to 10 external references, each { source (1-40 chars, e.g. \"EEQ\"), ref (1-80 chars, e.g. \"P14-4680\") }","items":{"properties":{"ref":{"type":"string"},"source":{"type":"string"}},"required":["source","ref"],"type":"object"},"type":"array"},"location":{"description":"Project location / venue","type":"string"},"name":{"description":"Project name","type":"string"},"number":{"description":"Project number, 1-40 letters, digits, dot, underscore or hyphen, unique in the org (default: next P-00001 style number). P-<digits> numbers are assigned automatically and refused 400 here; use your own format (e.g. P14-4680)","type":"string"}},"required": ⟨3 unchanged words⟩
ListallTaScan projects in the organization (each with its number, e.g. P-00001, and external_refs). Optional filters: status (exact, comma list), number (exact) and ref (matches any external_refs[].ref exactly, e.g. a customer job number like P14-4680).
{"properties":{"number":{"description":"Only the project with this project number (exact, e.g. P-00012)","type":"string"},"ref":{"description":"Only projects whose external_refs carry this ref (exact, e.g. P14-4680)","type":"string"},"status":{"description":"Only projects with this status (exact; comma-separated list allowed, e.g. \"active,archived\")","type":"string"}},"type":"object"}
Update a project (name, location, status, dates, number, external_refs). A number already used in the org is refused 409; external_refs replaces the whole list.
⟨5 unchanged words⟩ (ISO)","type":"string"},"external_refs":{"description":"The full list of external references (replaces the current one): up to 10 { source (1-40 chars), ref (1-80 chars) }","items":{"properties":{"ref":{"type":"string"},"source":{"type":"string"}},"required":["source","ref"],"type":"object"},"type":"array"},"location":{"description":"New location","type":"string"},"name":{"description":"New name","type":"string"},"number":{"description":"New project number, 1-40 letters, digits, dot, underscore or hyphen, unique in the org. A P-<digits> number is refused 400 unless it is the project's current number","type":"string"},"project_id":{ ⟨24 unchanged words⟩
Read the organization profile (GET /org): id, name, industry, logo, time zone and the admin phone MASKED to its last 4 digits (a tool never sees the full number). Read tier. Editing the organization is done by an owner or admin in the TaScan portal, not by any tool.
List the organization's connectors (GET /integrations), e.g. the Salesforce Work Order bridge: provider, instance URL, the project and list new work lands on (with names), whether it is on, the last poll time and the last error. Never shows secrets: the client id, the client secret, its storage name and the connector config are never returned. Read tier. Turning a connector on or off, retargeting it or adding one is done by an owner or admin in the TaScan portal, not by any tool.
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Changed the definition of "tascan_delegate_to_agent"
{"properties":{"agent_id":{"description":"Stable agent id used in receipts and the agent registry.","type":"string"},"display_name":{"description":"Readable id for the agent, e.g. \"LT-ZOOS-RSCH-02 · Zoos · Researcher 02\".","type":"string"},"model":{"description":"The model the agent runs on, e.g. claude-sonnet-5-5.","type":"string"},"resource_constraints":{"description":"Optionalfree-formprojectnarrowingsandbox:(e.g.{project/list\"project_ids\":ids)[\"<projectrecordeduuid>\", ...] }. Enforced on every call (migration 249):
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Changed the definition of "tascan_add_tasks", "tascan_control_fanout", "tascan_create_fanout" and 3 more
⟨261 unchanged words⟩ \"signature\" = the worker reads a document, types their full name and signsitwith their passkey (Face ID / fingerprint); the name is signed with it (attach the document with signature_doc_base64 and signature_doc_mime) ⟨223 unchanged words⟩
⟨7 unchanged words⟩ . pause holds every unclaimed seat and stopsthe orphan pass from re-firing them;
Authorization not required, issuer https://app.tascan.io
Added "tascan_get_signature_bundle"; changed the definition of "tascan_add_tasks" and "tascan_update_task" (105 tools before, 106 now)
⟨254 unchanged words⟩ "file\" = the worker uploads a file. \"signature\" = the worker reads a document and signs it with their passkey (attach the document with signature_doc_base64 and signature_doc_mime). Most info-collection tasks should be \"text\", ⟨14 unchanged words⟩ ","choice","link","url","file","signature"],"type":"string"},"signature_doc_base64":{"description":"Only with response_type signature: the document to be signed, base64 (PDF, PNG or JPEG, at most 10 MB). Uploaded after the task is created. Needs signature_doc_mime.","type":"string"},"signature_doc_mime":{"description":"Media type of signature_doc_base64.","enum":["application/pdf","image/png","image/jpeg"],"type":"string"},"sort_order": ⟨150 unchanged words⟩
Changed the definition of "tascan_send_sms"
⟨27 unchanged words⟩ — the recipient gets a tap-to-open checklist link. Attach images (MMS) with media_url (public https image URL) or media_base64 + media_type (jpeg/png/gif, max 3.5 MB) — e.g. a diagram, a tutorial photo or a site photo; the message text is optional when an image is attached. Sends from TaScan's carrier-registered A2P number (or the ⟨28 unchanged words⟩
⟨97 unchanged words⟩ checklist link","type":"string"},"media_base64":{"description":"Optional image to attach (MMS) as base64 bytes (a data: URI prefix is accepted). JPEG, PNG or GIF, max 3.5 MB. Stored privately by TaScan and sent through a short-lived link.","type":"string"},"media_type":{"description":"MIME type of media_base64 (not needed when media_base64 is a data: URI).","enum":["image/jpeg","image/png","image/gif"],"type":"string"},"media_url":{"description":"Optional image to attach (MMS): a public https URL of a JPEG, PNG or GIF. The carrier fetches it at send time.","type":"string"},"message":{"description":"Message text. Transactional and ⟨35 unchanged words⟩
Authorization not required, issuer https://app.tascan.io
Added "tascan_quickstart" (104 tools before, 105 now)
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…
Added "tascan_claim_run", "tascan_finish_run" and "tascan_heartbeat_run"; changed the definition of "tascan_control_fanout" and "tascan_create_fanout" (101 tools before, 104 now)
⟨43 unchanged words⟩ synth barrier now instead of waiting for moreseats.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. ⟨65 unchanged words⟩
{"properties":{"action":{"description":"pause, resume, cancel, close_barrier orclose_barrier.retry_synth. No amend, no answer (phase 1).","enum":["pause","resume","cancel","close_barrier
Added "tascan_control_fanout", "tascan_create_fanout" and "tascan_get_fanout" (98 tools before, 101 now)
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. 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…
Create a fan-out: 1-30 RESEARCH 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). 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 …
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 foreig…
Added "tascan_delegate_to_agent", "tascan_get_budget", "tascan_get_device" and 5 more; changed the definition of "tascan_add_tasks", "tascan_request_payment" and "tascan_send_sms" (90 tools before, 98 now)
{"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) ⟨388 unchanged words⟩
⟨9 unchanged words⟩ 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"},"
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Changed the definition of "tascan_create_cycle" and "tascan_request_verification"
⟨23 unchanged words⟩ 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 ⟨72 unchanged words⟩ code. Duplicate protection: the same idempotency_key, or (keyless) the same briefs + paths on a live root, within 24 hreturns
Added "tascan_dispatcher_action", "tascan_evidence_policy", "tascan_get_build_diff" and 7 more (80 tools before, 90 now)
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 age…
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 (wr…
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 …
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Changed the definition of "tascan_add_subtasks", "tascan_add_tasks", "tascan_reply_with_list" and 2 more
⟨47 unchanged words⟩ " 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": ⟨39 unchanged words⟩
⟨176 unchanged words⟩ \"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.
Authorization not required, issuer https://app.tascan.io
Added "tascan_record_integration" (79 tools before, 80 now)
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 not…
Changed the definition of "tascan_create_zone" and "tascan_update_zone"
⟨15 unchanged words⟩ :"boolean"},"auto_clock_in":{"description":"EnteringWrites a shift_start when thezoneWORKERwritesPAGE, while open, sees the phone enter the zone; detection is pull-based, there is no background geofencing. For ashift_startbackground-freeclock-inpresence event use a gate NFC/QR scan.","type":"boolean"},"auto_clock_out":{"description":"LeavingWrites a shift_end when
Changed the definition of "tascan_create_cycle"
⟨128 unchanged words⟩ root instead of queueing again (created=false). 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.
⟨388 unchanged words⟩ 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
Authorization not required, issuer https://app.tascan.io
Added "tascan_cancel_scheduled_sms", "tascan_list_scheduled_sms", "tascan_project_digest" and 1 more; changed the definition of "tascan_create_cycle" (75 tools before, 79 now)
⟨291 unchanged words⟩ 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 ( ⟨75 unchanged words⟩
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.
Authorization not required, issuer https://app.tascan.io
Authorization not required, issuer https://app.tascan.io
Changed the definition of "tascan_get_build" and "tascan_get_build_file"
⟨72 unchanged words⟩ to read a file. Truncated at 12000 chars. Reading the manifest is discovery, not a read of any file.
⟨60 unchanged words⟩ 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.
Added "tascan_create_cycle", "tascan_get_build", "tascan_get_build_file" and 2 more; changed the definition of "tascan_complete_task" and "tascan_get_receipt" (70 tools before, 75 now)
Completeaan ORDINARY task on behalf of a worker. Inserts a ⟨8 unchanged words⟩ 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.
⟨100 unchanged words⟩ Changed the definition of "tascan_get_receipt"
⟨74 unchanged words⟩ recorded; verification.result = the verdict of a namedpolicy (policy_id/version/hash + verifier non-null together);policy; all-null verification with reason no_policy_run = no policyran, true of every agent task in v0.1.ran. Never treat outcome=completed as success without a policy verdict you trust (protocol 8.3 C11).VerifierEleven-step=verifiereleven(6.8).stepsprofile=public returns the separately signed public export profile (6.8protocol 6.10):
Certificate recorded, valid to 2026-12-06
Authorization not required, issuer https://app.tascan.io
Added "tascan_get_receipt"; changed the definition of "tascan_add_tasks", "tascan_dispatch_to_agent", "tascan_get_task" and 2 more (69 tools before, 70 now)
⟨40 unchanged words⟩ simple confirmations. NOTE: To dispatch tasks tothe ClaudeanCodeAI agentrunninguseontascan_dispatch_to_agentMike'sinstead.PC,Writinguseintotascan_dispatch_to_agentaninstead
First tool surface recorded: 69 tools (server version 3.11.0)
Showing the latest 39 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨12 unchanged words⟩ ) plus one synthesizer under ONE cycle rootT_F(POST /coord/fanouts).ZeroNo Decision cards,zeroParked cards,zeroor pages per seat--: only a control action or the closing roll-up reaches a human.RequiresNeeds an API key with agent:dispatch:code--(an admin session has no dispatch budget:(key_required). dry_run true runs the same validationplus theand ceiling/cap pre-check and returns{dry_run:true, plan_sha256, seats,and problems:[]}WITHOUTwithoutconsumingspending budget or creatinganything -- a real preflight, not a real create.anything. Otherwise it consumesseats.lengthseats + 1 dispatch units BEFORE theauthoritativecreate; a refusal only theRPCdatabase can see (cap_below_plan, fanout_open_limit, bad agent_id, reserve_floor_unset) still consumes them, by design. Failsclosedfanout_ceiling_unset until the owner sets aceiling;ceiling, over_ceiling when cap exceeds it. idempotency_key replays a duplicate within 24h on the same plan, else idempotency_body_mismatch.Leaves fanout_created; everyEvery seat, the synth and the roll-up leavetheir owna signed completion. Track with tascan_get_fanout.
⟨32 unchanged words⟩ offline without trusting TaScan: the signed challenge preimage (v 2 also carries the typed name the signer entered, signer_typed_name), clientDataJSON, authenticatorData, signature, public key, the ⟨6 unchanged words⟩ SHA-256, task id, completion id and time. Check it with: npx tascan-verify --signature bundle.json [--doc the-document.pdf]. Contains no signed URL, phone number or email. Read tier, organization-scoped.
⟨23 unchanged words⟩ . Optionally filter to a comma-separated set ofkinds.kinds, and with since=<ISO time> read only messages newer than the last one you saw. Read tier. Post with tascan_post_message.
⟨20 unchanged words⟩ accepted).","type":"string"},"since":{"description":"Optional ISO 8601 time: return only messages created after it (pass the created_at of the last message you saw to read only new ones).","type":"string"},"task_id":{"description":"Task ID (UUID) ⟨7 unchanged words⟩
Listallthe tasks in an event (task list). status "open" returns only tasks with no completion yet: use it when checking for work to do, so a long list is not re-read in full. "done" returns only completed tasks; "all" (default) returns every task.
⟨5 unchanged words⟩ (event) ID","type":"string"},"status":{"description":"open = not completed yet (use this to find work), done = completed, all = everything (default).","enum":["open","done","all"],"type":"string"}},"required":["list_id"],"type":"object"}
Fetch the signature bundle for one signed document by signature assertion id (the signature_assertion_id inside the response value of a completed signature task). Returns the self-contained JSON an auditor can verify offline without trusting TaScan: the signed challenge preimage, clientDataJSON, authenticatorData, signature, public key, the user-verification and backup flags, the document SHA-256, task id, completion id and time. Contains no signed URL, phone number or email. Read tier, organization-scoped.
Create a fan-out: 1-30 seats (RESEARCH by default, or LOCAL subagent seats) plus one synthesizer under ONE cycle root T_F ⟨36 unchanged words⟩ session has no dispatch budget (key_required).Consumesdry_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 ⟨35 unchanged words⟩ within 24h on the same plan, else idempotency_body_mismatch.dry_run is forwarded as-is; the route has no preflight mode yet, so dry_run true still creates for real -- never a way to avoid creating.Leaves fanout_created; every seat, the synth and ⟨10 unchanged words⟩
⟨98 unchanged words⟩ :"integer"},"dry_run":{"description":"ForwardedtruetorunsPOSTthe/coord/fanoutssameasvalidationgiven.plusThetherouteceiling/caphaspre-checknoandserver-sidereturnspreflight{dry_run:true,forplan_sha256,thisseats,pathproblems:[]}today,WITHOUTsoconsumingtruebudgetstillorperformscreating aREAL createfan-out --do not rely on itatorealavoidpreflight,creatingnot afan-out.real create.","type":"boolean"},"idempotency_key":{ ⟨255 unchanged words⟩ 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":[ ⟨106 unchanged words⟩
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 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 th…
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.
{"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 ⟨96 unchanged words⟩
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 …
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.
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.
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.
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.
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.
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.
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).
{"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 ⟨119 unchanged words⟩ <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 hreturnsistherefusedexistingascycleidempotency_replay (created=falsenothing queued)insteadandofprinted as DUPLICATE with the existing root_id — safe to retry after aduplicatelostdispatch.answer.","type":"string"},"integrate_description":{ ⟨22 unchanged words⟩ <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 ⟨406 unchanged words⟩ :"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":{ ⟨5 unchanged words⟩ chars). T1 becomes \"CODE: <title>\" (\"CAPTURE: <title>\" when kind=review_only), T2 \"REVIEW: <title>\".","type ⟨9 unchanged words⟩
{"destructiveHint":false,"idempotentHint":truefalse,"openWorldHint":true,"readOnlyHint":false,"title":"Request Verification"}
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.
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.
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.
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.
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.
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.
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 i…
⟨50 unchanged words⟩ " for info requests, \"choice\" needsresponse_config.optionsresponse_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": ⟨27 unchanged words⟩
⟨8 unchanged words⟩ {"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": ⟨15 unchanged words⟩
⟨105 unchanged words⟩ for visual proof, \"checkbox\" for yes/noonly.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": ⟨21 unchanged words⟩
⟨2 unchanged words⟩ {"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 ⟨105 unchanged words⟩
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.
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.
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 …
⟨29 unchanged words⟩ separately signed public export profile: no raw org,idlist,workerproject,idworker, runidor trace id (each is a 16-hex id_hash), no storage locators, plus a binding to the full receipt ⟨23 unchanged words⟩
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. 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 re…
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.
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 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; …
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:) b…
⟨8 unchanged words⟩ -> 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 id, worker id, run id or trace id (each is a 16-hex id_hash), 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"}
⟨18 unchanged words⟩ up and executed automatically. No list ID needed.SupportsREQUIRESprefixesthe 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:PLANREVIEW:for→routing.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 availableagents.agents; track progress with tascan_get_task (its "agent" block).
⟨10 unchanged words⟩ 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 taskdescription.text.PrefixSTART it with CODE: SHELL: PLAN: MCP: RESEARCH: WRITE:PLANor REVIEW: for routing (prefix-only — nothing may precede it), orjustleaveplainittext.unprefixed (DEFAULT). The whole text is stored in the task description; the first 140 chars become the title.","type":"string"}},"required": ⟨3 unchanged words⟩
⟨28 unchanged words⟩ 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).
⟨20 unchanged words⟩ 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.
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:.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 (policy_id/version/hash + verifier non-…