Skip to content

document Cloud tools, MCP, and multi-user identity - #813

Merged
Aditya-thesys merged 9 commits into
mainfrom
ap-cloud-tools-multiuser
Jul 22, 2026
Merged

document Cloud tools, MCP, and multi-user identity #813
Aditya-thesys merged 9 commits into
mainfrom
ap-cloud-tools-multiuser

Conversation

@Aditya-thesys

Copy link
Copy Markdown
Contributor

What

Describe the change and why it is needed.

Changes

Test Plan

Describe how you validated this change.

  • Not applicable (explain why)
  • Verified locally

Checklist

  • I linked a related issue, if applicable
  • I updated docs/README when needed
  • I considered backwards compatibility

- SKILL.md: add an OpenUI Cloud capability matrix (Responses-compatible
  endpoint, out-of-box tools, artifact editing auto-enabled, fct_ storage
  plane) and trigger keywords for MCP / custom tools / multi-user queries
- cloud-integration.md: two new runbook steps — 'Add Tools and MCP'
  (server-side tool table, remote MCP example, the app-owned function-tool
  loop contract and its two safety rules) and 'Multi-User and Multi-App
  Convention' (fct_ scope binding, APP_ID identity, ownership checks,
  brownfield recipe); mint example now sends app_id; new verify items
- oss-to-cloud-migration.md: custom tool execution is now documented as
  supported via the template loop instead of a hard boundary
…d fixes

- ship src/lib/tool-loop.ts (runFunctionToolLoop): executes only declared
  tool names and skips calls already answered on the stream, so app tools
  coexist safely with Cloud's server-side tools
- add get_weather (Open-Meteo, no key) as the wired reference tool and a
  commented remote-MCP example in the chat route
- typed missing/invalid API key errors in both routes
- scaffold identity: create-app generates a stable APP_ID into .env; the
  frontend-token route sends it as app_id so apps sharing an org key stay
  isolated
- default model to google/gemini-3.5-flash-free; unpin dev/start ports
- pnpm.onlyBuiltDependencies for sharp/unrs-resolver (approve-builds
  no longer interrupts install)
- ship template gitignore un-dotted and restore the real name at scaffold
  time (npm strips nested .gitignore files from published packages)
- add default favicon
- allowlist uses Object.hasOwn so prototype-chain names (toString,
  constructor, ...) can never match a declared tool
- round-cap exhaustion settles instead of dropping (mirrors the openai
  SDK runTools invariant): the last round posts outputs with
  tool_choice "none", and calls a non-enforcing server lets through
  are settled in one final forward-only turn - a stored conversation
  is never left holding an unanswered function_call
- chat route: type createParams as ResponseCreateParamsNonStreaming and
  confine the cast to the Cloud-extension tool entries (artifact,
  image_search); no more blanket as-any
- pnpm-workspace.yaml: carry the allow-build list where pnpm >=10.14
  (onlyBuiltDependencies) and >=11 (allowBuilds) actually read it -
  the package.json pnpm field is ignored there
Both API routes import the openai SDK at request time; move it out of
devDependencies so production installs (--prod, deploy platforms that
prune dev deps) don't lose it.
Current conditions only — drop the 3-day forecast block and collapse
the WMO code table into a small family mapper. Still a real Open-Meteo
call so the reference keeps demonstrating fetch + abort signal +
error-as-JSON. 130 -> 90 lines.
One regex instead of slug-trim-cap-fallback: collapse every run of
non-alphanumerics to a hyphen. Edge names now produce slightly uglier
ids (trailing/duplicate hyphens) but stay .env- and query-param-safe,
which is the part that matters.
Both API routes carried the same inline 13-line missing-key response and
requiredEnv had gone unused. apiKeyOrError() in lib/env.ts now owns the
check: routes do a two-line guard, and the helper's doc comment records
why this is a structured response instead of a throw (keyless scaffolds
are a first-run state; a thrown Error surfaces as an opaque 500).
A keyless browser test showed the structured missing_api_key response
never reaches the chat UI: the first failing call is the SDK's
frontend-token mint, and its helper throws a status-only error without
reading the response body. Until the SDK surfaces error bodies, the
requiredEnv throw is the leaner equivalent, so env.ts and both routes
go back to it. The chat route keeps its response-driven handling
(429 billing message, 401/403 key guidance) — those do render, via
getChatErrorMessage.
@Aditya-thesys
Aditya-thesys merged commit aa42887 into main Jul 22, 2026
25 checks passed
@Aditya-thesys
Aditya-thesys deleted the ap-cloud-tools-multiuser branch July 22, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants