IonWarp logoIonWarp
Get started
IonWarp Docs
API

MCP Tools

Every mcp__dash__* tool available to IonWarp, with arguments and a minimal call.

The MCP tools exposed to IonWarp over mcp__dash__* (Core toolset plus the ionwarp module). Enumerated at build time (from the composed toolset).

actions_list

List the quick actions available on a Data view (surface:"view" + view_id) or on a specific object (surface:"object" + collection + object_id). Call this to discover an action_id before running it with actions_run. Read-only.

actions_run

Run a declared DashAction by action_id against a target (a view or an object; discover ids with actions_list). Executes permissions → before: → run: and returns the real outcome — a created task, the integration-action runs it performed, or a NAMED refusal. link and dialog actions are client-only and are refused here. Target is {"kind":"view","view_id":"…"} or {"kind":"object","collection":"…","object_id":"…"}.

actor_accounts_create

Create a service actor, workspace, owner membership, and one-time PAT.

agents_create

Create a chat agent for a project.

agents_get

Get a single agent by id.

agents_list

List agents in a project.

artifacts_extract_images

Extract screenshot-shaped embedded images from an uploaded PDF artifact into image artifacts (tags ["pdf-extract"]). Returns artifact ids + dimensions, largest first — never image bytes. Duplicate images (already extracted for this project, from any file) return the existing artifact with reused: true. Vet each candidate with media_analyze { artifact_id } before saving it as a content image.

artifacts_generate_image

Generate an image artifact from a prompt using OpenRouter image generation. Pass seed_artifact_id to condition on an existing image artifact; omit it for pure text-to-image.

artifacts_get

Get one artifact's full record by id — including metadata.preview, the file's extracted text. This is the bounded per-file read; never artifacts_read a binary for its text.

artifacts_import_leads

Import an uploaded lead-list spreadsheet (xlsx/csv with email + name/company columns) as CRM rows: companies (deduped by domain), people (deduped by email — saved-undrafted people ARE the lead pool campaign runs reuse), and ONE list linking them. Deterministic and server-side — call it once per lead-list artifact instead of re-typing rows through data_batch. Re-importing the same artifact is a no-op that returns the original result.

artifacts_list

List artifacts for a project, task, or task run. Inventory + classification only — metadata.preview (the extracted file text) is NOT included (metadata.preview_chars says how much text exists); read one file's preview via artifacts_get.

artifacts_read

Read a TEXT-NATIVE artifact's content (text/*, json, csv, xml), or any artifact as base64. Text mode REFUSES binaries (pdf/pptx/images) — their extracted text is metadata.preview via artifacts_get, and their pixels ride media_analyze.

artifacts_update

Merge a metadata patch into an artifact (shallow merge; a null value deletes its key). The ONE classification write door: the index-artifacts pipeline stamps metadata.index {kind, marketability, summary, confidential} here.

artifacts_upload

Upload a project artifact and return artifact metadata. Provide EXACTLY ONE content source: content_base64 (any mime type, mime_type required) OR url (server-side fetch of a public image — image content types only; mime_type optional, inferred from the response; the source url is recorded as metadata.source_image_url). Use url mode to seed real site imagery, e.g. images returned by a web scrape.

catalog_publish

Publish an ANONYMIZED snapshot of a project's GTM pack (its best measured agents + learnings + example drafts) into the public catalog as status pending_approval. The catalog is packs-only — single-agent entries were deleted 2026-08-18. Requires a fully templatized manifest — real company/people/product strings listed in forbidden_strings are refused (catalog_anonymization_leak). A human employee later flips the entry live; this tool can never do that.

checklist_item_update

Update ONE checklist item you are working on: attach a link/detail/evidence, mark it in_progress, or flag it blocked with a named gap. state accepts ONLY "in_progress" or "blocked". You CANNOT mark an item done — done is derived from the item's predicate (a real D1 read) and from nothing else; passing state:"done" is refused. Change the underlying data to make an item go done.

checklist_list

List this project's (or the workspace's) onboarding checklists, EVALUATED: every item's done-ness is re-derived from a real D1 read at call time. Pass scope:"workspace" for the workspace list, or omit for the pinned project. Use it to see what onboarding steps remain.

