MCP App Store
by KeenEthics

Overview

Moonwalk is where you write boards: pages that hold text alongside live tables, charts and interactive widgets, which you can keep private or publish as a public page. This connector lets Claude write and maintain those boards with you, and build the data and machinery behind them. What Claude can do with it: - Boards: read, search and write pages, reorganize them, and publish a board as a public page. - Data for your boards: create tables, read and write rows, and run read-only SQL queries whose results show live on a board. - Widgets: build interactive screens (charts, forms, dashboards) that sit on a board, and see a picture of what it built. - Automations: create workflows in Python that keep a board's data current, running on a schedule, from a webhook or by hand, and read each run's results. - Files: browse, search, read and edit the files in your base, and upload new ones. - Connections: see which third-party accounts and keys your base holds, and ask you to add one. Claude never sees or types a secret; you enter it in Moonwalk. Safe to hand to an agent: - Everything Claude changes is recorded as yours, with Claude noted as the agent. - Deleted boards, tables, widgets, automations and files go to a 30-day trash and can be restored. - Edits are versioned, and a batch of row changes can be undone in one step. - Tools are labeled read-only or destructive, so Claude asks before it changes anything. Requires a Moonwalk account (sign up at moonwalk.now). You sign in and approve access on Moonwalk's own screen, and can revoke it at any time from Moonwalk's Agents page.

Tools

activate_automation

ChatGPT
Lock this exact version and allow it to fire. Needs steps — the version is always there, because every edit goes into one. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

add_column

ChatGPT
Add a column to a table. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

bind_step_connection

ChatGPT
Bind a base connection to one declared key. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

change_column_type

ChatGPT
Change a column's type. Refused, naming the rows that stopped it, when a value would not survive the cast. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

clear_step_config

ChatGPT
Drop one config value, back to the declared default. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_automation

ChatGPT
Create an automation. The trigger's mode is set here and never again — a different mode is a different automation. description is required: one line a person would understand, saying what it does. It is the line its card shows, and an automation made without one is refused (422 description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_board

ChatGPT
Create a board, at the end of the list or after after. Every board is at the top level; one board links to another with a mention, never by holding it. It starts members only. The id is yours to mint. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_component

ChatGPT
Create a component. A component is one named export, export function <Name>(props), built from primitives, and may export types beside it: import { Card, Stat } from '@base/primitives' import { won } from '@base/utils' export function StatTiles({ items = [{ label: 'Total', value: 1200 }] }: { items?: { label: string; value: number }[] }) { return <Card>{items.map((i) => <Stat key={i.label} label={i.label} value={won(i.value)} />)}</Card> } A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_primitive

ChatGPT
Create a primitive. A primitive is one named export, export function <Name>(props), from react, @moonwalk/widget (its palette: usePalette()) and other primitives and utils — never a component: import { usePalette } from '@moonwalk/widget' export function Pill({ text = 'New' }: { text?: string }) { const p = usePalette() return <span style={{ color: p.sub }}>{text}</span> } A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_step

ChatGPT
Add a step. The source is linted at save: it must define a top-level run(...) and, for a code step, a ReturnType model it returns. Say why in change_description — one line a person would understand: "Skips weekends". It is the line the automation's history shows, and code saved without one is refused (422 change_description_required). A positional parameter of run(...) is an input, filled from the step's inputs list in order. {"step": "trigger", "path": [...]} reads what fired the run; {"step": "<hash>", "path": [...]} reads an earlier step's output. def run(title, file) -> ReturnType: ... inputs=[{"step": "trigger", "path": ["title"]}, {"step": "trigger", "path": ["file"]}] A count that does not match, or the same names in a different order, is refused at save (422 invalid_step). A step reaches the base's own tables through the SDK — no connection needed, and tables and columns are named by id, never by name: from mw_sdk import BaseModel, Config, Annotated, Literal, Ge, Le, Gt, Lt, MinLen, MaxLen, MultipleOf, connection_type, SecretConnection, BasicConnection, HmacConnection, AccountConnection, tables, files import uuid class ReturnType(BaseModel): written: int def run() -> ReturnType: tables.write(table_id, [ {"op": "insert", "row": str(uuid.uuid4()), "values": {column_id: value}}, ]) return ReturnType(written=1) tables.sql, tables.columns and tables.rows read; tables.write writes, and every write a run makes lands in one transaction, the run's. Undo never takes it back; on each table it touches it is a version of its own. discard_latest_version takes it back while it is still the newest, revert_version to the version before it once something is on top. An op is one of insert, set, delete, restore; row is a UUID the caller mints; values is keyed by column id. A new row lands last; rows are in order and cannot be placed. tables.sql is read-only Postgres over the base's views: a table is "v_<hex>" and a column "c_<hex>", the uuid without its dashes, so a rename never breaks a step. tables.columns(table_id) is how a step gets from a name to an id at run time rather than pasting one in. A step reads and writes files under /files, its working directory, with plain open. Pass any file name that came from outside — a trigger's input, a cell — through files.inside(folder, name) before opening it: it answers the absolute path, /files/<folder>/<name>, and raises ValueError for a name that climbs out of folder. A file field ("format": "file" on a manual trigger) hands the step the path the file was saved at, /files/Uploads/<name>. To delete a file, files.trash(path): it answers nothing, and the file waits in the base's trash for 30 days, so a mistake can be taken back. os.remove cannot be. A config (Config[T] on run) is a setting and never a credential. A key, password or token is a connection, asked for with request_connection. Each step gets 1 hour of wall time and 120 CPU-seconds, counted across every process it starts. Past either it is killed, and its step run's error_type says which: wall_time or cpu_time. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_table

