起動済みのClaude／Codex／Grok／Composer／Cursor agent sessionを再起動せず、会話contextを保ったままmodel／reasoning effortを変更する。各harnessのCLI標準model操作を使う。Cursorのreasoning_effort変更はmodelと同時指定する。

変更後のmodel。省略時はmodelを変更しない

変更後のreasoning effort。省略時はeffortを変更しない

claude-code codex-cli grok-cli cursor-cli

schema session_id provider harness model reasoning_effort

エージェントを単一の標準入口から永続sessionへ起動する。harnessはagent loop・認証・hook・transcriptを所有する実行基盤、modelはそのharnessが選ぶ推論モデルであり別軸。Cursor harnessからGPT／Claude／Grok等を選んでも完了相関はCursor方式のまま。Grok Composerは別harnessではなく harness=grok-cli と model=grok-composer-2.5-fast で指定する。通常CLIと同じHOME・cwd・project/user/local設定・MCP・plugin・skill・permission/trustを共有する。aitermは完了相関stateだけをlaunch単位で所有する。起動されたagentにはsub-agent自己認識、親session、delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。起動して投げたら投げっぱなしでよい＝親はここで待たない。完了通知は起動応答またはpty_send dispatch receiptの wait_processを、親のターンを塞がない別プロセスAPIへexecutable／argsの境界を保ったまま渡して受ける（PowerShell 7のStart-Processはwindows_start_process_argument_listを使う）（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要・foreground実行はしない）。wait_commandは人間向け互換表示。結果回収は pty_read(agent_transcript:true)。

作業ディレクトリ（絶対パス・任意）

現在のMCP processから継承する環境変数名

agent loop・session・hook・transcript・認証を所有する実行基盤

Claude Codeのpromptなしexact replay相関だけで使用

harnessが選ぶモデル。provider名ではなくlive catalog上のmodel ID

起動時に渡す初手プロンプト（任意）。送信後は待たずに即返る

harness adapterが標準CLI表現へ変換する思考レベル。Cursorではmodel同時指定が必要

Aiterm session名（省略で自動採番）

同一端末のThroughline sessionから読み取り専用contextを初手へ注入する

Throughline 0.10.8以降へそのまま渡すproject束縛済み長期記憶・知識の補足JSON path

能力宣言。read-onlyは対応harnessの標準read-only面で実効禁止する

旧互換field。新規連携はharnessを使う

実行中のCodex/Grok agentへ追加メッセージを差し込み、現在のターンを誘導する。独立した次ターンを始める用途ではなく、idle時は文字を送らずdelivery=idleを返す。

現在のターンへ追加する文字列。UTF-8で最大64KiB

schema session_id launch_id vendor harness delivery

【旧互換alias。新規連携は agent_launch(harness=claude-code)】Claude Codeの対話エージェントTUIを永続端末に起動する。`claude -p`ではなく、同じ利用者可視sessionへpty_sendで継続入力する。通常CLIと同じHOME・cwd・project/user/local設定・MCP・plugin・skill・permission/trustを共有する。aitermは完了相関stateだけをlaunch単位で所有する。起動されたagentにはsub-agent自己認識、親session、delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。通常settingsへlaunch固有Stop hook settingsを加算する。起動前に共有認証を構造化確認し、未認証ならsessionを作らない。起動して投げたら投げっぱなしでよい＝親はここで待たない。完了通知は起動応答またはpty_send dispatch receiptの wait_processを、親のターンを塞がない別プロセスAPIへexecutable／argsの境界を保ったまま渡して受ける（PowerShell 7のStart-Processはwindows_start_process_argument_listを使う）（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要・foreground実行はしない）。wait_commandは人間向け互換表示。結果回収は pty_read(agent_transcript:true)。Claude の durable turn は claude_turn でも回収できる。

作業ディレクトリ（対象リポのルート等・任意）

起動したagentへ現在のMCP processから継承する環境変数名。値はtool引数へ渡さない

promptなしClaude launchのexact replay相関ID。session_name必須

起動モデル（例: claude-sonnet-4-6）。省略時はClaude CLI既定

起動時に渡す初手プロンプト（任意）。送信後は待たずに即返る

Claude Code reasoning effort。low/medium/high/xhigh/max。省略時はCLI既定

セッション名（省略で自動採番）

同一端末のThroughline sessionから所有権を変えずに記憶を読み、promptのmissionより前へ注入する

後方互換field。trueはaiterm完了相関が有効という意味で、project/user環境の隔離を意味しない

aiterm相関付きClaudeのactive turn中に表示された権限確認UIを、turn相関を保ったまま検査・応答する専用面。inspectで画面digestと安全な単発Yes/Noだけを取得し、respondは同じoperation・同じdigestが現在も表示中の場合だけ送信する。

respondだけに指定する

直前のinspectが返したdigest。respondだけに指定する

durable operationのID。通常pty_send由来の匿名turnでは省略する

aiterm相関付きClaude sessionのdurable operationを構造化issue／recoverするmachine-caller専用面。pending／unknown／completedを人間向けerror文字列の解析なしで返し、Observer固有ロジックは持たない。

issueだけに指定するbounded turn本文

【旧互換alias。新規連携は agent_launch(harness=codex-cli)】Codexの対話エージェント TUI を永続端末に起動する。実装・レビュー・調査を対話で回す。通常CLIと同じHOME・cwd・project/user/local設定・MCP・plugin・skill・permission/trustを共有する。aitermは完了相関stateだけをlaunch単位で所有する。起動されたagentにはsub-agent自己認識、親session、delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。委譲契約を使う完全な呼び出し例: `codex_agent({"prompt":"<依頼>","model":"gpt-5.6-sol","reasoning_effort":"high","cwd":"/absolute/path/to/repo","write_scope":"read-only"})`。turn は pty_send で送る（自動で非ブロック dispatch になる）。起動して投げたら投げっぱなしでよい＝親はここで待たない。完了通知は起動応答またはpty_send dispatch receiptの wait_processを、親のターンを塞がない別プロセスAPIへexecutable／argsの境界を保ったまま渡して受ける（PowerShell 7のStart-Processはwindows_start_process_argument_listを使う）（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要・foreground実行はしない）。wait_commandは人間向け互換表示。結果回収は pty_read(agent_transcript:true)。model / reasoning_effort を引数で指定可（省略時は端末 config／CLI 既定を継承。実効値は起動応答に明示）。

作業ディレクトリ（対象リポのルート等・任意）

起動モデル（例: gpt-5.6-sol / gpt-5.6-terra / gpt-5.6-luna）。省略時は端末 config／CLI 既定を継承（端末側のピンがそのまま効く。実効値は起動応答に明示される）

起動時に渡す初手プロンプト（任意）。送信後は待たずに即返る

reasoning effort（思考レベル）。low/medium/high/xhigh/max/ultra（CLI／model 版依存）。ultra は max 推論＋proactive 自動委譲 ON＝使用量急増注意（明示要求時のみ）。省略時は端末 config／CLI 既定。

セッション名（省略で自動採番）

能力宣言。read-only、または書込みを許可するパスの説明文字列。対応harnessのread-onlyはCLI標準のread-only面で実効禁止する

【旧互換alias。新規連携は agent_launch(harness=grok-cli, model=grok-composer-2.5-fast)】Grok BuildのComposerモデルを永続端末に起動する。通常CLIと同じHOME・cwd・project/user/local設定・MCP・plugin・skill・permission/trustを共有する。aitermは完了相関stateだけをlaunch単位で所有する。起動されたagentにはsub-agent自己認識、親session、delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。turn は pty_send で送る（自動で非ブロック dispatch になる）。起動して投げたら投げっぱなしでよい＝親はここで待たない。完了通知は起動応答またはpty_send dispatch receiptの wait_processを、親のターンを塞がない別プロセスAPIへexecutable／argsの境界を保ったまま渡して受ける（PowerShell 7のStart-Processはwindows_start_process_argument_listを使う）（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要・foreground実行はしない）。wait_commandは人間向け互換表示。結果回収は pty_read(agent_transcript:true)。model／reasoning_effortを引数で指定可。live catalogにComposer modelがなければGrokへfallbackせず明示エラー。read-only sandboxとagent_configureに対応。

作業ディレクトリ（対象リポのルート等・任意）

起動モデル。省略時は grok-composer-2.5-fast。既定／explicit modelを起動前にlive catalogへ照合し、不在ならfallbackせずエラー

起動時に渡す初手プロンプト（任意）。送信後は待たずに即返る

Grok Build reasoning effort。利用可能値はCLI／modelのlive catalogに従う。省略時はCLI／model既定。

セッション名（省略で自動採番）

diagnostics

Factory 向け read-only 診断。安全な状態語彙だけを機械可読 JSON で返す（PTY 内容・認証情報・path・環境値は返さない）。

【旧互換alias。新規連携は agent_launch(harness=grok-cli)】Grok BuildのGrokモデル（既定 grok-4.6）の対話エージェント TUIを永続端末に起動する。通常CLIと同じHOME・cwd・project/user/local設定・MCP・plugin・skill・permission/trustを共有する。aitermは完了相関stateだけをlaunch単位で所有する。起動されたagentにはsub-agent自己認識、親session、delegation depth/lineage、delegation_allowed=trueを注入し、必要な追加委譲は許可する。turn は pty_send で送る（自動で非ブロック dispatch になる）。起動して投げたら投げっぱなしでよい＝親はここで待たない。完了通知は起動応答またはpty_send dispatch receiptの wait_processを、親のターンを塞がない別プロセスAPIへexecutable／argsの境界を保ったまま渡して受ける（PowerShell 7のStart-Processはwindows_start_process_argument_listを使う）（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要・foreground実行はしない）。wait_commandは人間向け互換表示。結果回収は pty_read(agent_transcript:true)。model／reasoning_effortを引数で指定可。read-only sandboxとagent_configureに対応。