checklist_push

Materialize a NEW declared checklist onto existing projects or workspaces (the 'ship a new onboarding list to everyone' path). Employee-admin only. Requires explicit project_ids or workspace_ids — an unfiltered push is refused.

checklist_run_publish

Publish TODAY's evaluation of this project's daily (Beast Mode) checklist — the ONE terminal write of a beast-mode-checklist run. summary (the day's one line, ≤140 chars) is the only required content: a list that declares NO judgment items is narrated, not graded, and a summary-only publish is the whole contract there. items is optional — pass every JUDGMENT item's verdict ({item_id, verdict: "pass"|"fail"|"skip", detail}) when the list declares any; a missing judgment verdict fails the WHOLE publish (checklist_verdict_missing). Fact items may be included as annotations, but their done-ness still derives from their own data query. Publishing again the same UTC day replaces that day's record. This does NOT mark items done — done derives from the published record on the next read.

config_get

Read this project's full effective configuration: every declared key with its resolved value, whether it came from the agent default or this project, and any project.md config that was REJECTED and why. Use it when the ## Config block in your prompt says keys were not shown, or to check a setting you were not given. Read-only — to CHANGE config, edit project.md frontmatter with skills_update. Never returns credentials.

custom_action_extract

Extract a draft Dozer custom action form schema from an uploaded artifact.

data_batch

Write records to Data in one capped batch — the primary tool for creating, seeding, or updating objects and appending timeline events. Call it whenever a task asks you to create or change records. Pass a top-level operations array; each operation is { op, collection, object_id, data } where op is "set" (create/update an object), "event" (append a timeline event), or "delete" (soft-delete). "set" MERGES into an existing object: only the fields you send change, every other field is preserved; send a field with value null to clear it. Fields shared by every row (provenance like created_by_agent_id, source_list_id, a context block) go ONCE in the optional top-level defaults object — the server merges defaults into each set operation's data (an operation's own value wins) — never repeat them per row. Example: {"defaults":{"created_by_agent_id":"agent-1"},"operations":[{"op":"set","collection":"equipment","object_id":"AT-100","data":{"unit_number":"AT-100","status":"active"}}]}. Never call it with an empty object. Keep batches SMALL: prefer <=4 operations per call, and give any operation carrying long text fields its own single-op call — a serialization slip anywhere in the JSON fails the ENTIRE batch and none of its operations are written.

data_delete

Soft-delete ONE object from a project's Data collection by object_id (it is hidden, not hard-erased). Use it to remove a single record; for bulk or mixed deletes alongside writes, prefer data_batch with op:"delete".

data_event

Append one timeline event to an existing object in a project's Data collection (e.g. a status change or note). For bulk events alongside object writes, prefer data_batch with op:"event".

data_events_list

List the timeline events (status changes, notes, and activity) recorded on one Data object, newest first. Use it to see an object's history before adding a note or acting on it. Read-only.

data_get

Read ONE object from a project's Data collection by its object_id, returning its current field values. Use it when you already know the exact object id; use data_query to search or list. Read-only.

data_query