ChatGPT
Create a table and its columns. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_util

ChatGPT
Create a util. A util is plain TypeScript and exports whatever it holds — export function won(n: number) { … }, export const GREEN = '#2f8f6b' — importing other utils and types from react and nothing else. Two utils may not export one name. It draws nothing, so it has no preview. A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

create_widget

ChatGPT
Create a widget from a declaration and a TypeScript screen. The screen is compiled on the way in; a refusal names every violation by line. Say why in change_description — one line, in words the person would use: "Shows the week's total above the chart". It is the line the widget's history shows for this version, and a source saved without one is refused (422 change_description_required). A screen may import react, @moonwalk/widget, @base/primitives, @base/components and @base/utils and nothing else — a part by its name — and exports its component as the default export: import { publicUrl, useFocus, usePalette, useQuery, useRun, useRunResult, useScroll, useTheme } from '@moonwalk/widget' export default function Tasks() { const tasks = useQuery('tasks') // a key of declaration.data const move = useRun('move') // a key of declaration.runs const collect = useRunResult() // a run answered strt, asked again by its id const theme = useTheme() // 'light' or 'dark' const palette = usePalette() // the kit's colours, in that theme const scroll = useScroll() // 0 → 1 as the page scrolls this block past const focus = useFocus() // false while the reader is in another window if (!tasks.rows) return <p>Loading…</p> return ( <> <audio src={publicUrl('theme.mp3')} controls /> {/ /files/Public/theme.mp3 /} <ul style={{ color: palette.text }}>{tasks.rows.map((t) => <li key={t.id}>{String(t.title)}</li>)}</ul> </> ) } The <Screen> provider is mounted around it for you; a screen never renders one. useQuery gives {rows, broken} and nothing that writes. There is no fetch, no token and no storage — the broker is the only way in or out. Build a widget from parts. Save utils and primitives first, then the components made of them, and the widget last, importing them — import { StatTiles } from '@base/components'. Each part appears on the person's screen as it is saved, so the build is watched; and the widget's own source stays short. Parts take props only: the widget reads and runs, and hands them rows and callbacks. create_component, create_primitive and create_util say the rest. A widget whose parts changed under it and no longer compiles keeps its last good build, with behind naming why. useRun gives a function resolving to {run_id, status, returncode, output}. status is fin (it ended) or strt (still going past the server's 3-second wait — not a failure). fin does not mean it worked: check status === 'fin' && returncode === 0. rej never reaches a screen — a refused run rejects the promise instead. output is the JSON object the automation's last step returned — its ReturnType — so read the field you want: run.output.message. It is null while strt and when the last step failed, and past 16 KB it is {"$over": <bytes>}: a run answers, it does not hand over a dataset. get_widget reports each run's output_schema. A run answered strt can be collected later: useRunResult()(run.run_id) resolves the same shape. A run may take a file. A trigger property marked {"type": "string", "format": "file"} takes one, and a screen passes a File at the top level of input — useRun('import')({ book: file, language: 'en' }). It goes as bytes in the one request, is saved into /files/Uploads/, and the step is handed the path it was saved at. Nothing in the SDK is new for it: an <input type="file"> and the File it yields. This is the one thing you cannot do yourself — fire_automation names a path because MCP carries no bytes, and the browser is the caller that sends them. A file past 100 MB is refused, 413 too_large. A screen loads a file from the base's Public/ folder by naming it: <audio src={publicUrl('theme.mp3')} controls /> plays /files/Public/theme.mp3. Images and fonts load the same way. Only files in Public/ can be named like that, and anybody can open them, signed in or not, so moving a file in is publishing it. The screenshot a save answers with does not load them. A declaration is data and runs. A widget reads and runs, and does nothing else — there is no way…