作業ディレクトリ（対象リポのルート等・任意）

起動モデル。省略時は grok-4.6。explicit modelを起動前にlive catalogへ照合し、不在ならfallbackせずエラー

起動時に渡す初手プロンプト（任意）。送信後は待たずに即返る

セッション名（省略で自動採番）

セッションを閉じ、ログ／読取位置を破棄する。同じsession_idへの再試行は安全で、closed／already_closedのstructured receiptを返す。

制御キーを送る（C-c, C-d, Enter, Tab, Up, Down... の別名に対応）。aiterm相関付きClaude sessionではturn相関を守るためC-cだけを許可し、承認UIはclaude_approvalで操作する。

キー名（例 "C-c", "Enter", "Up"）

握っているセッション一覧（名前 / 現在の前面コマンド / attach 状態 / サイズ / agent 情報）。

ローカル永続端末（POSIXはtmux、Windows nativeはpsmux 3.3.8以上）を1個開き、session_id を返す。backend server常駐ゆえ本サーバや クライアントが再起動してもセッションは生存する。リモート操作は専用ツールにせず、開いた端末の中で pty_send(session_id, "ssh host") と打って入る。

セッション名（省略時は t1, t2... を自動採番）

起動シェル（既定 bash）

セッションの出力をトークン削減して読む（既定は前回読取位置からの増分）。削減: 制御文字除去 / 反復圧縮 / head+tail 折りたたみ＋復元ヒント＋メタ併記。agent_transcript:true は agent session の直近完了ターンの最終 assistant メッセージを公開されたharness記録から平文で返す。長い回答が screen tail で切れた時の回収用。

agent session の直近完了ターンの最終 assistant メッセージを返す。Claudeはlaunch相関付きStop hook result、他harnessは通常transcript／session historyを使う。長い回答がscreen tailで切れた時の回収用

増分でなく全文

全文からの行範囲 "A:B"

末尾 N 行のみ

Claude operationの期待ID。agent_transcript:true時だけ指定し、古い別operationの結果を拒否する

削減せず生テキスト

直前コマンド別の自前 reducer(git/grep/pytest 等)で縮約

描画済みスクリーン(TUI 向け)

wait の最大待ち秒数

この文字列が出たら完了とみなす（既定はリテラル部分一致。`$ ` や `[..]` もそのまま探せる）

until を正規表現として扱う（既定 false＝リテラル部分一致。メタ文字を使いたい時のみ true）

完了まで待つ（dead / mark sentinel 自動検出 / until / 出力静止∧シェル復帰 / timeout）

セッションへテキストを送る。通常PTYへは送信のみ（出力は pty_read で取得）。agent session（launcher起動）への send は自動で dispatch になる: TUI の ready gate と submit 分離を通して即返り、receipt の event_cursor を返す。dispatch した子は投げっぱなしでよい＝親はここで待たない。完了通知はreceiptの `wait_process.executable` と `wait_process.args` をそのまま親のターンを塞がない別プロセスAPIへ渡して受け、PowerShell 7のStart-Processだけは `windows_start_process_argument_list` を単一文字列として渡す。exit を完了通知として扱う（exit 0=done / 3=timeout（既定600秒・未完了） / 4=closed。receiptのoutcomeが正で、done以外は未完了。ポーリング不要）。`wait_command` は人間向け互換表示でありprocess境界へ使わない。foreground実行で親のターンを塞がない。結果回収は pty_read(agent_transcript:true)、Claude の durable turn は claude_turn を使う。force:true は非Claude agent sessionへの手動介入用の素送信。aiterm相関付きClaudeの承認UIはclaude_approvalを使う。

末尾で Enter を送る（agent dispatch では常に submit）

非Claude agent sessionでは自動dispatchせず素送信する。aiterm相関付きClaudeのactive turnには使えない

完了 sentinel(終了コード付き)で包む。pty_read(wait:true) が until 無しでも自動検出して完了確定する（POSIX shell と PowerShell に対応。PowerShell の rc は成功0／失敗1。fish/csh/tcsh は未対応として送信前に拒否）。 enter:false と併用すると sentinel が実行されず完了検出が発火しない（送信後に pty_key("Enter") で実行される）。

送信前サニタイズを無効化

既知コマンドを rtk 形へ委譲して送る（rtk 不在なら素通し）

送る文字列（コマンド／prompt）。UTF-8で最大64KiB


Notion Describe

Return the JSON Schema and a working example for one operation, plus which tool runs it (notion_read or notion_write). Use this BEFORE calling the operation when the payload shape is non-trivial (query filters, structured block trees, database property definitions). For simple ops, just call it — errors carry the schema.

Operation name to describe, as listed by notion_read / notion_write.

Notion Describe

Notion Read

Run one Notion read operation by name. Nothing is modified.

Call: { operation, payload } — payload carries that operation's fields. Common: search_pages { query }, get_page { page_id }, get_page_markdown { page_id }, query_database { database_id, where? }, get_block_children { block_id }.

Responses are slimmed; pass verbose:true in payload for the raw Notion object. Every id field (page_id, block_id, database_id, view_id, …) also accepts a Notion URL, as copied from Share → Copy link. A block link's #fragment is used for block_id fields and a database link's ?v= for view_id fields.

If the payload is malformed, the error response includes the schema + a working example so you can correct and retry in one round-trip. Call notion_describe(operation) ahead of time only for complex shapes (query_database filters).

The read operation to run. This list is the complete menu of read operations enabled on this server; notion_describe(operation) returns any operation's full schema.

Operation parameters. Pass either single-op fields directly, or { items: [...], atomic?, idempotency_key?, concurrency? } for batch.

Notion Read

Notion Write

Run one Notion write operation by name. Archive, trash and delete operations remove content — confirm with the user before running them.

Two ways to call:
  • Single: { operation: "set_page_title", payload: { page_id, title } }
  • Batch:  { operation: "set_page_title", payload: { items: [{page_id, title}, ...], atomic?: false, idempotency_key?: "...", concurrency?: 3 } }
create_page, append_blocks, update_block and update_page_markdown also take a markdown string.

Responses are slimmed; pass verbose:true inside payload (single) or per item (batch) for the raw Notion object. Every id field (page_id, block_id, database_id, view_id, …) also accepts a Notion URL, as copied from Share → Copy link.

If the payload is malformed, the error response includes the schema + a working example so you can correct and retry in one round-trip. Call notion_describe(operation) ahead of time only for complex shapes (block trees, database property definitions, batch_mixed_blocks).

The write operation to run. This list is the complete menu of write operations enabled on this server; notion_describe(operation) returns any operation's full schema.

Notion Write


Authenticate with A-Team. Required before any tenant-aware operation (reading solutions, deploying, testing, etc.). The user can get their API key at https://mcp.ateam-ai.com/get-api-key. Only global endpoints (spec, examples, validate) work without auth. IMPORTANT: Even if environment variables (ADAS_API_KEY) are configured, you MUST call ateam_auth explicitly — env vars alone are not sufficient. For cross-tenant admin operations, use master_key instead of api_key.

Your A-Team API key (e.g., adas_xxxxx)

Master key for cross-tenant operations. Authenticates across ALL tenants without per-tenant API keys. Requires tenant parameter.

Tenant name (e.g., dev, main). Optional with api_key if format is adas_<tenant>_<hex>. REQUIRED with master_key.