List/read objects in a project's Data collection. Use it to check what already exists before writing, or to answer a question about the project's data. Pass properties (an array of field names) to project each object down to just those data fields plus the envelope (object_id, slug, reported_at) — this is how you keep a broad list read small; without it every row returns its FULL body (a people/drafts row is ~13KB, so an unprojected 50-row read is a ~650KB payload that bloats the run's context). Read-only.

data_schema_get

Read the schema of a project's Data collections — declared fields, their types, which are REQUIRED, their allowed values, what may be filtered and sorted, which operations the collection supports, and one worked call. Call this to discover which collections and properties exist before querying or writing; writes are validated against exactly this schema. Omit collection to list every collection. Read-only.

data_set

Create or update ONE object in a project's Data collection. Updates MERGE into the existing object: only the fields you send change, every other field (including name) is preserved; send a field with value null to clear it. For more than one record, or to mix creates/updates/events/deletes, prefer data_batch (one capped batch).

device_data_query

Query the workspace Device Data Lake with guarded R2 SQL. The helper injects workspace, time, expiry, and optional project bounds.

device_data_schema_get

Return the effective Device Data Schema for one workspace device.

device_data_schema_update

Create a new versioned Device Data Schema row after validating V1 scopes, raw keys, computed templates, and review rules.

game_queue_upsert

Enqueue (or update) items in a declared mini-game's queue for this project. game_type must be declared by the agent (agents/<agent>/games/); each item's item_type must be a declared card_type and its payload must carry subject {collection, object_id} — the ONE real object the card judges — plus focus, the VERBATIM QUOTE of the span the thumb judges. The quote is checked against that record at enqueue: not found, ambiguous, a part of a subject, or a mid-sentence fragment are all named refusals. Item actions come from the game config, never from this call. Max 10 items.

github_create_branch

Create a branch in the current project's linked repository, from base (default: the repository's real default branch, resolved — never assumed to be main). Reports a named error if the branch already exists — never force-moves an existing ref.

github_create_pr

Open a pull request on the current project's linked repository from head into base (default: the repository's real default branch, resolved). Returns the PR number and html_url — the skill's declared output.

github_get_file_content

Read one file from the current project's linked repository. An absent file is an ANSWER (returns content:null), never an error to retry. Returns total_lines/total_bytes; pass start_line/end_line (1-based, inclusive) to read a slice of a large file. A result carrying tool_result_truncated was cut by the platform budget — read it again in slices instead of guessing at the tail.

github_installations_list

List active IonWarp GitHub App installations attached to this workspace.

No arguments.

github_pull_requests_list

List recent pull requests (title, author, state, branches, merged_at) for the current project's linked repository. Use state=all with a limit to study recent team activity. With head (a branch name) the answer also carries already_open — the html_url of the OPEN PR from that branch, absent when there is none.

github_push_file

Create or update ONE file on a branch of the current project's linked repository, with a commit message. Call once per changed file. Refuses to write to the default branch — create a branch first.

github_repo_readme

Read the linked repository's README for the current project (repo-context learning).

github_repos_list

List repositories available to a workspace-owned IonWarp GitHub App installation.

github_upsert_marker_block

Write the canonical IonWarp agents-md section (PR Autofix + Session Analytics, \<!-- ionwarp:agents-md v3 -->\<!-- ionwarp:agents-md:end -->) into ONE file of the current project's linked repository, server-side: reads the file from the DEFAULT branch, replaces everything between the ionwarp:agents-md markers (any version) or appends the section after a blank line (creating the file if absent), then commits to branch (created from the default branch if missing). The section's bytes live on the platform — you never read, send, or compose them; pass only path, branch, message (and create). Returns action: replaced | appended | unchanged (+ already_enabled:true when unchanged) | absent (create:false and no file).

integrations_action

Request ONE semantic integration operation, by id (e.g. instantly.campaigns.list, resend.email.send). Your brief already carries the id and required_input for the work you were given — use them; a refusal here names the complete valid set, so there is never anything to look up. Dash owns the connection, credentials, endpoint, policy, and idempotency and returns a durable action. Reads and draft-preloads run automatically; controls and sends (campaign start/resume, resend.email.send) execute under the project's run mode — approved drafts in a live project send directly, bounded by the ONE daily send cap (a cap-refused push is named daily_send_cap_reached). Dash fills in the outcome (status_code, external_id, url, duration_ms) — you never report it.

integrations_actions_list

List the IntegrationActions (provider sync attempts + outcomes) recorded on one Data object, e.g. a draft. Read-only — shows status, external id, HTTP status, duration, and any error per provider.

integrations_actions_update

Record the outcome of an IntegrationAction after calling a provider: set status to completed (success) or failed, with a result object carrying status_code / external_id / url / response_excerpt / duration_ms, or an error_message on failure. Durable — this is what the status chip reads back.

integrations_call