deactivate_automation

ChatGPT
Stop it firing and unlock it for editing. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_automation

ChatGPT
Trash an automation. Its steps, runs, versions and files are kept and nothing fires it; restore_automation brings it back with its trigger live. Refused while a widget binds it, naming the widgets. One with no steps that nothing but your own open sitting ever touched is deleted outright instead, and has no way back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_board

ChatGPT
Trash a board with everything on it. restore_board brings it back; list_trash with board shows it. While it is in the trash its view link answers not-found. One with nothing in it that nothing but your own open sitting ever touched is deleted outright instead, and has no way back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_column

ChatGPT
Drop a column. Never refused — every query naming it stops running and says so. restore_column takes it back, with its values — and so do undo, to the place it held, and reverting the table to a version from before the drop. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_component

ChatGPT
Trash a component. Refused while anything imports it (409 in_use, naming what does). restore_component brings it back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_connection

ChatGPT
Delete a connection. Refused while a step is bound to it. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_file

ChatGPT
Move a file, or a directory and everything in it, into the base's trash, where it waits 30 days. It leaves the tree — list_trash with kind="file" is where it is now, and restore_file takes the id from there and puts it back where it was. Never the root, /files/Uploads or /files/Public. Nothing you do deletes a file for good. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_primitive

ChatGPT
Trash a primitive. Refused while anything imports it (409 in_use, naming what does). restore_primitive brings it back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_step

ChatGPT
Delete a step and everything under it — an if takes both branches. Refused while a step left behind reads one that goes; rewire or delete that step first. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_table

ChatGPT
Trash a table. restore_table brings it back — unless the table held no rows and nothing but your own open sitting ever touched it, which is deleted outright and has no way back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_util

ChatGPT
Trash a util. Refused while anything imports one of its exports (409 in_use, naming what does). restore_util brings it back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

delete_widget

ChatGPT
Trash a widget. restore_widget brings it back. Refused while a board still draws it, naming the blocks. One with no source that nothing but your own open sitting ever touched is deleted outright instead, and has no way back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_board

ChatGPT
Apply a batch of block operations to one board — the only way to write, delete or reorder a block. One call is one transaction. A heading is a heading block: its text, and level 1, 2 or 3 in props. A set at ["type"] turns a paragraph into a heading or back and keeps the block's id — send the level with it. A value box is a text chunk {"value": {"sql": …, "description": …}}: one cell of a query, drawn live inside a sentence. Always both fields, the description one line. Rows on a board are a widget's job: make one with create_widget and put a widget block on the board. A text chunk may instead be {"mention": "<board id>"}: a live board of this base, drawn as its current title. It stores no title, and anything else it names is refused with mention_invalid. A board is never a block of another board. Marks sit flat on a chunk: bold, italic, underline, code, strike, link, and color for the ink and background for a wash behind it. A colour is a name, never a hex — grey, brown, orange, yellow, green, blue, purple, pink or red — and the two are independent. An image block's props are exactly one of {"path": "/files/…"}, a picture in the base's files, or {"url": "https://…"}, one on the web. A path is copied into the block and shrunk to 4000 px, so moving or deleting the file later changes nothing; it is stored as image, width and height, and the answer's stored says so. A URL is drawn live and breaks when its site does. PNG, JPEG, GIF and WebP only. To put a local file on a board, request_upload it and name the path you get back. The description is for the person, not for you: what the query asks, in the words someone would use to ask for it — "Tasks still open, newest first". The SQL is physical names in hex and nobody can read it, so this is the only readable record of what the block draws, and a block saved without one is refused. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_column

ChatGPT
Rename a column, or set a select's options. options is the full list: keep an option by its id, relabel it under the same id, add one with a label only, leave one out to remove it. Ids never change, so nothing naming them breaks. An option a row still holds cannot be removed. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_component

ChatGPT
Replace old with new in a component's source, leaving the rest byte for byte, and save it. old must appear exactly once — include enough of the lines around it — unless replace_all. A refused edit saves nothing. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_file

ChatGPT
Replace old with new in a text file, leaving the rest of it byte for byte. old must appear exactly once — include enough of the lines around it to make it unique — unless replace_all. Nothing changes when the edit is refused, and the answer says why. To write a whole file, use write_file. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_primitive

ChatGPT
Replace old with new in a primitive's source, leaving the rest byte for byte, and save it. old must appear exactly once — include enough of the lines around it — unless replace_all. A refused edit saves nothing. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_util

