Tools
Every tool works on the signed-in account only, and every item it returns links to its source on Upvera. Results come back as structuredContent with a short text summary.
upvera_whoami
The Upvera account this connection acts for.
| Scope | read:own |
| Input | none |
| Returns | handle, display name, profile URL, plan name |
| Hints | read-only, idempotent |
list_my_startups
Startups you own or are a member of, as owner, poster or launcher.
| Scope | read:own |
| Input | none |
| Returns | for each startup: name, slug, stage, your role, last post date, URL |
| Hints | read-only, idempotent |
get_startup_status
One of your startups in one call.
| Scope | read:own |
| Input | startup (string, 1 to 80 characters): the id or slug from list_my_startups |
| Returns | identity, the 10 most recent published posts, proof sources with their verification status and source links, public value with the latest receipt |
| Hints | read-only, idempotent |
Asking about a startup that isn't yours returns: That startup is not one of yours. Use list_my_startups to see the ones you can read.
get_build_trail
Recent commits from the repositories connected to your startups, newest first. Messages are trimmed and secrets are removed.
| Scope | read:own |
| Input | since (optional, ISO date such as 2026-10-13): defaults to 14 days back, at most 30 |
| Returns | since and up to 60 commits, each with repo, sha7, message (first line, up to 200 characters), at and url. Merge commits are skipped |
| Hints | read-only, idempotent |
create_draft
Saves a draft to your Hatch. It is never published automatically: you review it and publish it in the app.
| Scope | write:drafts |
| Input | title (1 to 120 characters) · body (1 to 8,000 characters) · commit_sha (optional, 7 to 40 hex characters) · startup (optional, id or slug) · idempotency_key (optional, up to 120 characters) |
| Returns | note_id, created (false when the key matched an earlier draft) and open_url, which opens the draft in the app |
| Hints | not read-only, not destructive, idempotent |
Send the same idempotency_key when you retry, and you get the same draft back instead of a second one.
prepare_post
Prepares a post on your account and shows it in a preview card. Nothing is published by this tool.
| Scope | write:drafts |
| Input | body (1 to 500 characters) · startup (optional, id or slug; required for an update) · kind (post or update, default post) · idempotency_key (optional, up to 120 characters) |
| Returns | draft_id, status, needs_site with its reasons, and the preview: author, startup, kind and the locked text |
| Hints | not read-only, not destructive, idempotent |
The text is cleaned and locked on Upvera's side and bound to a content hash, so the card publishes exactly what it shows. Hidden direction-override and zero-width characters are rejected; emoji, including joined emoji, are kept.
needs_site is true for your first post from an assistant, a post with a link or an @mention, and while posting from assistants is switched off. Then the card offers Confirm in Upvera, which opens Upvera's own compose screen with the text filled in.
publish_post and undo_post
These two run only from the preview card, when you press Publish or Undo. They are marked as app-only, so clients do not list them to the model, and they need the optional publish:posts scope. Posting from the card is rolling out.
publish_post | undo_post | |
|---|---|---|
| Scope | publish:posts | publish:posts |
| Input | draft, plus a one-time ticket and the content hash that the card holds | draft |
| Returns | post_id, url, undo_until | undone |
| Hints | destructive, open world | destructive, idempotent |
A post can be undone for 10 minutes. After that it stays, and you can delete it in the app like any post.
Errors
A tool error comes back as a normal result with isError: true and one sentence that says what to do next.
| Reason | Message |
|---|---|
not_member | That startup is not one of yours. Use list_my_startups to see the ones you can read. |
not_found | Nothing was found for that id or slug. |
rate_limited | Too many requests right now. Wait a minute and try again. |
shed | Upvera is shedding load right now. Try again in a few minutes. |
invalid | The request was not valid. Check the arguments and try again. |
disabled | Posting from AI assistants is turned off right now. The user can publish it in Upvera. |
needs_site | This post has to be confirmed in Upvera by the user. |
expired | This preview expired. Prepare the post again. |
mismatch | This preview is no longer valid. Prepare the post again. |
used | This prepared post was already used. |
too_late | The undo window has passed. The post can be deleted in the Upvera app. |
timeout | Upvera took too long to answer. Try again. |
A typical session
› Draft today's Kiln update from my commits
⏺ upvera · list_my_startups()
Kiln (kiln-…) · owner · last post 2 days ago
⏺ upvera · get_build_trail(since: "2026-10-19")
7 commits · "checkout fits on one screen" …
⏺ upvera · create_draft(title: "Checkout fits on one screen", startup: "kiln-…", commit_sha: "a3f9c1e", …)
✓ Draft saved to Hatch · open it in Upvera to publishUpdated 2026-10-19