Make an authenticated request to a connected integration's provider API WITHOUT ever seeing the API key — Dash injects credentials and returns only {status, data}. Use the provider's documented endpoints (see the agent's channels/ skill references): put the path in endpoint, INCLUDING any query string the provider documents (e.g. /campaigns?limit=50&status=draft), and the JSON request body in body — an object OR an array, whatever that endpoint documents. NEVER send an auth header yourself: Dash injects this project's credentials, and a call carrying authorization, x-api-key, x-key, proxy-authorization, cookie, set-cookie, host, :authority, x-forwarded-host, x-forwarded-proto, x-forwarded-for, forwarded, x-real-ip, x-original-url, x-rewrite-url, x-http-method-override, x-method-override, x-http-method (any casing) is REFUSED whole — nothing reaches the provider, so remove the header and retry rather than assuming it was ignored. Pass subjectCollection + subjectId (e.g. drafts + the draft id) when the call is for one object, so it shows on that object's sync status. Every call is recorded as a durable integration action — success and failure — so an operator can see afterwards exactly what was called. NEVER call activation or sending endpoints (e.g. campaign start/activate/resume, a status PATCH to active, or an email send) unless the running skill explicitly instructs it — adding a lead to a DRAFT/inactive campaign is the only write a skill should make on its own.

integrations_connect

Connect a provider credential (api_key) for the workspace or a project. Pass app_slug (e.g. resend, instantly, lemlist, heyreach), a credentials object (e.g. {api_key: '...'}), optional metadata, and scope (workspace | project). Unknown providers are refused. Echoes the stored connection row (id, app_slug, owner). Use this to install an integration from outside the app.

integrations_get

Get a single integration by id, WITH the semantic actions that provider supports: action id, risk (read | write | draft_preload | control | send), whether it needs approval, a summary, and its required input keys. Read this, then request one via integrations_action. No credentials are ever returned. (This absorbed integrations_capabilities_get: two reads that answered halves of one question — 'what is this connection, and what can it do' — and a caller needed both to act.)

Attach a workspace integration credential to a project so the project's runs can use it. Idempotent. Only this workspace's own workspace-scoped credentials attach — a platform default already applies to every project, and an unknown or foreign integrationId is refused.

Detach an integration credential from a project. The credential itself is untouched — it stays valid for the workspace and for any other project it is attached to; only this project stops being able to use it.

List every integration credential a project COULD use — the workspace's own credentials plus the platform defaults — each with linked (in this project's set right now), attachable (a link can be added/removed), and effective (the one of that provider's switched-on credentials Approve actually spends). Use this before integrations_links_attach to see what exists and what is already on.

integrations_list

List connected integrations for the workspace (or a project).

integrations_request

Ask the user to connect a provider via a secure card rendered in chat — use this whenever the user wants to add/integrate a provider, whether or not Dash supports it. Known api_key providers show their real credential fields; unknown providers show your proposed credential_fields (default: one api_key) and email the Dash team a support request; OAuth-only providers show an honest 'coming soon' state. NEVER ask the user to paste a key into chat — the card submits it directly to the API. If the workspace already has the provider connected this returns already_connected credential ids instead (attach them with integrations_links_attach).

learnings_context

Read the current learnings to inject into a run's reasoning. Pass subject_type + subject_id for a subject's learnings, or nothing for the whole project's. Call this at the START of a run to steer it with what the agent already believes.

learnings_create

Record ONE curated belief the agent now holds (deduped by the belief text; creating the same belief twice yields one row). Provide the one-line learning, optional body (evidence), source, and the subject it is about (subject_type + subject_id) or leave subject off for project-wide. It also lands a "learning_created" memory on the subject's timeline. Do NOT write the learnings collection via data_set/data_batch — use this tool.

learnings_remove

Remove ONE learning by its learning_id (from learnings_create / learnings_context). The only other verb — there is no strengthen/weaken feedback loop.

logs_query

Read this project's operational log — errors the RUNTIME recorded (a tool that threw, a timeout that fired, a run that failed), newest first. Filter by run_id for one run's errors, or by type ('error' | 'warning' | 'info') / code (the run-error taxonomy, e.g. 'tool_timeout', 'provider_rate_limited') / since (ISO timestamp) / limit. Every row carries its message, the related objects, and its context (including a fired timeout's configured budget). This is a read-only record: logs describe what happened, they never decide a run's outcome.

media_analyze

Analyze an image with a vision model and return { description, is_product_screenshot, confidence, reason, category, visual_richness }. Provide EXACTLY ONE source: url (public http(s) image) OR artifact_id (existing project artifact). Use it to vet scraped images BEFORE saving them as product screenshots: real app UI (dashboards with data, forms with inputs/buttons, tables) passes; generic marketing art (stock photos, illustrated heroes, gradients, logos) does not. visual_richness (rich | moderate | sparse) rates how much real content the pixels carry, so you can prefer a dense dashboard over a sparse crop among screenshots that all pass. The verdict comes from the pixels — never from filenames or scraped alt text. Idempotent per artifact: an already-analyzed artifact returns its recorded verdict (reused: true) without re-running the model — never re-call it for a file whose metadata.media_analysis is already in the artifacts_list inventory.

metrics_list

Read this project's registered metrics — the SAME resolver the dashboard tiles use, so your numbers and the UI's cannot disagree. Returns items with {key, label, value, groups?, window, last_updated, freshness, source, error?}. Input {project_id?, owner_kind?, owner_id?, keys?, window?, from?, to?}: owner_kind defaults to 'project' (pass a collection key + owner_id for object-owned metrics, e.g. one campaign agent); pass from+to (ISO) to cover an EXACT period (a report's period_start/period_end), or window='operating_day' for today-so-far, else the standing/lifetime read. value:null means measured-missing — render an em dash and name the gap, never 0.

project_setup_get

Get project_setup status for a project.

project_setup_health

Inspect what a project already has — Data collections, views, the agent, tasks, and stale runs — and what is still missing. Call this first on an onboarding or setup run to see the current state before writing any records, then create only what is missing (typically via data_batch).

projects_create

Create a new project in the workspace.

projects_get

Get a single project by id.

projects_list

List projects in the workspace this key is scoped to.

No arguments.

projects_update

Change a project's run mode — how much this project is allowed to do on its own. The available modes and what each permits are declared by the project's agent (e.g. Moab: paused | sandbox | live); read them back from the project or the UI. A TASK RUN CANNOT CALL THIS: raising or lowering a project's own autonomy is an operator act, so this is refused when it is called from inside an AI task turn.

render_pdf

Render markdown into a PDF artifact for the current project. Use this when the user asks for a PDF file, report, export, or downloadable document.

report_context

FIRST call of a project-report run. Returns the report row's deterministic window ({cadence, period_start, period_end, report_day} — daily = the SEND-DAY, PT midnight → now, and report_day is the day's reports record id to read with data_get; weekly = since the last delivered period; run-now override wins), plus name, destinations, recipient count, and — when the project has a daily Beast Mode checklist with published days — a server-computed checklist digest ({days, latest_items}) to COPY into the report's bottom blocks (never re-derive it).

report_publish

The ONE terminal call of a project-report run. Pass the report_id, the window you were given by report_context (period_start/period_end/cadence, echoed verbatim), and the typed blocks array (metrics | markdown | actions | divider). The platform validates the blocks, mints the action codes, and delivers the branded email + timeline event deterministically. Every actions item wants a ≤3-word label and a self-contained prompt naming the period and literal record ids — an item that misses that is DROPPED and returned in dropped_actions, it does not fail the publish. Only a payload with no metrics/markdown content at all fails, with a named report_blocks_invalid. Metric values may be numbers or strings. Publishing twice for the same window updates the same run — it never sends a second email.

save_custom_action

Create or update a Dozer custom action in the custom_actions Data collection.

skills_get

Read ONE skill's full markdown body by id (e.g. skill_id "project" for the project context doc project.md), plus exact executed source/hash provenance. Use it to inspect a skill before editing it with skills_update. Read-only.

skills_list

List the skills available to this project/workspace (id, name, category, scope, enabled). Use it to discover skill ids before reading one with skills_get or editing it with skills_update — e.g. to find the project context doc "project" (project.md). Read-only.

skills_update

Update the FULL markdown content of an editable (non-catalog) skill instance. Primary use: maintain the project's durable context doc project.md (skill_id "project") — employees, CTA/style, site facts, conventions — after research or when the user states a durable preference. Send the complete new content (this replaces the body; read the current content from your system prompt's Project Context block and patch it, do not drop sections). POSITION MATTERS for config: a config: map is parsed ONLY from a frontmatter fence that STARTS the doc — send --- as the very first line, then config: with every key nested UNDER it (two-space indented), then ---, then the markdown body. A declared config key in the body OR at the frontmatter top level is refused (config_keys_unreadable). The Project Context block shows the body with frontmatter STRIPPED, so when patching, re-add the fence and the full config: map at the top rather than appending config below. Catalog skills are read-only. Every edit is versioned with this task/run as provenance.

tasks_cancel

Cancel an active TaskRun for an existing task.

tasks_create

Create a task (optionally launching it with run:true). Returns { task_id, run_id? } and accepts backend for platform/provider/model selection.

tasks_get

Get a single task by id.

tasks_list

List tasks in a project.

tasks_messages

List durable task messages for a task.

tasks_start

Start a new TaskRun for an existing task.

tasks_status

Get a task run's status, output, and error. Address it by task_id (the task's latest run — the same thing the REST per-task status read returns) or by run_id for one specific run.