ChatGPT
Replace old with new in a util's source, leaving the rest byte for byte, and save it. old must appear exactly once — include enough of the lines around it — unless replace_all. A refused edit saves nothing. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

edit_widget

ChatGPT
Replace old with new in a widget's screen source, leaving the rest byte for byte, and save it — answered as update_widget is, with the picture. old must appear exactly once — include enough of the lines around it — unless replace_all. A refused edit saves nothing. Say why in change_description — one line, in words the person would use: "Shows the week's total above the chart". It is the line the widget's history shows for this version, and a source saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

execute_code

ChatGPT
Run a Python snippet in this base's sandbox and return its exit code, stdout and stderr. dependencies are pip requirements installed into a fresh venv; the first call for a given set takes about a minute. A snippet gets the same limits as a step: 1 hour of wall time and 120 CPU-seconds, counted across every process it starts. Past either it is killed, and killed_by says which: wall_time or cpu_time. cpu_ms and wall_ms are what the CPU and wall-time limits count: every process it started, from the moment it was sent. Installing its dependencies comes first and is in neither, so a first run can take a minute and report a few hundred ms. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

fire_automation

ChatGPT
Fire an automation by hand, whether it is on or off. Returns the run id at once — read the run to find out what happened. A file field ("format": "file") takes the path of a file already in the base — /files/Uploads/book.pdf; request_upload is how a file from your own machine gets there. You are the one caller that names a path; every other sender of a run, a widget's screen included, sends the file itself. 422 file_not_found for a path that is not a file. Each step gets 1 hour of wall time and 120 CPU-seconds, counted across every process it starts. Past either it is killed, and its step run's error_type says which: wall_time or cpu_time. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_account_action

ChatGPT
One action of a linked account: its argument JSON Schema in input_parameters, plus its output shape and its scopes. Read it before writing the call rather than guessing at argument names. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_automation

ChatGPT
One automation: its step tree, its trigger and its state. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_board

ChatGPT
One board: its blocks, who may view it, and the ref of its view link. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_component

ChatGPT
One component: its source, the parts it uses, what uses it, and what standing on it does not build now. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_connection_request

ChatGPT
How an ask was answered: pending or filled, and — once filled — the connection that was actually made, which may not be the name you asked for. 404 no_such_request once the person declined it, expired once the hour is up. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_primitive

ChatGPT
One primitive: its source, the parts it uses, what uses it, and what standing on it does not build now. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_run

ChatGPT
One run: its status, its timings, what it received (input) and what it returned (output). Either is {"$over": <bytes>} past 16 KB. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_run_steps

ChatGPT
One row per executed step, in execution order — what you debug a run from. cpu_ms and wall_ms are what the CPU and wall-time limits count: every process it started, from the moment it was sent. Installing its dependencies comes first and is in neither, so a first run can take a minute and report a few hundred ms. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_step_configs

ChatGPT
What a step declares as config, and the values saved against it. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_step_connections

ChatGPT
What a step declares as connections, and which base connection is bound to each key. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_step_source

ChatGPT
The Python source of one step, as it is on disk. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_table

ChatGPT
One table and every column on it, with each column's type. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_util

ChatGPT
One util: its source, the utils it uses, what uses it, and what standing on it does not build now. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_version

ChatGPT
One version, and what it changed against the version before it. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_webhook_secret

ChatGPT
Where the person gets a webhook trigger's signing secret, never the secret itself. Show them the url: on that screen they press the eye on the trigger and copy the secret to paste upstream. secret_set is false while an upstream secret has not been pasted in. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_widget

ChatGPT
One widget: its declaration, its screen source and its build hash. An empty source is a stub — a name waiting for you to write its screen with update_widget. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

get_widget_data

ChatGPT
Run every data query a widget declares and return the rows. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

grep

ChatGPT
Find lines matching a regular expression (Python re) inside the base's files, dotfiles included, and answer each hit's path, line number and text. Case-sensitive unless case_insensitive. path is the folder to search under; glob narrows which files are read, matched the way search_files matches. Binary files, files too large to preview and lines over 10,000 characters are skipped. At most 100 hits; truncated says there were more. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_account_actions

ChatGPT
What a linked account can do: every action slug a step may call through it, narrowed by search. 409 not_an_account for a connection that was typed rather than clicked — only an account has a catalogue. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_automations

ChatGPT
Every automation in the base, with its steps and trigger. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_bases

ChatGPT
The Moonwalk bases you can reach, as {id, name}, oldest first. Every other tool acts on one of them and takes its id as base_id, read_overview optionally. More than one base means the person's words may fit either.

