Reference · Tools for AI clients
about
about(str, map, str | null) -> str | nullWhat it does
In a tool (fn mcp), asks the person at the AI client to pick one of choices, a map from
a key to the text they see, and gives the key they picked. default is one of the keys, or
null for none, and is always written. The call stops at the question as at
confirm: the client is sent a form with the choices, asks the
person, and calls the tool again with the answer, and the function runs again from the top,
this time getting the key. A client that cannot ask gets default, and the tool's result
says so, so the model can tell the person. Outside a tool's call (the program's own code, or
a page calling a server fn mcp) it gives default at once. See Tools for AI
clients.
Examples
/// Publishes a post. It is public at once.fn mcp publish_post(title: str, body: str) -> int with db { let who = about("Who can see it?", { public: "Everyone", draft: "Only me, as a draft" }, "draft") if !confirm(`Publish "${title}" now?`) { return err("not published: the user said no") } db.one("insert into posts (title, body, draft) values (?, ?, ?) returning id", title, body, who == "draft").id}The client shows Who can see it? with the two texts, Only me, as a draft chosen to
start; then the box Publish "..." now?. With a client that cannot show a form, about
takes the default, and a tool that goes on to its answer adds the line the user was not asked "Who can see it?": the default "Only me, as a draft" was taken to its result; this
one stops at confirm instead, which needs a yes (this needs the user's yes, and this client cannot ask). Outside a tool's call the default is the answer:
print(about("Who can see it?", { public: "Everyone", draft: "Only me, as a draft" }, "draft"))print(about("Which colour?", { red: "Red", blue: "Blue" }, null))draftnullEdge cases
defaultis one of the choices' keys, ornullfor none (then nothing is picked to start, and a client that cannot ask getsnull).quillo checkrefuses a default that is not a key and choices that are empty, and the call stops on them as it runs.- A person who declines or dismisses the question ends the call, with an
isErrorsaying so (the user declined to answer: Who can see it?). - It never asks for free text, only for a choice, as MCP forbids asking for passwords, keys or payment details in a form.
- Ask first. A tool asks before it changes anything, as with
confirm; the same rules hold: the signed state (10 minutes, once, for the same caller, tool and arguments), at most 100 questions or rounds in a call, a question after a change refused. - A question the checker does not see a tool ask, as in a function given to a builtin (a
locale_fromortenant_fromrule), is refused as it runs and the call stops: no one was asked, so no default is given. - A component cannot use it: a page asks its visitor with ask, the
page's dialog.
askwith three arguments is an error that namesabout. - A program's own function named
aboutis warned of, as any that hides a builtin, and its own is used.
See also
confirm, ask, mcp_token, Tools for AI clients
Thread 0 posts
On about(): questions, tips, corrections, and code that uses it.
No posts yet. The first one opens the thread.
Edit this page on GitHub · every example's output was made by running it (tools/refcheck.mjs) · questions on Discord or r/quillo