Optional API URL override (e.g., https://dev-api.ateam-ai.com). Use this to target a different environment without restarting the MCP server.

REQUIRED onboarding entrypoint for A-Team MCP. MUST be called when user greets, says hi, asks what this is, asks for help, explores capabilities, or when MCP is first connected. Returns platform explanation, example solutions, and assistant behavior instructions. Do NOT improvise an introduction — call this tool instead.

DEPLOY THE CURRENT MAIN BRANCH TO A-TEAM CORE. ⚠ HEAVIEST OPERATION (60-180s): validates solution+skills → deploys all connectors+skills to Core (regenerates MCP servers) → health-checks → optionally runs a warm test → auto-pushes to GitHub.

🌳 DEV/PROD WORKFLOW:
  1. Edit files → ateam_github_patch (writes to `dev` branch by default)
  2. (Optional) Preview what's about to ship → ateam_github_diff
  3. Ship dev → main → ateam_github_promote (merges + auto-tags `prod-YYYY-MM-DD-NNN`)
  4. Deploy main to Core → ateam_build_and_run

This tool ALWAYS deploys the `main` branch — there is no `ref` parameter. To deploy in-progress dev work, first promote it.

AUTO-DETECTS GitHub repo: if you omit mcp_store and a repo exists, connector code is pulled from main automatically. First deploy requires mcp_store. After that, edit via ateam_github_patch + promote, then build_and_run. For small changes prefer ateam_patch (faster, incremental). Requires authentication.

Optional: connector metadata (id, name, transport). Entry points auto-detected from mcp_store.

Optional: if true, pull connector source code from main. AUTO-DETECTED: if you omit both mcp_store and github, the system checks if a repo exists and pulls from main automatically.

Optional: connector source code files. Key = connector id, value = array of {path, content}.

Optional after first deploy: skill definitions. If omitted, auto-pulled from main (skills/{id}/skill.json).

Full solution definition. Required on first deploy. After first deploy, just pass solution_id instead — everything is auto-pulled from GitHub main.

The solution ID. Use this INSTEAD of passing the full solution object — the solution definition is auto-pulled from main. Required if solution object is omitted.

Optional: send a test message after deployment to verify the skill works. Returns the full execution result.

Optional: which skill to test (defaults to the first skill).

SLIM chain status — the chip-quick poll. Given a chain_id (from ateam_conversation), returns the WHOLE-CHAIN aggregate status cheaply: chain_status + chain_done (true only when the ENTIRE chain — root job + every handoff + askAnySkill subcall — is terminal), plus pending_question, result, and a short progress line.

This is what you poll on a loop after ateam_conversation — NOT ateam_get_chain (that returns the full tree; too heavy for periodic polling). A single job can finish while the chain is still running, so poll chain_done, not a job's status.

Loop: call every ~2s until chain_done === true (or pending_question is set — the assistant is waiting on the user). Then read `result` / fetch the full tree once via ateam_get_chain if you need per-job detail.

Optional. WHO is asking. A job belongs to an actor and Core enforces that on per-job reads, so a tenant key alone is refused. Usually unnecessary — the session remembers the actor from ateam_conversation/ateam_test_skill. Pass it to inspect a job run by a DIFFERENT actor (e.g. a real user's).

The chain id returned by ateam_conversation (the conversation's identity). Any job id in the chain also works — Core resolves the chain aggregate.

Alias for chain_id — any job in the chain resolves to the chain aggregate. The handler has always accepted it; without this declaration MCP stripped it before the handler could see it.

Returns last_activity_at / idle_seconds / activity_source. A LARGE idle_seconds does NOT mean dead — on this platform a healthy build sits minutes inside a single provider call. Read activity_source (what it was doing) with it; never apply an 'idle > N ⇒ dead' rule.

Output: bounded

Read what a connector process actually PRINTED to stderr. This is the only place a connector's internal failure is visible: a tool that catches its own error still returns ok:true, and the widget then renders an empty state that looks like real data.

Real case (2026-08-11): a dashboard connector's ledger.getData got 401 Authentication required from Core, swallowed it, returned an empty ledger, and displayed 0.00 everywhere — while the upload said ok, the tool said ok:true, and the surface probe said surface_ok. The word 'Authentication' appeared ONLY here.

USE IT whenever a tool succeeds but the data is empty, wrong, or zero — that combination is the signature of a swallowed error, and 'the call returned ok' is not evidence it worked. Pass the returned `cursor` back as `since` to read only what is new since your last look, so you can bracket an action and see exactly what it printed. Only stdio (solution) connectors stream stderr through Core; a platform/HTTP connector answers ok:false with a reason.

The connector ID (e.g. 'accounting-dashboard-mcp')

Keep only lines that read as errors (401/failed/exception/refused/…)

Max lines (default 100, max 300)

Cursor from a previous call — returns only lines printed after it. Omit for the whole retained tail.

The solution ID

Output: bounded

Send a chat message to a deployed solution. No skill_id needed — the system auto-routes to the right skill.

ALWAYS ASYNC: returns a chain_id immediately — the assistant's reply is NOT in this response (a conversation can run for minutes across handoffs + subcalls, so a synchronous wait would hit the 100s edge timeout → 524).

POLL BY CHAIN, NEVER BY JOB: an individual job can terminate while the chain is still running, so poll ateam_chain_status(chain_id) on a loop (~2s) and stop when chain_done === true (or pending_question is set — the assistant is waiting on the user). That is the cheap chip-quick poll (Core's whole-chain computeChainStatus — the same thing the standard chat uses). Use ateam_get_chain(chain_id) only ONCE at the end if you want the full tree / per-job detail — it's too heavy to loop on.

Multi-turn: pass the actor_id from a previous response back in to continue the same thread (e.g. reply to a confirmation prompt). Each call starts a new chain; the same actor_id maintains conversation context.

Optional: actor ID from a previous response to continue the conversation. Omit for a new conversation.

The message to send (e.g., 'send email to X' or 'I confirm')

The solution ID

Scaffold a new MCP connector with server.js + package.json + README. Eliminates ~50% of identical boilerplate (MCP server setup, tool registration, stdio transport). You then fill in the tool implementations. Set ui_capable=true to include ui.listPlugins / ui.getPlugin stubs (plugin source files added separately via ateam_create_plugin). After scaffolding, the files are uploaded to Core via the same path as ateam_upload_connector.

Connector ID (lowercase-with-dashes, no spaces). Becomes the directory name.

Human-readable name for the connector (e.g. 'Hue Lights'). Defaults to connector_id.

The solution ID

If true, include ui.listPlugins/ui.getPlugin handler stubs. Default: false.

Scaffold a UI plugin (iframe HTML, React Native TSX, or both) inside an existing connector. Eliminates ~50% of identical plugin boilerplate (imports, theme/bridge hooks, postMessage protocol, default export shape). You then fill in the component body. Use kind='iframe' for web-only, 'rn' for mobile-only, 'adaptive' for both. Also writes ui-dist/<plugin>/manifest.json with the required render block.

⚠ RENDERING IS NOT AUTOMATIC. At deploy, Phase 5 discovers plugins by calling each connector's ui.listPlugins + ui.getPlugin — a plugin only appears (and renders) if the connector ADVERTISES it there with a render.{mode, iframeUrl?, reactNative?} block. Dropping the scaffold files alone does NOT register it. If the connector generates its plugin list from ui-dist/<plugin>/manifest.json, the emitted manifest is picked up automatically; if the connector has a HARDCODED list (e.g. personal-assistant-ui-mcp: UI_PLUGINS[] + PLUGIN_MANIFESTS{} in server.js), you MUST add this plugin there (copy the render block from the manifest.json). Verify after deploy with ateam_get_solution(solution_id, 'connectors_health') or ateam_get_widget_catalog. Then declare it at solution ui_plugins[] so a skill can open it via sys.focusUiPlugin (see ateam_get_spec topic:'widgets').

The scaffold MERGES into the existing connector (server.js + other files preserved) — works on GitHub-backed AND repo-less tenants; merge base is the GitHub repo when connected, else the deployed connector source.

Existing connector to add the plugin into (e.g. 'personal-assistant-ui-mcp')

Render mode. 'adaptive' (default) produces both iframe + RN scaffolds.

Plugin name (lowercase-with-dashes). E.g. 'memories-panel'. Becomes the dir name.

The solution ID

⚠ CASCADING — any skill whose engine.bootstrap_tools or tools[] name a tool from this connector will FAIL its next execution. Stops and deletes the connector from A-Team Core; drops references from the solution definition (grants, platform_connectors, ui_plugins ids starting `mcp:<connector-id>:*`) and skill definitions (connectors array); cleans up mcp-store files. ALSO REMOVES THE SOURCE: `connectors/<id>/` is deleted from the repo (main AND dev) in the same call, so the delete is DURABLE. This CHANGED on 2026-08-23 — it used to preserve the source and name `ateam_build_and_run(github:true)` as a way to resurrect. That made a delete undo itself on a later publish, and only in some states, since connectors[] is synthesized from mcp_store keys ONLY when it is empty. If you want the code kept, copy it out (ateam_get_connector_source) BEFORE deleting. If the repo removal fails the response says so under `github` — Core is clean but the source is still there. REQUIRES `confirm:true`.

REQUIRED. Must be exactly true. A missing/false value refuses the call with a recovery hint.

The connector ID to remove (e.g. 'device-mock-mcp')

The solution ID (e.g. 'smart-home-assistant')

⚠ IRREVERSIBLE in Core + Builder FS — kills the running MCP process, unregisters from skill registry, deletes the Mongo record, drops from solution.skills[] and solution.linked_skills, and removes the skill's files from Builder FS. REQUIRES `confirm:true`. RECOVERY: the skill still lives in GitHub — `ateam_github_pull` rebuilds the whole solution (no per-skill restore path).

The skill ID to remove (e.g. 'linkedin-agent')

The solution ID (e.g. 'personal-adas')

⚠ IRREVERSIBLE — kills Mongo state, running MCP processes, and Builder FS for the whole solution and every skill. REQUIRES `confirm:true` AND `confirm_solution_id` echoing the solution id you're destroying (defeats typos and hallucinated ids). RECOVERY: the GitHub repo is untouched; `ateam_github_pull` rebuilds the solution from `main`. Prefer that over re-deploying from memory.

REQUIRED. Must exactly equal `solution_id`. This defeats typos and hallucinated ids — you can't wipe a solution you couldn't spell.

The solution ID to delete

CONSULT THIS DURING DESIGN — before and while you design a skill/solution. Describe what you're building; it returns POINTERS to the platform capabilities that fit (per-actor storage, widgets, triggers, sub-agents, mobile data, run-scripts, multi-skill, GitHub, …), each with the /spec topic to read next (via ateam_get_spec) and the tool to wire it. Also returns 'missing' hints (capabilities your goal implies but the design hasn't wired) and lifecycle hints (e.g. connect GitHub when the project will iterate). ADVISORY ONLY — you decide and own the design. Stateless: pass the current design_state each call; consult it as often as you like as the design evolves.

Optional. The design so far (skills, connectors, capabilities already wired) so the advisor can point at what's still missing. Pass {} at the start.

What you're trying to build, in your own words (e.g. 'a coach that tracks each user's meals from photos and shows a dashboard').

Output: bounded

Inspect the full chain tree — the whole run rooted at chain_id, walking down through every handoff and askAnySkill subcall.

Use when a chain has already run and you want to analyze the structure: which skill called which, how deep the call tree went, which tool inside which job invoked which sub-tool. The two main shapes:
  • response.data.chainJobs[] — one entry per job in the chain. Fields: jobId, skill, status, iteration, depth (0 = root, +1 per askAnySkill subcall hop), relation ('root' | 'subcall' | 'handoff'), parentJobId, parentSkill, goal.
  • response.data.executionSteps[] — every tool call across all chain jobs, tagged with _skill, _jobId, _depth (= job depth), _relation, _parentSkill, _parentJobId, _toolDepth (tool-in-tool nesting via opId/parentOpId).

Differs from ateam_test_status by purpose: status is for live polling of a job you just kicked off; get_chain is for post-hoc tree analysis (debugging multi-skill flows, regression testing, comparing two runs).

Auth: forwards your authed api_key. Tenant scoped by the key itself. Actor scoping: you can only inspect chains rooted at jobs your actor has access to.

THE EXECUTION'S IDENTITY — what ateam_conversation returns and what you actually hold. A chain is the whole run: root job + every handoff + every askAnySkill subcall. Prefer this.

Alias for chain_id. Any job inside the chain works — Core walks up to the root — but you rarely hold one; prefer chain_id.

Optional. The skill slug for the job — speeds up the lookup when the job isn't in memory and must be loaded from storage. Omit if you don't have it; lookup still works but does an extra round-trip.

Read the source code files of a deployed MCP connector. Returns all files (server.js, package.json, etc.) stored in the mcp_store for this connector. Use this BEFORE patching or rewriting a connector — always read the current code first so you can make surgical fixes instead of blind full rewrites.

The connector ID to read (e.g. 'home-assistant-mcp')

Optional. Read ONE file (e.g. 'server.js', 'ui-dist/panel/index.html'). Omit to get a file manifest (paths + sizes, no content) — a whole connector's source exceeds the ~50KB output limit and truncates, so read files one at a time.

Get complete working examples that pass validation. Study these before building your own.

Example type: 'skill' = Order Support Agent, 'connector' = stdio MCP connector, 'connector-ui' = UI-capable connector, 'solution' = full 3-skill e-commerce solution, 'script-cache-skill' = fat-tool skill with script_cache opt-in (reference implementation of script-level JIT shortcuts — study this before building any browser-automation skill), 'ui-plugin-native' = complete working React Native (mobile) UI plugin (rn-src/index.tsx + esbuild build:rn → rn-bundle, @adas/plugin-sdk, es2015), 'index' = list all available examples

skill connector connector-ui solution script-cache-skill ui-plugin-native index

Get execution logs for a solution — recent jobs with step traces, tool calls, errors, and timing. Essential for debugging what actually happened during skill execution. (Advanced.)

The actor whose job this is. REQUIRED for per-job detail: a job belongs to an actor and Core refuses the detail endpoint without one (the list form does not check). Use the same actor_id you passed to ateam_conversation.

The CHAIN id — what ateam_conversation returns and ateam_chain_status takes. Prefer this: it is the id you actually hold. Resolved to the underlying job for you.

Optional: get detailed trace for a specific job ID

Max jobs to return (default: 10, max: 50)

Optional: filter logs to a specific skill

The solution ID

Read what EARLIER runs on this solution learned — newest first, bounded. Call this during orientation, BEFORE planning: it is the only thing that carries context across runs, and it is cheap. Each entry says which tool misled a previous run, the verbatim error, what was tried instead, and whether that worked. An empty list is a real answer (nothing learned yet).

Max entries, newest first (default 20)

The solution ID

Get execution metrics — timing, tool stats, bottlenecks, signals, and recommendations. (Advanced.)

Optional: deep analysis for the job behind a CHAIN id — what ateam_conversation returns and what you actually hold. Resolved to the job for you.

Optional: deep analysis for a specific job

Optional: recent metrics for a specific skill

The solution ID

Output: bounded

What this build has already ACHIEVED — read it FIRST when continuing a run, before any orientation call. Returns the CURRENT status per step (latest entry wins) plus recent history.

Then build only the steps that are ABSENT or not yet `verified`.

ABSENT IS NOT "NOTHING WAS DONE" — the journal may predate a step, or a run may have died before writing. It is a fast path, not a new source of truth: check before rebuilding something expensive.

Complements ateam_get_lessons, which records what BROKE. This records what WORKS.

History entries to return (default 60). `steps` is always complete.

The solution ID

Read solution state — definition, skills, health, status, or export. Use this to inspect deployed solutions.

Optional byte-paging: max bytes of the serialized result to return in this page (pair with 'offset'). Omit both for the whole result (may truncate at the output cap).

Optional byte-paging: start returning the serialized result from this byte offset. Use with 'limit' to page a result larger than the ~50KB output cap; the response's _paging.next_offset gives the next page (null when done). Concatenate the `content` slices across pages, then JSON.parse.

Optional (with skill_id): return ONLY this section of the skill instead of the whole definition — avoids the ~50KB output truncation on big skills. Dotted paths work (e.g. 'role', 'tools', 'intents.supported', 'policy', 'engine'). Omit for the full skill; use ateam_show_skill_minimal for the slim authoring view.

Optional: read a specific skill by ID (original or internal)

The solution ID

What to read: 'definition' = full solution def, 'skills' = list skills, 'health' = live health check, 'status' = deploy status, 'export' = exportable bundle, 'validate' = re-validate from stored state, 'connectors_health' = connector status

definition skills health status export validate connectors_health

Get the A-Team specification — schemas, validation rules, system tools, agent guides, and templates. Start here after bootstrap to understand how to build skills and solutions. Use 'section' to get just one part of the skill spec (much smaller than the full spec). Use 'search' to find specific fields or concepts across the spec.

When designing a persona that orchestrates logic via run_python_script (the Python-as-orchestrator pattern), also fetch topic='python_helpers' — that returns the adas.* helper namespace reference. Skills designed without knowing about adas.* produce 5-10x larger / brittler scripts.

When wiring widgets (UI plugins) into a solution, fetch topic='widgets' — that returns the widget spec (catalog model, how_to_use blocks, opener_call shape, persona phrasing rules, binding semantics) so you can declare `ui_plugins` correctly. For the live catalog of widgets actually available in a deployed tenant, use ateam_get_widget_catalog instead.

Optional: filter the spec to only sections containing this search term. Works with any topic. Example: search='bootstrap' returns only fields/sections mentioning 'bootstrap'.

Optional: get just one section of the skill spec (only works with topic='skill'). Sections: 'engine' = model/reasoning/planner optimization/bootstrap tools, 'tools' = tool definitions/meta tools, 'intents' = intents/problem/scenarios, 'policy' = access control/grants/workflows, 'triggers' = automation triggers, 'connectors' = connector linking/channels, 'role' = persona/goals, 'template' = minimal quick start, 'guide' = build steps/common mistakes

engine tools intents policy triggers connectors role template guide

What to fetch: 'overview' = API overview + endpoints, 'skill' = full skill spec, 'solution' = full solution spec, 'enums' = all enum values, 'connector-multi-user' = multi-user connector guide, 'python_helpers' = adas.* helper namespace for run_python_script orchestration (read this when designing personas that read state → call tools → checkpoint → status; without it, scripts hand-roll JSON parsing and tool delegation = 5-10x larger and brittler), 'widgets' = widget (UI plugin) spec: catalog model, how_to_use block shape (solution.json snippet + opener_call + persona_phrasing + binding_notes), and rules for declaring ui_plugins. Pair with ateam_get_widget_catalog for the live per-tenant inventory. 'ui-plugins' = the DEEP React Native (mobile) plugin build guide: author in rn-src/, compile with a build:rn esbuild script (format=cjs, target=es2015, external react/react-native/@adas/plugin-sdk) to rn-bundle/index.bundle.js, plain-object export — read this before authoring any MOBILE widget. 'monitoring' = THE MONITORING CONTRACT: which tools are safe to call in a poll loop (with cost / poll interval / whether output stays bounded as the run grows), which are not and what to use instead, plus the running ateam-mcp version. Read this BEFORE writing any loop that watches a build — the safe poll is ateam_chain_status, never ateam_get_chain.

overview skill solution enums connector-multi-user python_helpers widgets ui-plugins actor-storage voice voice-native triggers sub-agent consumer-roles mobile-connector monitoring

Get the live catalog of widgets (UI plugins) available in this tenant's solution. Returns platform-bundled + solution-bundled + skill-declared widgets, each with a paste-ready how_to_use block (solution.json snippet + opener_call + persona_phrasing + binding_notes).

Use this when wiring widgets into a skill or solution — the how_to_use block is designed to be copied verbatim into the solution.json ui_plugins[] entry and into the persona's opener phrasing, so you don't have to hand-roll either. The catalog reflects what is actually deployed in the tenant right now, not the abstract spec (for the spec itself, use ateam_get_spec topic='widgets').

Origins:
  • 'platform' = widgets bundled with the platform (always available).
  • 'solution' = widgets bundled with this tenant's solution.
  • 'skill' = widgets declared by a specific skill in the solution.

Auth: forwards your authed api_key to Core (no master-secret involvement). Tenant scope is pinned by the key itself.

Optional. 'full' (default) returns each widget with its paste-ready how_to_use block (solution.json snippet, opener_call, persona_phrasing, binding_notes). 'summary' returns just id/name/origin/description for a quick overview.

Optional. If true, includes widgets that are available but not currently referenced by any skill or ui_plugins entry. Default false (only widgets actually wired into the solution).

Optional. Filter by widget origin. 'all' (default) returns everything. 'platform' = platform-bundled only. 'solution' = solution-bundled only. 'skill' = skill-declared only.

Optional. The solution to query. Defaults to the tenant's current solution.

Get the builder workflows — step-by-step state machines for building skills and solutions. Use this to guide users through the entire build process conversationally. Returns phases, what to ask, what to build, exit criteria, and tips for each stage.

PRE-FLIGHT BEFORE PROMOTE. Compares `dev` (head) vs `main` (base) by default — shows exactly which commits and files are about to ship if you call ateam_github_promote() next.

Use this when you want to:
  • Review changes before promoting to prod
  • See if dev is ahead of main at all (returns ahead_by: 0 if nothing to promote)
  • **Diagnose a failed promote** — check `behind_by` and `status`. `status: 'diverged'` (behind_by > 0) means main holds commits dev never received, which is what makes ateam_github_promote return 409 Merge conflict. ALWAYS call this after a promote failure, before reporting anything to the user.
  • Inspect arbitrary branch/tag/commit comparisons (override base/head)

Note: `files[]` lists what DIFFERS, not what conflicts. For solution.json and skills/*/skill.json the difference is often deploy-generated data (regenerated connector tools, timestamps) rather than authored change — see ateam_github_read's `_ateam_representation`.

Base branch/tag/sha (the target — what you're comparing TO). Default: 'main'.

Head branch/tag/sha (the source — what you're comparing FROM). Default: 'dev'.

The solution ID

List all available checkpoints (safe-* tags) for a solution. Shows tag name, date, counter, and commit SHA. Use before rollback to see available safe points.

The solution ID

View commit history for a solution's GitHub repo. Shows recent commits with messages, SHAs, timestamps, and links. Default reads from `main` (prod). Pass `ref: 'dev'` to see in-progress work.

Max commits to return (default: 10)

Branch to read commits from. Default: 'main'.

The solution ID

Edit a file in the solution's GitHub repo and commit. Two modes:
1. FULL FILE: provide `content` — replaces entire file (good for new files or small files)
2. SEARCH/REPLACE: provide `search` + `replace` — surgical edit without sending full file (preferred for large files like server.js)
Always use search/replace for large files (>5KB). Always read the file first with ateam_github_read to get the exact text to search for.

DEFAULTS TO `dev` BRANCH — writes don't touch prod. Use ateam_github_promote to ship dev→main when ready. Pass ref:'main' only for emergency hotfixes.

Branch to read/write (alias for `ref`). Declared so MCP does not strip it — an undeclared argument is dropped silently, which made a branch:"dev" read return `main` with no error.

The full file content to write (mode 1 — full file replacement)

Optional commit message (default: 'Update <path>')

File path to create/update (e.g. 'connectors/home-assistant-mcp/server.js')

Target branch. Default: 'dev' (safe — won't touch prod). Use 'main' only for emergency hotfixes.

Text to replace the search string with (mode 2 — required with search)

Exact text to find in the file (mode 2 — search/replace). Must match exactly including whitespace.

The solution ID

SHIP DEV TO PROD. Merges the `dev` branch into `main` and auto-tags the new main HEAD as safe-YYYY-MM-DD-NNN. Use after testing your dev work, when you're ready to deploy changes to production.

Workflow: 1) ateam_github_patch (writes to dev) → 2) ateam_github_promote (merges dev→main) → 3) ateam_build_and_run (deploys main).

Pass dry_run:true to see what's about to ship without merging.

ON 409 MERGE CONFLICT: main holds commits dev never received. Call ateam_github_sync_from_main(solution_id) to merge main into dev, then promote again. Only if THAT also returns 409 did both sides edit the same lines — that one needs a human (open a PR on GitHub).

If true: show the diff (commits + files about to ship) without merging. Default: false.

Optional: human-readable label for the auto-tag (e.g., 'v2 stable', 'before refactor')

If true: merge without creating an auto-tag. Default: false (auto-tag enabled).

The solution ID

Deploy a solution FROM its GitHub repo. Reads .ateam/export.json + connector source from the repo and feeds it into the deploy pipeline. Use this to restore a previous version or deploy from GitHub as the source of truth.

The solution ID to pull and deploy from GitHub

Push the current deployed solution to GitHub. Auto-creates the repo on first use. Commits the full bundle (solution + skills + connector source) atomically. Use after ateam_build_and_run to version your solution, or anytime you want to snapshot the current state.

Optional commit message (default: 'Deploy <solution_id>')

The solution ID (e.g. 'smart-home-assistant')

Read any file from a solution's GitHub repo. Returns the file content. Use this to read connector source code, skill definitions, or any versioned file. Default reads from `main` (deployed/prod state). Pass `ref: 'dev'` to read in-progress work.

⚠ NOT RUNTIME STATE. For `solution.json` and `skills/<id>/skill.json` this returns a git MIRROR, not what is deployed. Connector-imported tools are regenerated at deploy time, so a repo copy's `tools[]` can differ from production (on one solution `dev` showed 29 tools while production ran 66). Reads of those paths carry an `_ateam_representation` field saying what you are holding. To answer "what can this skill actually do?", call ateam_get_solution(solution_id, skill_id, section:'tools') — never this tool.

Branch to read/write (alias for `ref`). Declared so MCP does not strip it — an undeclared argument is dropped silently, which made a branch:"dev" read return `main` with no error.

File path in the repo (e.g. 'connectors/home-assistant-mcp/server.js', 'solution.json', 'skills/order-support/skill.json')

Branch, tag, or commit SHA to read from. Default: 'main' (prod). Use 'dev' to read in-progress work.

The solution ID

JOIN a diverged dev and main. Use when ateam_github_promote returns PROMOTE_NEEDS_HUMAN or PROMOTE_PRECONDITION_FAILED — i.e. the automatic main→dev back-merge could not resolve itself.

TRY sync_from_main FIRST; this tool calls it internally (a plain merge keeps both sides with no judgement call) and only escalates when git genuinely conflicts.

On conflict it writes a TWO-PARENT merge commit so the histories actually join. That matters: copying one branch's tree onto the other makes the contents match while leaving NO merge base, so the very next promote conflicts again — equal content is not a reconciled history.

Conflicting files are resolved per file, NEWEST WINS, and every decision is reported. Recency is a heuristic, not intent: read the decisions. On a real tenant main held the newer solution.json while dev held the newer widget, so a blanket choice would have reverted one of them.

WHO NEEDS THIS: any tenant whose deploys predate the dev-routing fix carries main-only commits the platform itself wrote, and hits this on its first promote afterwards. Pass dry_run:true to see the decisions before writing anything.

Report the per-file decisions without writing the merge commit.

The solution ID

Roll prod (`main` branch) back to a previous state.

ADDITIVE — does NOT destroy history. Creates a new commit on top of main whose tree matches the target's tree. The history of everything between target and current main is preserved (you can roll back the rollback).

Workflow: 1) ateam_github_list_versions (find a safe-* tag) → 2) ateam_github_rollback(target: 'safe-...') → 3) ateam_build_and_run (deploys the reverted state).

The solution ID

Tag (e.g., 'safe-2026-05-19-001') or commit SHA to revert main to. Use ateam_github_list_versions to find safe-* tags.

Check if a solution has a GitHub repo, its URL, and the latest commit. Use this to verify GitHub integration is working for a solution.

The solution ID

BRING `dev` UP TO DATE WITH `main` — merges main into dev. The mirror of ateam_github_promote.

USE THIS WHEN PROMOTE RETURNS 409. promote only ships dev→main, so the moment anything lands on main directly — a hotfix, a manual edit, an ateam_github_rollback, or a write that mis-targeted the branch — dev falls behind and can never be promoted again. Without this tool that divergence is unfixable from A-Team: the only exits are the GitHub web UI or a raw API call.

Workflow on a 409: 1) ateam_github_diff (confirm status:'diverged') → 2) ateam_github_sync_from_main → 3) ateam_github_promote.

Pass dry_run:true FIRST to see exactly which commits and files would come into dev without changing anything.

This is a real merge, not a force: if main and dev edited the SAME lines it returns 409 too, and that one genuinely needs a human (open a PR).

If true: show the commits + files that would merge into dev, change nothing. Default: false. Call this first.

The solution ID

Output: bounded

Write a file to the solution's GitHub repo. Use this to create new connector files or replace existing ones — one file per call. This is the PRIMARY way to write connector code after first deploy. Write each file individually (server.js, package.json, UI assets), then call ateam_github_promote() to ship to prod (dev→main), then ateam_build_and_run() to deploy.

DEFAULTS TO `dev` BRANCH.

The full file content

Optional commit message (default: 'Write <path>')

File path to write (e.g. 'connectors/my-mcp/server.js', 'connectors/my-mcp/package.json')

Target branch. Default: 'dev'.

The solution ID

List all solutions deployed in the Skill Builder.

Record ONE lesson this run learned, so the NEXT run does not relearn it. A building agent starts every run empty — it does not know which tool misled the last run or the workaround that got past it. Log a lesson the moment a tool misleads you AND you find a way through.

APPEND-ONLY. You cannot edit or delete earlier lessons, and you do not supply the timestamp — the server stamps it, so it cannot be forged.

PROVENANCE CAVEAT, stated because the earlier wording over-promised: `job_id` and `actor` are recorded ONLY when the caller supplies x-adas-job-id / x-adas-actor-id. An agent calling this tool does not, so those fields are usually null — a lesson cannot currently be traced back to the run that produced it, and the file cannot tell 'three runs hit this' from 'one run hit it three times'. Do not put a job id in `error` to compensate; keep that field verbatim.

LOG ONLY WHAT YOU OBSERVED. Quote the error VERBATIM; never paraphrase it and never write a theory about platform internals. A wrong lesson is worse than no lesson, because the next run cannot check it and will act on it.

Use kind='misleading_success' when a call REPORTED success while the thing you wanted did not happen — that class is the most expensive to rediscover and it is invisible to a failures-only log.

The VERBATIM error or failed_steps fragment. Not a paraphrase.

failure = it errored; surprise = it worked but not as documented; misleading_success = it REPORTED success while the intended effect did not happen

The solution this lesson belongs to

The tool that misled you, e.g. "ateam_build_and_run"

What you did instead (optional)

Did the workaround work? Omit if you never found out — 'unknown' is a real answer

Record that a build STEP is done, so a later run does not redo it. Write it AS IT HAPPENS, never at the end — the runs that most need a journal are the ones the clock kills.

WHY: a continuation cannot otherwise tell what the previous run achieved, so it re-runs the whole orientation (bootstrap, get_workflows, list_solutions, get_solution, get_spec, get_examples, github_read) to re-derive from documents what was already established — and re-inflates its prompt into the region where provider latency collapses. Measured across 13 runs: stalls track PROMPT SIZE (~60k), not turn count. ateam_get_progress is ONE call instead of nine.

status — three values, and the third is the point:
  built     — the artefact exists (files written, committed)
  deployed  — the platform accepted it
  verified  — YOU CALLED IT AND GOT REAL DATA BACK

`verified` REQUIRES verified_by, and a deploy response is not verification. `connected` and `tools > 0` are tools/list facts: a clinic connector showed 9 tools while every storage call returned 401. A journal that stops at `deployed` records that build as finished.

Re-log the same step as it advances (built → deployed → verified) — latest wins, no update path. If a step REGRESSES, re-log it at the lower status: silence must not read as "still fine".

One line of what exists — e.g. '10 tools, 8 seeded appointments'.

The solution ID

built = artefact exists · deployed = platform accepted it · verified = you called it and got real data back

STABLE slug a later run can MATCH rather than enumerate: 'connector:<id>', 'skill:<id>', 'widget:<name>', 'seed:<what>'. Keep it identical across runs — a renamed step reads as a new one.

REQUIRED when status is 'verified': the literal call that proved it and what came back, e.g. 'ateam_test_connector(clinic-data-mcp, appointments.list_all) → 23 rows'. Storing the evidence beside the claim is what makes the journal auditable instead of self-reported.

Surgically update ANY field in a skill or solution definition, redeploy, and optionally re-test — all in one step.

⚠ MERGE-BY-DEFAULT (v0.4.0) — Arrays are protected from silent replace. Bare array writes on solution.linked_skills / ui_plugins / platform_connectors / handoffs / grants / triggers (etc.) and skill.tools / connectors / handoffs / scenarios are REFUSED to prevent sibling loss. Add or remove items with the _push / _delete / _update suffixes; opt into a full-array replace only when you really mean it.

OPERATIONS (safe by construction):
1. Scalar (dot notation): { "problem.statement": "new value", "role.persona": "You are..." }
2. Deep nested: { "intents.thresholds.accept": 0.9, "policy.escalation.enabled": true }
3. Array APPEND: { "tools_push": [{ name: "new_tool", description: "..." }] }
4. Array REMOVE: { "tools_delete": ["tool_name"] }
5. Array MODIFY-ONE: { "tools_update": [{ name: "existing_tool", description: "updated" }] }
6. Full-array REPLACE (opt-in): { "linked_skills": [...], "linked_skills_replace": true } — or { _replace: true, ... } to opt every array in this call.

SOLUTION-LEVEL EXAMPLES (target='solution'):
- ADD a skill to the solution: updates: { "linked_skills_push": ["my-new-skill"] } ← NOT { linked_skills: ["my-new-skill"] } (that would REFUSE — it drops your other skills)
- REMOVE a skill: updates: { "linked_skills_delete": ["old-skill"] }
- ADD a UI plugin: updates: { "ui_plugins_push": [{ id: "mcp:conn:panel", ... }] }
- ADD a handoff: updates: { "handoffs_push": [{ id: "h1", ... }] }

SKILL-LEVEL EXAMPLES (target='skill' + skill_id):
- Change persona: updates: { "role.persona": "You are a friendly assistant" }
- Append to persona: updates: { "persona_append": "\n\nALWAYS respond in 2 sentences." }
- Add a guardrail: updates: { "policy.guardrails.never_push": ["Never share passwords"] }
- Add a tool: updates: { "tools_push": [{ name: "conn.tool", description: "...", inputs: [...], output: {...} }] }
- Change intent: updates: { "intents.supported_update": [{ id: "i1", description: "new desc" }] }
- CREATE a new skill: target='skill', skill_id='my-new-skill', updates: { "problem.statement": "...", "role.persona": "..." } — auto-scaffolded and added to solution topology.

PREVIEW BEFORE WRITING: pass dry_run:true to see the diff (arrays_merged, arrays_replaced, dropped_ids, added_ids) without applying. Use this before any destructive-looking edit.

VERDICT (skill target): the response carries a NON-BLOCKING `validation` block { skill_id, valid, ready_to_export, error_count, incomplete_sections[], unresolved_refs } — the patch always saves even if the def is now invalid, so CHECK valid: false and fix incomplete_sections before relying on it (build_and_run will refuse to deploy an invalid skill). error_count can include auto-import connector-tool artifacts, so act on incomplete_sections first.

If true, apply the patch in memory and return the diff (arrays_merged, arrays_replaced, dropped_ids, added_ids, would_write_bytes) WITHOUT writing to GitHub or redeploying. Preview a change before committing to it.

If true, return the FULL patched definition. Default false — the result returns a compact patched_summary instead, because the full definition can exceed the ~50KB output limit and truncate the rest of the result (redeploy status, widget_health).

Required when target is 'skill'. The skill ID to patch.

The solution ID

Where the solution/skill definition lives. Omit (DEFAULT) — prefer the tenant's GitHub repo (GitHub is master), but AUTO-DEGRADE to the Builder FS store if the tenant hasn't connected a repo, so a simple def patch always succeeds (it's pushed to GitHub once connected). 'github' — force GitHub; fails loud if not connected (use when you specifically require the repo write). 'local' — force the Builder FS store, no GitHub (repo-less bootstrap tenant). Redeploy is local in all modes.

What to update: 'solution' for solution definition, 'skill' for skill definition fields (problem, role, intents, tools, policy, engine, scenarios, etc.)

Optional: re-test the skill after patching. Requires skill_id.

The update payload. Use dot notation for nested scalars (e.g. 'problem.statement': 'new value'). For arrays, use _push/_delete/_update suffixes (e.g. 'tools_push', 'tools_delete'). You can update ANY field in the skill definition: problem, role, intents, tools, policy, engine, scenarios, glossary, etc.

Re-deploy skills WITHOUT changing any definitions. ⚠ HEAVY OPERATION: regenerates MCP servers (Python code) for every skill, pushes each to A-Team Core, restarts connectors, and verifies tool discovery. Takes 30-120s depending on skill count. Use after connector restarts, Core hiccups, or stale state. For incremental changes, prefer ateam_patch (which updates + redeploys in one step).

Optional: redeploy a single skill only. Omit to redeploy ALL skills in the solution.

The solution ID to redeploy

Show the minimal authoring view of a skill — persona + connectors + handoff_when + style + policy guardrails only. ~10× smaller than ateam_get_solution(view:'skills') for the same skill. Use this when you only need the irreducible author content (Phase 9 of the strip).

The skill ID

The solution ID

Show the minimal authoring view of a solution — name + description + style + routing_mode + identity_mode + skill ids + connector ids only. Skips deployed metadata, handoffs (auto-generated), grants, ui_plugins, validation results. Use this for fast inspection without the verbose fields (Phase 9 of the strip).

The solution ID

Semantic search over the FULL ateam platform /spec documentation — the deep fallback behind ateam_design_advisor. Ask a natural-language 'how do I…' question and get the most relevant doc chunks (with their topic + heading), then read the full topic via ateam_get_spec(topic). Use this when the advisor's pointer isn't enough, or for details/examples on anything — including topics outside the curated capability list. Read-only.

Natural-language question, e.g. 'how do I send a proactive daily reminder?' or 'per-user persistence'.

How many chunks to return (default 8, max 25).

Show GitHub sync status for ALL tenants and solutions in one call. Requires master key authentication. Returns a summary table of every tenant's solutions with their GitHub sync state.

Output: bounded

Sync ALL tenants: push Builder FS → GitHub, then pull GitHub → Core MongoDB. Requires master key authentication. Returns a summary table with results for each tenant/solution.

Only pull from GitHub to Core (skip push). Default: false (full sync).

Only push to GitHub (skip pull to Core). Default: false (full sync).

Abort a running test. Pass chain_id to abort the WHOLE run — every job in the chain — and get back which ones stopped. Aborting by job_id stops that job only, leaving handoffs running. Stops at the next iteration boundary. (Advanced.)

THE EXECUTION'S IDENTITY — what ateam_conversation returns and what you actually hold. A chain is the whole run: root job + every handoff + every askAnySkill subcall. Prefer this.

Abort ONE job only. Prefer chain_id: aborting the root leaves handoffs running while reporting the test aborted.

The skill ID

The solution ID

Call a tool on a running connector and get the result. Use this to test individual connector tools (e.g., triggers.list, entities.list, google.command) without deploying to a client. The connector must be connected and running.

Optional: arguments to pass to the tool

The connector ID (e.g., 'home-assistant-mcp', 'google-home-mcp')

The solution ID

The tool name to call (e.g., 'triggers.list', 'entities.list', 'google.devices')

Fire a REAL notification at an existing actor in a deployed solution — for end-to-end testing of the system-initiated notification path (telegram/push/app channels).

Unlike ateam_test_skill (synthetic test actor with no channels) and ateam_conversation (user-initiated thread), this calls the /api/internal/notify-user path that PCM and other sibling services use — so the actor's real enabled channels actually receive the message.

Use for:
  • Channel fan-out smoke (does telegram/push/app actually receive it?)
  • Delivery-result verification (per-channel ok/failed in the response).

Auth: forwards your authed api_key to Core (no master-secret involvement). Tenant is pinned by the key itself — cross-tenant targeting is structurally impossible.

⚠ SAFETY:
  • The text is prefixed with [TEST] in the actual notification — visible to the user, anti-phishing.
  • Rate-limited: 10 calls/min per session.
  • Every call is audited (caller, tenant, actor, content hash) regardless of outcome.
  • actor_id is scoped to your tenant — cross-tenant targeting is rejected by Core's per-tenant Mongo isolation.
  • reply_handler is NOT supported via api-key auth (Core ignores it). Routing the user's next reply to an arbitrary skill is a privilege-escalation surface. For routing/engagement tests, use ateam_test_skill.

Target actor ID in your tenant (e.g. 'usr_arie_admin_0001'). Must exist; Core rejects if not found in your tenant.

Notification text. Will be sent to all of the actor's enabled channels, prefixed with [TEST] for the recipient.

Optional metadata merged into message.metadata. Useful for correlation IDs.

The solution ID (required for tenant scoping + audit context).

Audit label for message.source. Default 'ateam-test'.

Notification urgency. Default 'normal'.

Test the decision pipeline (intent detection → planning) for a skill WITHOUT executing tools. Returns intent classification, first planned action, and timing. Use this to debug why a skill classifies intent incorrectly or plans the wrong action.

The test message to classify and plan for

The skill ID to test

The solution ID

Send a test message to a deployed skill and get the execution result.

Wait modes (wait_for):
  • 'root' (default, back-compat) — wait until the message's root job completes, return single-job result. Fast, ignores any sub-skills the root delegated to via askAnySkill.
  • 'chain' — wait until EVERY job in the chain (root + handoffs + askAnySkill subcalls, recursively) reaches a terminal state, then return the full chain tree. Use when testing multi-skill flows (orchestrator → workers, builders → sub-builders, etc.). The response.chain field carries chainJobs[] with parentJobId/relation/depth and executionSteps[] with tool-nesting (opId/parentOpId/_toolDepth).

Legacy: wait:false is equivalent to wait_for:'never' — returns job_id immediately for polling via ateam_test_status. wait:true is the same as the default wait_for:'root'.

Optional actor ID for conversation continuity. Pass the actor_id from a previous test response to continue the conversation. Omit to auto-generate a test actor (test_<timestamp>_<random>, auto-expires in 24h).

Optional. Max total ms to wait when wait_for:'chain'. Default 300000 (5 min). Long-running chains (skill-factory, large bundle builds) may need higher. Clamped to [10000, 900000].

The test message to send to the skill

The skill ID to test (original or internal ID)

The solution ID

Legacy: if false, return job_id immediately for polling. If true or omitted, behaves like wait_for:'root'. Prefer wait_for going forward.

What to wait for before returning. 'root' (default) = root job done; 'chain' = every chain job terminal (use for multi-skill flows); 'never' = return job_id immediately (poll via ateam_test_status). When 'chain', the response includes the chain tree under response.chain.

Poll the progress of an async test. Pass chain_id for the WHOLE run (recommended — the root job finishing does NOT mean the run finished; a handoff may still be going). Pass job_id to poll one job alone: iteration count, tool call steps, status, and result when done.

Set include_chain:true to ALSO include the full chain tree (every job in the chain, rooted at this job_id, with parent/child linkage). Use when this job dispatched askAnySkill subcalls and you want a single snapshot of the whole multi-skill state instead of polling each child job_id separately.

THE EXECUTION'S IDENTITY — what ateam_conversation returns and what you actually hold. A chain is the whole run: root job + every handoff + every askAnySkill subcall. Prefer this.

If true, includes response.chain — the full chain tree rooted at this job_id (chainJobs[] with parentJobId/relation/depth, executionSteps[] with tool-nesting). Costs one extra Core call. Default false (back-compat).

ONE job inside the chain, when you want that job alone. Omit and pass chain_id for the whole run — a root job can be 'completed' while a handoff is still running.

The skill ID

The solution ID

safe:false when include_chain:true (that fetches the full tree).

Output: bounded

Simulate a voice conversation with a deployed solution. Runs the full voice pipeline (session → caller verification → prompt → skill dispatch → response) using text instead of audio. Returns each turn with bot response, verification status, tool calls, and entities. Use this to test voice-enabled solutions end-to-end without making a phone call.

Array of user messages to send sequentially (simulates a multi-turn phone conversation)

Optional: simulated caller phone number (e.g., '+14155551234'). If the number is in the solution's known phones list, the caller is auto-verified.

Optional: target a specific skill by slug instead of using voice routing.

The solution ID

Optional: max wait time per skill execution in milliseconds (default: 60000).

Upload connector code to Core and restart — WITHOUT redeploying skills.

MERGES with the GitHub state at `ref` by default (default ref: 'dev'). Sending a partial file set ONLY overlays those files — the rest of the connector is preserved from GitHub. To fully replace the connector dir (historical behavior), pass replace:true.

Modes:
  • github:true (no files)        — deploy the GitHub state at `ref` as-is.
  • github:true + files:[]        — GitHub state at `ref` as BASE, your files overlay on top (incoming wins).
  • files:[] (no github)          — default MERGE with GitHub state at `ref`. Refuses if no GitHub base exists (no silent nuke).
  • files:[] + replace:true       — full replace. Wipes connector dir + writes only the provided files. Use deliberately.

Multi-file connectors (server.js + dashboard HTML + RN bundle + package/manifest): pass each file with content_base64 (a single-line, escape-safe base64 string) instead of content — so you don't hand-escape ~90KB of HTML/JS/JSON inside one tool call. This is the CANONICAL agent path for a full connector; do NOT hand-roll `curl` against the raw endpoint (that skips connector registration / PAT provisioning).

Common traps this design prevents:
  • Pre-fix bug (2026-06-06): sending just ui-dist HTML wiped server.js + node_modules — connector broke until a full re-upload. Now: those files merge with the GitHub base.
  • Pre-fix bug: github:true silently read from `main` even when patches were on `dev`. Now: defaults to dev; pass ref:'main' to opt into the legacy path.

The connector ID to upload (e.g. 'personal-assistant-ui-mcp')

Files to upload — each needs 'path' plus ONE of content (inline string) or content_base64 (escape-safe base64; preferred for multi-file connectors). By default merges with the GitHub state at `ref`. Set replace:true to wipe the connector dir and write only these files.

File content as an inline string. Prefer content_base64 when the content has complex escaping (HTML/JS/JSON).

File content as a single-line base64 string — escape-safe. PREFERRED for a multi-file connector so large HTML/JS/bundles don't need hand-escaping in the tool call. Provide exactly ONE of content / content_base64 per file.

Relative file path (e.g. 'server.js', 'ui-dist/panel/index.html')

RECOVERY: respawn the connector + re-inject its CURRENT env even when the source is UNCHANGED. Normally an unchanged-source upload no-ops (unchanged:true) and leaves the process running. But a connector spawned before a shared-secret rotation keeps the STALE secret — it still lists tools (looks healthy) yet 401s on every per-actor call, with no recovery short of a fake source edit. Use `ateam_upload_connector(solution_id, connector_id, github:true, force:true)` to pull the current source and force a fresh respawn (which picks up the current secret). Default: false.

If true, pull connector files from GitHub repo at `ref`. Default: false. Combine with files:[] to use GitHub as the base and overlay your files.

GitHub branch to read from for the BASE state. Default: 'dev' (matches ateam_github_patch). Pass 'main' to read from production. Pre-2026-06-05 callers that relied on the silent-main default must pass ref:'main' explicitly.

Opt into FULL REPLACE: wipe the connector dir and write only the provided `files`. Default: false (= merge with GitHub state at `ref`). Use with intent — sending an incomplete file set with replace:true will break the connector.

The solution ID

ONE call that returns the REAL runtime end-state of a solution — connectors connected + tools discovered, every declared widget actually rendering, skills deployed — with the EXACT failing gaps. Use this instead of guess-and-check after a deploy/patch: it tells you the truth (what's actually live) and names precisely what's broken, not a generic warning. Reliable from any connection (routes through the Builder, not a direct Core call).

The solution ID to verify.

Output: bounded

Check that the Builder filesystem state and GitHub state are in sync for a solution. Read-only probe — does NOT trigger a deploy.

Returns:
  • ok: true + drifts: [] if everything matches
  • ok: false + drifts: [{path, kind}] listing files that differ (kinds: fs_missing, gh_missing, content_differs)

Drift can creep in when GitHub writes happen but Builder FS doesn't get the mirror update (network blip, container restart mid-write). Boot sync heals most of it on next backend restart; this tool surfaces drift earlier.

Run after a series of ateam_github_patch calls to confirm the Builder backend is consistent with GitHub before you ateam_build_and_run.

The solution ID to verify

PROVE a connector ui_plugin actually renders WITH DATA — the required evidence that a user-visible UI fix is done. A plugin fetches its data over postMessage from its parent window, so opening its iframe alone shows the empty state and 'confirms' the very bug you're checking. This opens the plugin in the REAL host surface in headless Chromium, records every MCP tool call it makes, and returns { ok, verdict, visible_text, calls, failures }. It distinguishes 'invented tool name' / 'right tool, no data' / 'plugin never asked'. FAIL-CLOSED: a browser-mcp outage returns ok:false verdict:'inconclusive' (never a soft pass). Run AFTER a UI/data fix; quote visible_text in your report. Requires authentication.

Optional actor to render as; defaults to the solution's context actor.

Optional assertion: { tools: ['memory.get', ...] } — each MUST be called by the plugin, else ok:false.

The ui_plugin id to probe, e.g. 'mcp:accounting-mcp:spending-dashboard'.

The solution id.


🧩 Generate schemas, diff JSONs, and create SDK boilerplates (Python/TypeScript).

JSON string for schema/diff, or URL for SDK

Second JSON string for diff action

🔴 Close browser with cleanup and session save

Save cookies and storage for next session

🚀 Initialize a reliable browser session with automatic recovery and self-healing selectors.

🤖 AI Usage Guide: Use this FIRST to start the browser session. Only run once per session.

Enable AI auto-healing for broken selectors

Universal Playwright BrowserContext options (e.g. httpCredentials, geolocation, extraHTTPHeaders, permissions, viewport, userAgent, etc.)

Block ads and trackers

Record continuous video of session

Automatically handle Cloudflare Turnstile challenges

click

👆 Reliable click with self-healing selectors, iframe support, hover for dynamic controls, and automatic video player detection.

🤖 AI Usage Guide: If a CSS selector fails or you are unsure of the selector, DO NOT guess repeatedly. Call `see_page` with `annotate: true` to get the `annotationId`, then click using `annotationId` instead of `selector`.

Auto-find alternative selector if broken

Alternative to selector: Pass the number from see_page(annotate: true) to click instantly

Auto-accept alerts/confirms to prevent blocking

Auto-detect video player iframe (JWPlayer, VideoJS, Plyr, VidStack, DooPlayer)

Force click even if element not visible (use JS click)

Wait time after hover before click (ms)

Hover before click (for dynamic controls like video players)

Only hover, do not click (to reveal hidden controls)

Smooth natural cursor movement

Execute in specific iframe index (use media_extractor list_iframes to get index)

Alternative: iframe CSS selector instead of index

Max wait time for video to start playing (ms)

Auto-retry on failure

Auto-scroll element into view before click

CSS selector (AI auto-heals if element not found)

Timeout for element to appear

Use player API (jwplayer.play()) instead of DOM click for reliable playback

Wait until video actually starts playing

🧠 Deep page analysis: DOM structure, scripts, styles, accessibility, performance metrics, SEO tags, security headers, protection-service detection (Cloudflare, DataDome, reCAPTCHA), technology stack identification, and recommendations for the best content-loading strategy.

🤖 AI Usage Guide: Use this if a page fails to load fully or if elements are unexpectedly absent, to check for protection services or iFrames.

AI provides recommendations

Detect page protection services

💻 Execute custom JavaScript with async support, error handling, and iframe context

Execute async code

Execute in specific iframe index (0=main, 1+=iframes)

Alternative: iframe CSS selector

Wait for iframe to be ready

🔎 Universal data extractor with 9 modes: (1) regex, (2) json, (3) meta, (4) structured, (5) auto, (6) deobfuscate (decode encoded strings), (7) apiDiscovery, (8) decrypt (decode encoded data), (9) links - extract all links including hidden, iframe, and encoded links.

🤖 AI Usage Guide: Use this INSTEAD of executing custom JS (`execute_js`) to read data. If you need links, use type="links". For general info, use type="auto".

For decrypt: AES initialization vector

For decrypt: AES decryption key

Auto-decode Base64/URL in results

For decrypt: automatically locate decoding keys from page scripts

For decrypt: data to decode/decrypt

Regex flags

For links: Include hidden links

For JSON: path expression

For regex: pattern to search

For links: Search inside iframes

For structured/links: CSS selector

regex json meta structured auto deobfuscate apiDiscovery decrypt links

📄 Get page content in multiple formats: html, text, markdown, rawHttp, or elements. Extracts text, attributes, or visual bounding boxes (rects). Can optionally save directly to a file.

🤖 AI Usage Guide: Prefer format="rawHttp" for static sites to fetch raw HTML directly without JavaScript rendering (10x faster). If you need coordinates, use format="elements" with an xpath or text selector.

Auto-fix broken selectors

Extract all element attributes

Include page title and URL at the top

Return multiple matching elements (for format=elements)

URL to fetch raw HTTP (no JS). Defaults to current page URL if format is rawHttp.

Absolute file path to save extracted content to disk

CSS selector (AI will auto-heal if broken)

Find elements containing exact text

Wait for JavaScript to render

XPath selector

🎬 Universal media extractor with 6 actions: (1) extract - find all video/audio/HLS/DASH/download URLs from page + nested iframes (3+ levels deep), (2) list_iframes - list all iframes with indices, (3) switch_iframe - get iframe URL and info (use iframe/iframeSelector params on other tools to target specific iframes), (4) player_control - control video players (JWPlayer, VideoJS, Plyr, VidStack, DooPlayer) via API: play/pause/seek/sources, (5) decode_url - decode encoded URLs: auto/url/base64/aes with key+IV, (6) batch_extract - extract from multiple URLs at once.

AES IV (optional)

AES decryption key

AI optimizes extraction strategy

Deep scan scripts and data attributes

For decode_url action

iFrame index

iFrame selector

video, audio, hls, dash, download, iframes

Multiple URLs for batch extraction

navigate

🧭 Navigate to URL with smart retry, context recovery, and AI healing.

🤖 AI Usage Guide: Use this right after browser_init to load a target website. Wait for networkidle by default.

Auto-retry on failures

AI-powered smart waiting

load domcontentloaded networkidle commit

📡 Record all network activity with 11 actions: (1) start, (2) stop, (3) get, (4) clear, (5) get_media, (6) get_navigations, (7) get_api_calls, (8) get_intercepted_apis, (9) get_websockets, (10) get_graphql - extract GraphQL queries/mutations, (11) export_har - generate HAR 1.2 format JSON.

AI detects video/audio streams

Capture fetch/XHR response bodies (JSON, form-urlencoded)

🎹 Press keyboard keys with natural timing

Natural delay between presses

📈 Track automation progress with AI predictions

AI estimates remaining time

📜 Natural scrolling with adaptive pattern detection

Auto-detect lazy loading patterns

0 = AI decides based on content

🔀 Trace complete redirect chains including HTTP 301/302 redirects, JavaScript-based navigations (window.location, setTimeout redirects), and meta refresh tags. Auto-decodes encoded URLs in the chain. Returns full redirect path with status codes and headers.

🤖 AI Usage Guide: Use this if a URL is failing to load or redirecting infinitely to understand the routing.

Auto-decode encoded URLs in chain

Track JS navigations

Track meta refresh redirects

Navigation timeout in milliseconds

🔁 Replay a captured API request directly within the page context, reusing the existing session cookies and headers.

👁 AI VISION ("eyes"): Visually SEE the current page exactly like a human does. Returns a screenshot image AND a RICH SINGLE-SHOT MAP of the entire page in one call: full page text, all visible interactive elements (buttons, links, inputs) with position/selector, AND an iframe inventory — so you can plan and execute a whole multi-step task from ONE view without re-capturing the page after every action.

🤖 AI Usage Guide (HUMAN-LIKE WORKFLOW):
1. Call see_page ONCE with fullPage:true, includePageText:true, scanIframes:true, annotate:true.
2. From that single view, PLAN and RUN all actions for this page in a CONTINUOUS sequence WITHOUT re-capturing the page between steps. You can pass a `steps` array (click / type / press_key / scroll / wait / extract / see) and they run back-to-back in ONE flow — this is the unified task runner (the old separate browse_task tool is merged here to avoid confusion). A BEFORE and AFTER screenshot are captured automatically.
3. ONLY call see_page AGAIN after the page genuinely changes (navigation to a new URL, a modal/popup opens, or new dynamic content loads). Never re-capture the same unchanged page.
4. For multi-page tasks (login → dashboard → settings), let each navigation trigger a fresh single see_page, then continue the continuous action sequence. This mimics how a human watches a page once, acts, then looks again only when the page actually changes.

Super Vision: Draw red bounding boxes with numbers over all interactive elements for instant click/type targeting

Hover over menus before taking screenshot to reveal dropdowns

Take an AFTER screenshot when running steps

Take a BEFORE screenshot when running steps

Image format (jpeg = smaller, faster for vision)

See the entire scrollable page (true) or just the current viewport (false)

Include the full text content of the page (DOM reading)

Include the visual map of interactive elements

Include cleaned page text so the agent can plan actions without re-capturing

Max number of interactive elements to map

Optional file path to also save the captured image

JPEG quality 0-100 (lower = smaller image to the AI)

List all iframes (index + url) so cross-frame navigation is planned in one view

HUMAN-LIKE TASK RUNNER: optional list of actions to run in ONE continuous flow right after capturing the page — WITHOUT re-capturing between steps. Actions: click / type / press_key / scroll / wait / extract / see. Ideal for multi-step forms, wizards, and checkouts. Plan the whole task from this single page view, then hand the step list here. (Merged from the former browse_task tool.)

click type press_key scroll wait extract see

For scroll: pixels

For see step: annotate interactive elements

Numeric id from a prior see_page(annotate:true)

For type: clear field before typing

For press_key: number of presses

For scroll

For extract

For see step: capture full scrollable page

For click: human-like cursor movement

For see step: include page text

For press_key: key to press

For press_key: modifier keys

For type: press Enter after typing

For click: auto-retry count

For see step: include iframe inventory

CSS selector (or use annotationId instead)

For scroll: smooth scrolling

For type: text to enter

Per-step timeout (ms)

For wait: selector/value

For wait

For extract: xpath selector

Stop the step sequence on first failure (true) or continue (false)

Check for DOM mutations (popups/alerts) since last view

🔓 Handle verification widgets and smart form automation for automated testing of your own pages (Turnstile challenges, text/image recognition via OCR). Note: reCAPTCHA/hCaptcha are not supported — use third-party services for those.

AI matches fields even if names differ

Allowed characters in captcha

Analyze page structure before solving

CSS selector for captcha image (required for text/image type)

Expected captcha text length

Form field data to fill (AI matches fields automatically)

Form selector (AI auto-detects if not provided)

Natural typing with variable delays

CSS selector for input field to fill result

OCR language: eng, hin, eng+hin

Max refresh attempts for OCR

CSS selector for captcha refresh button

Auto-submit form after filling and verification

Verification type: turnstile (JS-based), text/image (OCR-based), auto (detect). Note: reCAPTCHA/hCaptcha are not supported — use third-party services.

🗄 Inspect IndexedDB and Service Workers natively via JS.

type

⌨ Type text with natural speed variation, smart clearing, and iframe support.

🤖 AI Usage Guide: Like `click`, if the selector fails, use `see_page` with `annotate: true` and pass the `annotationId`.

Alternative to selector: Pass the number from see_page(annotate: true) to type instantly

Keystroke delay with natural timing variation

Execute in specific iframe index

Alternative: iframe CSS selector

Press Enter after typing

Wait for selector before typing

wait

⏳ Smart wait with AI prediction for optimal timing.

🤖 AI Usage Guide: Avoid arbitrary timeouts. Use type="networkidle" or type="selector" to wait for elements to appear dynamically before interacting with them.

AI optimizes wait time based on page load patterns

Selector or timeout value