list_boards

ChatGPT
Every board of the base, in sidebar order, with who may view each and the ref of its view link. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_components

ChatGPT
Every live component in the base. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_connection_requests

ChatGPT
Every ask in the base still waiting on the person — yours, another chat's, or one made over /api/mcp — with its name, kind, who asked, why, and when it runs out (expires_at). The list the Connections dot reads. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_connections

ChatGPT
Every connection the base holds. The fields never come back out. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_files

ChatGPT
One directory of the base's tree. A path is absolute from /files, the root — /files/notes/todo.md — and every answer spells it that way. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_primitives

ChatGPT
Every live primitive in the base. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_rows

ChatGPT
Rows of one table, by limit and offset. To filter, sort, group or join, write SQL — run_sql. The database screen's own filter is the UI's and adds nothing an agent holding SQL does not already have. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_runs

ChatGPT
An automation's runs, newest first. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_services

ChatGPT
The services an account can be linked for, searched by name — the Connections screen's picker. Look the slug up here before request_connection with account rather than guessing it. 503 not_configured means no account can be linked on this stack at all. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_steps

ChatGPT
Every step of an automation, in tree order, with its inputs. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_tables

ChatGPT
Every live table in the base. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_trash

ChatGPT
What one section has in its trash, newest first, each with when it goes for good (purge_at, 30 days after it was deleted). file lists a deleted folder and not what was in it, and each row carries the path it came from — which is what tells two files of one name apart. Restore with restore_board, restore_widget, restore_automation, restore_table or restore_file — or restore_component, restore_primitive, restore_util — each of which takes the id of a row here. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_utils

ChatGPT
Every live util in the base. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_versions

ChatGPT
A board's, a table's, a widget's or an automation's versions, newest first. One writer's writes inside ten minutes of each other are one version, and each row's actor_kind and via say whose: you, the person, or a run. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_widget_errors

ChatGPT
What went wrong with a widget, newest first, each with its kind: undeclared_data and undeclared_run for a read or run its declaration never named, automation_gone for a declared run whose automation has left, render for a screen that threw, compile for a save the compiler refused. A run's own failure is not here — get_run has it. limit is capped at 200. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

list_widgets

ChatGPT
Every live widget in the base, by name and size. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

mkdir

ChatGPT
Make one directory, whose parent must already be there. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

move_board

ChatGPT
Put a board after after in the list, or first when after is null. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

move_file

ChatGPT
Move or rename an entry. to is the whole new path. Never /files/Uploads itself, and never in or out of the trash. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

next_undo

ChatGPT
What undo would take back, without taking it: the transaction, how many rows, and how many changes of each kind — drop or add for a column. undo takes the newest write of the member you act for — theirs in the browser as much as yours — so read this first when that matters. {"ok": true} when there is nothing to undo. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

read_file

ChatGPT
A file's text. An image comes back as a picture you can see: encoding image, and the picture, shrunk to 2000 px. Any other file that is not UTF-8, or is too large, comes back as binary with no text. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

read_overview

ChatGPT
How a Moonwalk base works: the rules no single tool states. Pass base_id to also get what that base holds.

read_screen

ChatGPT
Which screen the person last had open in this base's web app: its section (boards, database, widgets, …), the id and name of what was open, and line, one sentence saying so. seconds_ago is how long since the tab reported it — it reports on moving and on coming back into view, so an old one most likely means the person has moved on to another window. {"screen": null} means this person has never had the base open. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

rename_column

ChatGPT
Rename a column. A label edit — nothing in the database moves. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

rename_table

ChatGPT
Rename a table. Its columns and rows are untouched. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

request_connection

ChatGPT
Ask the person for a credential you must never see. Name the connection you want and why: secret, basic or hmac for a key they type, or account for a service they connect by clicking — then provider is the service's slug, like gmail. Never ask for an API key, password or token in the conversation, and never accept one there. In the chat panel a box asks them under your message, and their answer comes back to you as the next message: stop and wait for it. Anywhere else, show them the URL this answers and stop; then poll get_connection_request. The name is a proposal — bind steps to the name the answer gives, not the one you asked for. For a key, how_to_get is required: the path to it from where the person starts, as site > page > button, like platform.openai.com > API keys > Create new secret key. Add how_to_get_url, like https://platform.openai.com/api-keys, when you know the page. It shows in the box where they type the key, so write it for someone who has never done it. When you're not sure of the path, say so in it rather than inventing one. An account takes neither. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

request_upload