timeline_append

Append ONE authored memory to a subject's timeline (e.g. run_summary, draft_created, email_sent, goal_progress). Provide subject_type + subject_id (the object whose timeline it is), a kind, and a title. Optionally add links[] to every related object as { collection, id, rel } where rel is "subject" | "author" | "task" | "related" — one row then renders on ALL linked objects' timelines. The task/author link and run correlation are auto-filled from the current run. Do NOT write timeline_events via data_set/data_batch — use this tool. Example: {"subject_type":"agents","subject_id":"agent_meet_zest","kind":"draft_created","title":"Drafted outreach to Jennifer","links":[{"collection":"people","id":"person_jennifer","rel":"related"}]}

timeline_query

Read a subject's timeline — the memories whose subject is this object OR that link to it (OR-filter). Pass subject_type + subject_id for one object's timeline, or subject_type alone for the whole collection's activity. Optionally filter by kinds[] and page with limit/cursor.

usage_summary

Read this project's compute usage for a window: total_usd spent, a by_kind breakdown (skill id or 'chat', each with usd), and runs (distinct task runs billed). Input {project_id?, from?, to?, days?} — pass from+to (ISO or epoch ms) to cover an EXACT period, e.g. the report_context period a report tile is stamped with; otherwise days is a trailing window ending now (default 7, max 90). Read-only; the numbers come from the same usage ledger rollup the Usage explorer renders, so the two always agree.