ChatGPT
Get a one-time link for sending a file from your own machine into the base — MCP carries no bytes, so this is how one gets in. Run the command it answers with your file's path in place of the placeholder; the upload answers {"path": "/files/Uploads/…"}, which is what a file field in fire_automation takes. The link works once, for 5 minutes. If the upload cannot connect, do what the note says. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_automation

ChatGPT
Bring a trashed automation back, its trigger live again. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_board

ChatGPT
Bring a board out of the trash, at the end of the list, as it was: a published one is served at its address again. list_trash names what is there. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_column

ChatGPT
Take a dropped column back under the same id, with every value it held. Every stored query naming it runs again with no edit. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_component

ChatGPT
Bring a trashed component back. It is saved again, so it is refused when its name was taken meanwhile or it no longer compiles. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_file

ChatGPT
Put a trashed entry back where it came from, under the name it had. id is a row's from list_trash, not a path. Refused when something is at that path now. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_primitive

ChatGPT
Bring a trashed primitive back. It is saved again, so it is refused when its name was taken meanwhile or it no longer compiles. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_table

ChatGPT
Bring a trashed table back, if its name is still free. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_util

ChatGPT
Bring a trashed util back. It is saved again, so it is refused when its name or an export was taken meanwhile, or it no longer compiles. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

restore_widget

ChatGPT
Bring a trashed widget back. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

revert_version

ChatGPT
Put the resource back as an older version had it, as a new version — nothing is removed. A table goes back whole, other people's later writes included. An automation's configs and bindings do not survive it, and it is refused while the automation is active (409 locked). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

run_sql

ChatGPT
Run read-only SQL against this base's tables. Ordinary Postgres — joins, GROUP BY, date_trunc, window functions, now(). Names are physical and derived from ids, so a rename never breaks a query: a table is the view "v_<hex>" (get_table gives the ids; the hex is the uuid without dashes) and a column is "c_<hex>". Select id when you want the rows to be writable or numbered. A select/multi_select value is an option id, not its label. Writes are refused by the database itself, not by a check here: there is one role per base, granted SELECT on its views and nothing else. Use write_rows to change anything. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

screenshot_board

ChatGPT
A picture of a board's body as a visitor reads it — its text, pictures, value boxes and widgets, drawn from the rows they read now — 1280 pixels wide. A picture from a URL draws as not loaded. Who may view the board changes nothing: it stays as it was. Nothing is written and no run is fired. A board taller than 1200 pixels comes back one page at a time: the answer says page of pages, and page: 2 is the next 1200 pixels, and so on to the end. Each call draws the board afresh. A page past the last is refused, naming how many there are. theme picks light (the default) or dark. thrown is anything a widget threw while it drew. When it cannot be drawn the answer is {"screenshot": {"unavailable": <reason>}}. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

screenshot_widget

ChatGPT
A picture of a widget as it looks now, drawn from the rows it reads now — the same picture, four sizes and thrown a save answers with, without saving. For a widget whose rows may have changed since it was last saved; a save already answers with one. Nothing is written and no run is fired: while it draws, every run is refused not while previewing. theme picks light (the default) or dark. A stub answers {"screenshot": null}, and one that cannot be drawn {"unavailable": <reason>}. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

search_boards

ChatGPT
Boards whose title holds q — the sidebar's filter. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

search_files

ChatGPT
Find files and folders by a glob, without listing folders one by one. A pattern with no / matches a name at any depth (*.md); one with a / matches the path from path, ** descending (notes/**/*.md), or from the root when it starts /files/. Dotfiles are included. At most 100 answers. Documented at https://docs.moonwalk.now/tools.html#files. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

set_board_lock

ChatGPT
Lock a board, or unlock it. A locked board refuses every edit to its title and its body — edit_board answers board_locked — for everyone, until somebody unlocks it. Moving, trashing and its visibility still work. Unlock only when the person asked you to change that board. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

set_board_visibility

ChatGPT
Who may open a board's view link, /b/<name>-<token>: members of this base, signed in, or anybody with the link, signed in or not — public. Every board has the link from the moment it is made, and it never changes: only the token is read, so a rename never breaks a link already handed out. The answer's path is that link. Make a board public only when the person asked for it to be public. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

set_step_config

ChatGPT
Set one config value, checked against the step's declaration. A config (Config[T] on run) is a setting and never a credential. A key, password or token is a connection, asked for with request_connection. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

set_webhook_secret

ChatGPT
Where the person pastes the upstream's signing secret, never the secret itself. Show them the url: on that screen they paste it into the trigger; never ask for it in the conversation. Refused (409 system_generated) when Moonwalk made the secret; that one is copied, with get_webhook_secret. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

unbind_step_connection

ChatGPT
Unbind whatever is on one declared key. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

undo

ChatGPT
Take back the newest transaction of the member you act for — one this session just made, or one they made in the browser; next_undo says which before you call it. A row write, or a column dropped or added: a dropped column comes back where it was, with its values. Cells another write has since changed are skipped and reported, never overwritten. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_automation

ChatGPT
Rename an automation or change its description. A blank description is refused (422 description_required); leave it out to keep the one there. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_component

ChatGPT
Replace a component's name, source or both, each whole. Its name is the function its source exports, so a new name comes with the source that exports it. To change a few lines, edit_component sends less. A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_primitive

ChatGPT
Replace a primitive's name, source or both, each whole. Its name is the function its source exports, so a new name comes with the source that exports it. To change a few lines, edit_primitive sends less. A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_step

ChatGPT
Replace a step's name, source, dependencies or inputs. Say why in change_description — one line a person would understand: "Skips weekends". It is the line the automation's history shows, and code saved without one is refused (422 change_description_required). Each step gets 1 hour of wall time and 120 CPU-seconds, counted across every process it starts. Past either it is killed, and its step run's error_type says which: wall_time or cpu_time. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_trigger

ChatGPT
Edit the trigger within its mode: output schema, run-record limit, and that mode's own field. The mode itself is fixed, and there is no on/off here: whether it fires is activate_automation. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_util

ChatGPT
Replace a util's name, source or both, each whole. To change a few lines, edit_util sends less. A widget is built from the base's parts, three kinds in layers: primitives (Card, Button) → components built of them (StatTiles) → widgets, with utils (formatters, constants) beside them, usable by all three. A screen imports them as @base/primitives, @base/components and @base/utils, always by name: import { Card } from '@base/primitives'. A primitive may import primitives and utils, and usePalette and useTheme from @moonwalk/widget; a component, those and other components; a util, other utils and types from react. Everything a part exports is reached through its kind's module, so a name — Props, say — is exported by one part of a kind only. Build in order: utils and primitives first, then components, the widget last. Each part appears on the person's screen as it is saved, drawn, so the build is watched rather than arriving whole at the end. Props only. A part never imports useQuery, useRun or useRunResult: the widget reads and runs, and hands its parts rows and callbacks. Every prop has a default — a component or a primitive is drawn alone as <Name /> for its preview, so a prop without one does not compile. It must not position itself either: the widget places it. Names are one capitalised word, unique across all three kinds. A save is compiled against the parts it uses and refused with every error by line (422 contract_violation). Then everything standing on it is rebuilt; what no longer compiles keeps its last good build and is behind — behind on the answer lists it, error on a part and behind on a widget say why. Renaming a part leaves what imports the old name behind until you fix it. Say why in change_description, one line in the person's words: it is the line the part's history shows, and code saved without one is refused (422 change_description_required). This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

update_widget

ChatGPT
Replace a widget's name, declaration, source or size — any of them in one save. Each is replaced whole, never merged. To change a few lines of the source, edit_widget sends less. Say why in change_description — one line, in words the person would use: "Shows the week's total above the chart". It is the line the widget's history shows for this version, and a source saved without one is refused (422 change_description_required). Build a widget from parts. Save utils and primitives first, then the components made of them, and the widget last, importing them — import { StatTiles } from '@base/components'. Each part appears on the person's screen as it is saved, so the build is watched; and the widget's own source stays short. Parts take props only: the widget reads and runs, and hands them rows and callbacks. create_component, create_primitive and create_util say the rest. A widget whose parts changed under it and no longer compiles keeps its last good build, with behind naming why. useRun gives a function resolving to {run_id, status, returncode, output}. status is fin (it ended) or strt (still going past the server's 3-second wait — not a failure). fin does not mean it worked: check status === 'fin' && returncode === 0. rej never reaches a screen — a refused run rejects the promise instead. output is the JSON object the automation's last step returned — its ReturnType — so read the field you want: run.output.message. It is null while strt and when the last step failed, and past 16 KB it is {"$over": <bytes>}: a run answers, it does not hand over a dataset. get_widget reports each run's output_schema. A run answered strt can be collected later: useRunResult()(run.run_id) resolves the same shape. A run may take a file. A trigger property marked {"type": "string", "format": "file"} takes one, and a screen passes a File at the top level of input — useRun('import')({ book: file, language: 'en' }). It goes as bytes in the one request, is saved into /files/Uploads/, and the step is handed the path it was saved at. Nothing in the SDK is new for it: an <input type="file"> and the File it yields. This is the one thing you cannot do yourself — fire_automation names a path because MCP carries no bytes, and the browser is the caller that sends them. A file past 100 MB is refused, 413 too_large. A screen loads a file from the base's Public/ folder by naming it: <audio src={publicUrl('theme.mp3')} controls /> plays /files/Public/theme.mp3. Images and fonts load the same way. Only files in Public/ can be named like that, and anybody can open them, signed in or not, so moving a file in is publishing it. The screenshot a save answers with does not load them. A declaration is data and runs. A widget reads and runs, and does nothing else — there is no way to write a row through a query, so a data entry has no mode and a declaration carrying one is refused. Each declaration.data entry is two fields: sql and description. The SQL is read-only Postgres over this base's views — "v_<hex>" for a table and "c_<hex>" for a column, both derived from ids, so a rename never breaks one. Alias every column to the key the screen reads, and select id when the screen needs a row to name in a run. The description is for the person, not for you: what the query asks, in the words someone would use to ask for it. The SQL is hex and nobody can read it, so this is the only readable record, and an entry without one is refused. Each declaration.runs entry is the screen's name for it → the id of an automation that already exists in this base. Its trigger must be manual: a cron or webhook trigger fills its own payload, so a screen has nothing to supply. useRun('move')(input) fires it with input as the trigger's output, so input has to fit that trigger's output_schema — read it back off get_widget, which reports each run as {automation_id, automation_name, input_schema, output_schema}, the last being what the run's output holds. Build the a…