views_get

Read ONE saved Data view (dashboard/table) definition by view_id — its collection, columns, filters, sort, and grouping. Returns the view's configuration, not its rows; fetch the rows with data_query on the view's collection. Read-only.

views_list

List the project's saved Data views — the dashboards and tables (with their collections and layouts) that operators see in the UI. Use it to discover what views exist so you can read or update one, or render the same data. Read-only.

views_update

Update the mutable fields of an existing saved Data view (dashboard/table) — such as its title, columns, filters, sort, or grouping — via a merge patch. Use views_list/views_get to find the view_id and current config first. Only allowed fields are changed.

whoami

Return the workspace and effective scopes of the calling API key.

No arguments.

workspace_current_get

Get the current MCP actor, workspace, scopes, agent, and project pin.

No arguments.

workspace_get

Get the workspace this key is scoped to.

No arguments.

workspace_invites_create

Create tracked workspace email invites or a linked per-record invite.

workspace_invites_deliver

Send a tracked workspace invite email.

workspace_invites_list

List pending workspace-wide invites.

No arguments.

workspace_members_list

List members of the workspace.

No arguments.

workspace_usage_get

Get the workspace's run/credit usage and limits.

No arguments.

On this page

IonWarp logoIonWarp

Ready to build? Connect an agent and go — no credit card needed to start.

Get startedSee our plans