withdraw_connection_request

ChatGPT
Take a pending ask back, when the person asked you to drop it or you no longer need it. It removes any pending ask in the base, not only your own — list_connection_requests says who asked. Nothing is woken, not even the chat that asked: it learns from get_connection_request's 404, the way it learns of an expiry. 409 already_answered once filled. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

write_file

ChatGPT
Write a whole text file, making or replacing it. The parent must exist, except under /files/.agent/memory/, whose folders are made. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

write_rows

ChatGPT
Insert, set, delete or restore rows of one table. One call is one transaction and one undo step, however many rows it touches. A new row lands last; rows are in order and cannot be placed. This is Moonwalk. base_id is an id from list_bases. The rules of a Moonwalk base that no single tool states are in read_overview.

activate_automation

Claude

add_column

Claude

bind_step_connection

Claude

change_column_type

Claude

clear_step_config

Claude

create_automation

Claude

create_board

Claude

create_step

Claude

create_table

Claude

create_widget

Claude

deactivate_automation

Claude

delete_automation

Claude

delete_board

Claude

delete_column

Claude

delete_connection

Claude

delete_file

Claude

delete_step

Claude

delete_table

Claude

delete_widget

Claude

discard_latest_version

Claude

edit_board

Claude

edit_file

Claude

execute_code

Claude

fire_automation

Claude

get_account_action

Claude

get_automation

Claude

get_board

Claude

get_connection_request

Claude

get_run

Claude

get_run_steps

Claude

get_step_configs

Claude

get_step_connections

Claude

get_step_source

Claude

get_table

Claude

get_version

Claude

get_webhook_secret

Claude

get_widget

Claude

get_widget_data

Claude

grep

Claude

list_account_actions

Claude

list_automations

Claude

list_bases

Claude

list_boards

Claude

list_connection_requests

Claude

list_connections

Claude

list_files

Claude

list_rows

Claude

list_runs

Claude

list_services

Claude

list_steps

Claude

list_tables

Claude

list_trash

Claude

list_versions

Claude

list_widget_errors

Claude

list_widgets

Claude

mkdir

Claude

move_board

Claude

move_file

Claude

next_undo

Claude

read_file

Claude

read_overview

Claude

read_screen

Claude

rename_column

Claude

rename_table

Claude

request_connection

Claude

request_upload

Claude

restore_automation

Claude

restore_board

Claude

restore_column

Claude

restore_file

Claude

restore_table

Claude

restore_widget

Claude

revert_version

Claude

run_sql

Claude

screenshot_board

Claude

screenshot_widget

Claude

search_boards

Claude

search_files

Claude

set_board_lock

Claude

set_board_published

Claude

set_step_config

Claude

set_webhook_secret

Claude

unbind_step_connection

Claude

undo

Claude

update_automation

Claude

update_step

Claude

update_trigger

Claude

update_widget

Claude

withdraw_connection_request

Claude

write_file

Claude

write_rows

Claude

Capabilities

Writes

Example Prompts

Click any prompt to copy it.

App Stats

204

Tools

3

Prompts

ChatGPT, Claude

Platforms

Works with

ChatGPT
Claude

Data refreshed daily