You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit a5e280f
Browse filesBrowse the repository at this point in the historyBrowse files
docs(skills): teach os environments use-runtime and os mcp connect (#31225)
<!-- claude-projects-attribution: {"github_login":"huangyiirene"} -->
_Requested by **Irene** · [project
thread](https://claude.ai/code/project/chan_01TJXtQ1tVD26ecLDZxFS67x?thread=cmsg_01TJXtQ1tVD26ecLDZxFS67xKoxHJ3zQQdUAbBUgta4iFN)_Fixes#31143
Clause-②: no
Metadata-protocol: none
`dispatch-gates --tier` reads a MANDATORY model tier for `skills/**`
(clause ① of the model-tiering ruling); it is waived by the standing
order of the maintainer in this project (2026-11-03), and this card ran
on the project's default model. The dispatching seat runs the contract
review.
**Cross-seat note:** `content/docs/deployment/cli.mdx` and
`content/docs/deployment/publish-and-preview.mdx` are folded into this
`domain:skills` card by the triage (6708594558), so the skill and the
docs say the same thing. `content/docs/ai/connect-mcp.mdx` § "Claude
Code (one command)" (the page that gives the `claude mcp add` line) was
confirmed by the seat by name before it was edited.
## 维护者速读
- 改了什么:平台技能 `operations.md` 新增 `os environments use-runtime` 与 `os mcp
connect` 两行,`os deploy` 行加自托管目标的流程(构建 → 试运行计划 → 内联安装 → `hotLoaded`
即上线,`--confirm-access-upgrade`),`os package install` 行写明不带 `-u`
时回落到记住的运行时;`cli.mdx` 新增「Deploy to a self-hosted runtime」「To a
self-hosted runtime」「MCP / `os mcp connect`」三节并更新 install 的 `-u`/`-t`
默认值;`publish-and-preview.mdx` 加一段;`connect-mcp.mdx` 在手敲 `claude mcp add`
之前先介绍 `os mcp connect`;评测加两例。
- 为什么改:#30888(PR #31137)与 #30889(PR #31149)已合并,文档和技能没教,开发者与 AI 仍手敲地址、令牌和
`claude mcp add`(#31143)。
- 风险与回滚:只改文档、技能文字与 eval;`operations.md` 先删 8 处同文件重述/错述(−594 字节),余额 +53
token 按常设裁决 6513306068 提高该行上限 3287 → 3340;发 `@objectstack/skills`
patch;回滚即 revert。
- 先看:`skills/objectstack-platform/references/operations.md` 的 §
Environments & deploy 表,以及下方「删减与去处」表(含席位裁定删除的 `os login` / `os register`
两行错述)。
- 两分钟验证:`node scripts/check-skills-token-ratchet.mjs`,预期退出
0,`operations.md 3340 / 3340`。
- 需要你做的:`skills/**` 属 Tier H(人合),需要 `os-zhuang` 或 `hotlong` 的一次
approval,之后席位落地。
## What changes
### 1. The platform skill
(`skills/objectstack-platform/references/operations.md`)
```diff
-| `os login` / `logout` / `whoami` | Auth against the ObjectStack cloud control plane |
-| `os register` | Register the local stack as a deployable target |
+| `os environments use-runtime <url> --token <key>` | Deploy to a self-hosted runtime instead: the key (one it issued) is tried first (`--no-verify` skips), then kept in `~/.objectstack/cloud.json` (0600) across cloud login/logout. `--forget` or `os environments switch` targets the cloud again |
-… `--no-wait`; `--wait-timeout <seconds>` (600) |
+… `--no-wait`; `--wait-timeout <seconds>` (600). A `use-runtime` target, no `--env`: build, dry-run plan, install, live on `hotLoaded`; `--confirm-access-upgrade <token>` |
-| `os package install <manifest-id │ ./dist/objectstack.json> [--version │ -u/--url http://localhost:3000]` | … not the cloud login |
+| `os package install <manifest-id │ ./dist/objectstack.json> [--version │ -u/--url]` | … not the cloud login. No `-u`: the `use-runtime` runtime and, with no `-t`/`--email`, its key; else `http://localhost:3000` |
+| `os mcp connect` | Register the cloud environment's MCP server (picked as `os deploy` picks it) with Claude Code (`claude mcp add`); `--url <base>` for a self-hosted or local server (named `objectstack`); `--name`; `--print` runs nothing (other clients). Stores no token: the client runs the server's own OAuth |
```
The skill rows stay short and the full sequence lives in the CLI
reference (the order's preference).
### 2. The docs
- `content/docs/deployment/cli.mdx`: a `use-runtime` row in § Cloud
Environments; new § "Deploy to a self-hosted runtime" (examples, the key
and its probe, `--no-verify`, storage, which of `use-runtime` / `switch`
wins, `--forget`, a flag table); § `os deploy` names the self-hosted
target in its lead, gains a `--confirm-access-upgrade` row and a "To a
self-hosted runtime" subsection (the four steps and the `d` key); new §
MCP / `os mcp connect` (examples, environment resolution, `--url`,
names, `--client`, `--print`, failure exits, no token, revoke, a flag
table); § `os package install`'s `-u` and `-t` rows now give the
remembered runtime as the default.
- `content/docs/deployment/publish-and-preview.mdx` § 3 "Install a
version": one paragraph on remembering a runtime with `use-runtime` so
`os deploy` and the `d` key deploy there, the `os package install`
fallback, and how to target the cloud again.
- `content/docs/ai/connect-mcp.mdx` § "Claude Code (one command)": one
paragraph plus a fence before the hand-typed lines, which stay.
## Code site per taught sentence (`main` `66bf5b4a`)
| Taught | Code site |
|:--|:--|
| `os environments use-runtime <url> --token <key>`; `-t` reads
`OS_RUNTIME_TOKEN` |
`packages/cli/src/commands/environments/use-runtime.ts` `args.url`
(L40–L42), `flags.token` (L45–L49) |
| The key is tried first on `GET /api/v1/marketplace/install-local`;
401/403, 404, unreachable refused, nothing recorded | `use-runtime.ts`
L93–L100, `probeRuntime` (L142–L178) |
| `--no-verify` records anyway (a container not up yet) |
`use-runtime.ts` `verify` flag (L50–L54, `allowNo`), header L21–L25 |
| URL is an http(s) base URL, no query or fragment |
`normalizeRuntimeUrl` (L118–L135) |
| `--forget` drops the record; cloud is the target again; not with a url
| `use-runtime.ts` L65–L77; `forgetRuntimeTarget`
(`packages/cli/src/utils/runtime-target.ts` L65–L69) |
| Stored in `~/.objectstack/cloud.json`, 0600, its own record; key sent
only to its url | `packages/cli/src/utils/cloud-config.ts` header
L31–L44, `getCloudCredentialsPath` L106, `writeFile(..., { mode: 0o600
})` L132; `runtime-target.ts` header L23–L27 |
| Cloud logout keeps it; cloud login keeps it | `cloud-config.ts`
`deleteCloudConfig` L193–L195, `writeCloudConfig` L187–L190 (header
L40–L43) |
| `os environments switch <id>` (when recorded in cloud.json) makes the
cloud the target again, keeping the runtime |
`packages/cli/src/commands/environments/switch.ts` L78–L79;
`activateCloudDeployTarget` (`runtime-target.ts` L76–L81) |
| `os deploy` with a runtime target and no `--env` deploys there;
`--env` names a cloud environment |
`packages/cli/src/commands/deploy.ts` L152–L156 |
| Self-hosted sequence: build → dry run (plan printed; a runtime that
predates it installs anyway, said, exit 1) → install (a register failure
is refused here) → `hotLoaded` ⇒ 0 | `deploy.ts` `deployToRuntime`
L288–L335, header L49–L71; `install.ts` L511–L522 (dry run ignored ⇒
INSTALLED, exit 1) and L617–L622 (an inline manifest whose register
throws is refused `422 PLUGIN_REGISTER_FAILED`) |
| `--confirm-access-upgrade <token>` passed through; refused when the
target is the cloud | `deploy.ts` flag L138–L142, L157–L164, L320 |
| The `d` key runs the same `os deploy`, no cloud login asked |
`packages/cli/src/utils/dev-deploy-key.ts` header L26–L31,
`deployKeyHint` L74–L75, L118 |
| `os package install` with no `-u`: the remembered runtime (its key
when no `-t` / `--email` and the url is its own), else
`http://localhost:3000` | `runtime-target.ts` `runtimeInstallTarget`
L92–L108, `DEFAULT_RUNTIME_INSTALL_URL` L38;
`packages/cli/src/commands/package/install.ts` flags L218–L234,
L328–L337 |
| `os mcp connect` resolves the cloud environment as `os deploy`:
`--env`, active, only; none/several refused naming `--env`; a remembered
runtime is not consulted | `packages/cli/src/commands/mcp/connect.ts`
header L8–L15, `resolveInstallTarget` call L202–L212 (no runtime-target
read in the file) |
| MCP URL = environment origin + `/api/v1/mcp`; registered under its
slug / display name / id, lower-cased, other runs → `-` | `connect.ts`
`MCP_ENDPOINT_PATH` L54, `environmentServerName` L78–L84, L234–L235 |
| `--url` skips the cloud, adds `/api/v1/mcp`, refuses a URL ending in
it, name `objectstack` | `connect.ts` `mcpUrlFromBase` L91–L113,
L182–L191; `OBJECTSTACK_MCP_SERVER_NAME = 'objectstack'`
(`packages/mcp/src/skill-md.ts` L51) |
| `--name` overrides (letters, digits, `-`, `_`) | `connect.ts` flag
L143–L145, `SERVER_NAME` L60, L173–L177 |
| `--client claude-code` is the only value and the default; runs `claude
mcp add --transport http NAME URL` | `connect.ts` `MCP_CLIENTS` L57,
flag L146–L150, `claudeMcpAddArgs` L63–L65 |
| `--print` prints the endpoint and the line, runs nothing; other
clients add the endpoint themselves | `connect.ts` flag L151–L154,
header L35–L41, L243–L248 |
| `claude` missing or `claude mcp add` failing exits non-zero; remove or
pick another `--name` | `connect.ts` L251–L270 |
| No token stored; `--token` only finds the environment; sign-in via
`/mcp`; revoke in Account → Connect an AI Assistant | `connect.ts`
header L24–L33, `token` flag L161–L165, L273–L281 |
## Token readings and every deletion's home
`node scripts/check-skills-token-ratchet.mjs` on fresh `main`
`66bf5b4a`: `operations.md` **3285 / 3287** (headroom 2). With the
teaching added: 3489 (+202 over). After the deletions below and the
review's S1 correction: **3340**, 13140 → 13360 bytes (+220 net: −594
cut, +814 added). The remainder, **+53** measured, raises only that
file's row 3287 → 3340, pinned at the measurement, under the standing
maintainer ruling 2026-10-27, verbatim and untranslated:
「A:先削重复,余额按实测提高」 (ruling record 6513306068 on #27847). No other row
changes. (The seat's ruling expected about +47; the extra 6 tokens are
an accuracy fix found after it: the MCP row first said "the `os deploy`
environment", but with a self-hosted target `os deploy` goes to the
runtime while `os mcp connect` still resolves a cloud environment, so
the row now says "the cloud environment (picked as `os deploy` picks
it)".)
Every deletion, with every fact it held and where each survives (seat
ruling: cuts 1–7 accepted):
| # | Cut (bytes) | Facts it held | Surviving home |
|:--|:--|:--|:--|
| 1 | `os dev` row: " — idempotent, never overwrites an existing
account" (53) | seeding never touches an existing account | the same
row, whose "on an **empty** DB only" now reads "with **no login** yet"
(review S1: the seed is gated on the absence of a login, not an empty
user table, `packages/cli/src/commands/dev.ts` L777–L781; −2 bytes) |
| 2 | Verify item 2: "A bare `field` (missing `record.`) fails here."
(47) | `os validate` refuses a bare field ref | the section intro (a
bare field ref in a predicate faults; "Both are caught at author time by
one command") and item 2's `record.<field>` existence check |
| 3 | "(`os lint` is a *separate* style/convention pass and does not
replace `os validate`.)" (86) | lint is a style/convention pass; it is
not the gate | Daily-loop `os lint` row ("Style/convention lint on
metadata files") and the rule of thumb ("never report … done until `os
validate` passes") |
| 4 | Production port row: " — a shifted port breaks reverse-proxy
upstreams, better-auth callback URLs, and CORS trusted-origins as opaque
403/502s" (122) | what a shifted port breaks | Production guidance "Keep
these in sync when you change the port (mismatch ⇒ better-auth `Invalid
origin` 403 / CORS failures)" list: reverse-proxy upstream,
`OS_AUTH_URL` / `baseURL` + `callbackURL`, `OS_TRUSTED_ORIGINS`. The
word "502" is the one fact not restated. |
| 5 | Production guidance: " Don't rely on the `3000` default; it
collides easily on shared hosts." (72) | don't rely on the default |
"Pin the port explicitly — `PORT=8080 os start`" and the resolution
chain showing `3000` as the default |
| 6 | Testing: " — with the in-memory driver a full bootstrap is cheap"
(58) | a fresh kernel per test is cheap | the section intro: "tests run
in milliseconds" |
| 7a | Row `os login` / `logout` / `whoami` · "Auth against the
ObjectStack cloud control plane" (88) | **misstated**: `os login`
authenticates against the runtime server and stores `credentials.json`
(`login.ts` L240–L253); cloud auth is `os cloud login` |
`content/docs/deployment/cli.mdx` § Authentication; the `os cloud login`
row stays in the skill |
| 7b | Row `os register` · "Register the local stack as a deployable
target" (68) | **misstated**: `os register` creates an account and
stores credentials (`register.ts` L64) |
`content/docs/deployment/cli.mdx` § Authentication |
Cut 6 joins its two lines into one (the deletion spans the line break);
no other line is rewrapped. No test or script pins any cut text (grepped
`packages/`, `scripts/`, `.claude/`, `skills/`, `content/`; only
`packages/skills/dist` and CHANGELOGs carry copies).
## Eval cases
(`skills/objectstack-platform/evals/config-plugins-ops.json`)
- **21** · "We run ObjectStack's Docker image on our own server at
https://objectos.example.com. How do I deploy my app there from the
project without typing its URL and key every time?" → `use-runtime <url>
--token <key>`, probe and `--no-verify`, `cloud.json` (0600) across
login/logout, then `os deploy` / `d`: build, dry-run plan, inline
install, live on `hotLoaded`, `--confirm-access-upgrade`; `os package
install` fallback; `--forget` / `switch` back. `must_contain`: `os
environments use-runtime`, `--token`; `must_not_contain`: `os deploy
--url` (no such flag).
- **22** · "Connect Claude Code to our ObjectOS Cloud environment's MCP
server, and to my local `os dev` server too." → `os mcp connect` (runs
`claude mcp add --transport http <name> <url>`, environment as `os
deploy` picks it, named after it), `--url http://localhost:3000`
registered as `objectstack`, `--name`, `--print` for other clients, no
token, `/mcp` sign-in. `must_contain`: `os mcp connect`, `--url`;
`must_not_contain`: `--client cursor` (the only client is
`claude-code`).
Swept the skill's evals for the old claims: no case encodes the cut
text, `os login` / `os register`, or the `localhost:3000` install
default; case 5's `os lint` and case 17's cloud `os deploy` stay true.
## Other sites found (not edited)
- `content/docs/ai/agents.mdx` L99 and
`content/docs/getting-started/build-with-claude-code.mdx` L477–L502
still give only the hand-typed `claude mcp add` line;
`content/docs/releases/v16.mdx` is release history.
- `packages/cli/src/commands/environments/create.ts` (`--activate`) does
not call `activateCloudDeployTarget`, so only `os environments switch`
returns the deploy target to the cloud; the docs teach only `switch`.
Whether `create --activate` should too is a CLI question, not a teaching
one.
## Gates
Head `4e0b6486` (two commits on merge base `66bf5b4a`; the second is the
review delta: S1, N3, N4, N7 and the N6 re-flow of the one ragged `os
mcp connect` paragraph). `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` derives the same **87** commands as
at `e15e06e1`; **all 87 exited 0**, 0 NOT MEASURED among them. Each ran
with `timeout 900` under `NODE_OPTIONS=--max-old-space-size=8192`, after
`pnpm install --frozen-lockfile` and a full `pnpm build` (exit 0). The
list with each exit code: `gates-4e0b6486.txt` in the card folder (round
1: `gates-e15e06e1.txt`, 87/87 exit 0). It includes `pnpm
check:skill-identifier-liveness`, `pnpm --filter @objectstack/spec run
check:skill-refs`, `pnpm check:skill-compatibility`, `node
scripts/check-skills-token-ratchet.mjs` (and `--self-test`), `pnpm
check:doc-authoring`, `pnpm check:doc-anchors`, `pnpm --filter
@objectstack/spec run check:docs`, `pnpm check:cli-command-ids`, `pnpm
check:cli-examples-parity` and `node scripts/check-empty-changeset.mjs
--base origin/main`.
The CI-only steps dispatch-gates names as NOT MEASURED (Build Docs,
Build Core, the type-check lanes, dogfood and shard attestation) run in
CI. `node scripts/check-commit-card-trailers.mjs --range
origin/main..HEAD` exit 0 before the push.
<!-- signed: domain:skills#3 · huangyiirene ·
session_01J8VVAnBUEjCrpMSAcQv3Gp -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
docs(skills): the platform skill teaches `os environments use-runtime` and `os mcp connect`
6
+
7
+
Clause-②: no
8
+
Metadata-protocol: none
9
+
10
+
`objectstack-platform`'s operations reference gains two rows and two clauses. `os environments use-runtime <url> --token <key>` makes a self-hosted runtime the deploy target: the key is tried on the runtime first (`--no-verify` skips that), kept in `~/.objectstack/cloud.json` (0600) across cloud login and logout, and `--forget` or `os environments switch` targets the cloud again. The `os deploy` row says how it deploys to that runtime (build, dry-run plan, inline install, live on `hotLoaded`, `--confirm-access-upgrade`), and the `os package install` row says it falls back to that runtime with no `-u`. `os mcp connect` registers an environment's MCP server with Claude Code, `--url` for a self-hosted or local server (named `objectstack`), `--name`, `--print`, and stores no token. Paid by cutting restatement in the same file and two rows that misstated `os login` and `os register`. Two new eval cases cover the commands. The CLI behaviour already shipped; this release only teaches it.
Copy file name to clipboardExpand all lines: content/docs/deployment/cli.mdx
+125-3Lines changed: 125 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3130,6 +3130,7 @@ spells them, so one consumer reads both commands.
3130
3130
| `os environments create` | Provision a new environment. With `--activate` (the default) the new environment becomes the active one, recorded in `~/.objectstack/cloud.json` as well when the control plane it talked to is the one `os cloud login` recorded — so [`os package publish --install`](#os-package-publish) can install into it with no `switch` in between |
3131
3131
| `os environments switch <id>` | Set the active environment for later CLI calls. Recorded in `~/.objectstack/cloud.json` as well when the control plane it talked to is the one `os cloud login` recorded, so [`os package publish --install`](#os-package-publish) can use it |
3132
3132
| `os environments bind <id>` | Bind a compiled local artifact to an existing environment |
3133
+
| `os environments use-runtime <url> --token <key>` | Make a self-hosted runtime the deploy target instead of an ObjectOS Cloud environment — see [Deploy to a self-hosted runtime](#deploy-to-a-self-hosted-runtime) |
is reserved for the server-side reseed endpoint; use it only when that endpoint
3157
3158
is available in your deployment.
3158
3159
3160
+
#### Deploy to a self-hosted runtime
3161
+
3162
+
`os environments use-runtime` remembers a runtime you operate — ObjectStack's
3163
+
Docker image, Community or Enterprise — as the deploy target, so
3164
+
[`os deploy`](#to-a-self-hosted-runtime), the `d` key in [`os dev`](#os-dev) and
3165
+
[`os package install`](#os-package-install) stop asking for its URL and key.
3166
+
3167
+
```bash
3168
+
os environments use-runtime http://localhost:8080 --token osk_…
3169
+
OS_RUNTIME_TOKEN=osk_… os environments use-runtime https://objectos.example.com
3170
+
os environments use-runtime --forget # deploy to ObjectOS Cloud again
3171
+
```
3172
+
3173
+
The key is an API key the runtime issued (its **Setup → API Keys**); `-t, --token`
3174
+
reads `OS_RUNTIME_TOKEN`. The URL is the runtime's http(s) base URL, with no query
3175
+
or fragment. Before anything is written, the key is tried on the runtime's
3176
+
install-local endpoint (`GET /api/v1/marketplace/install-local`, which answers
3177
+
only an authenticated caller): a key the runtime rejects (`401`/`403`), a
3178
+
runtime that does not serve the endpoint (`404`), or one that cannot be reached
3179
+
is refused, naming why, and nothing is recorded. `--no-verify` records it anyway,
3180
+
for a container that is not up yet.
3181
+
3182
+
The URL and key are stored in `~/.objectstack/cloud.json` (mode `0600`), the file
3183
+
`os cloud login` writes, as their own record: no cloud request reads the key, and
3184
+
it is sent only to that runtime's URL. `os cloud logout` keeps the record, and so
3185
+
does a new `os cloud login`.
3186
+
3187
+
Whichever of `use-runtime` and `os environments switch` ran last is the target
3188
+
`os deploy` uses. `os environments switch <id>`, when it records the environment
3189
+
in `cloud.json` (see the table above), makes ObjectOS Cloud the target again and
3190
+
keeps the remembered runtime, so `os package install` still falls back to it.
3191
+
`--forget` drops the record.
3192
+
3193
+
| Flag | Env equivalent | Purpose |
3194
+
|---|---|---|
3195
+
| `url` (positional) | — | Base URL of the self-hosted runtime (e.g. `http://localhost:8080`) |
3196
+
| `-t, --token <key>` | `OS_RUNTIME_TOKEN` | An API key the runtime issued; sent only to this runtime |
3197
+
| `--no-verify` | — | Record the runtime without trying the key on it first |
3198
+
| `--forget` | — | Forget the remembered runtime; ObjectOS Cloud is the deploy target again. Takes no `url` |
3199
+
3159
3200
### Deploy
3160
3201
3161
3202
#### `os deploy`
3162
3203
3163
3204
Puts the app in the current directory on your ObjectOS Cloud environment, with
3164
-
no flags. It builds the app (the compile [`os build`](#os-compile) runs),
3205
+
no flags (or on a [self-hosted runtime](#to-a-self-hosted-runtime) you made the
3206
+
target). It builds the app (the compile [`os build`](#os-compile) runs),
3165
3207
publishes it as `<manifest.version>-dev.<YYYYMMDDHHMMSS>` — a UTC semver
3166
3208
pre-release, so deploying again never needs a version bump — installs that
3167
3209
version into your organization's environment, and waits until the environment
@@ -3199,10 +3241,90 @@ is its production, so a deploy is always a deliberate act.
3199
3241
| `--wait-timeout <seconds>` | — | How long to wait for the environment to serve the new version (default `600`) |
3200
3242
| `-s, --server <url>` | `OS_CLOUD_URL` | Control-plane URL. Default `https://cloud.objectos.ai`, or the URL recorded by `os cloud login` |
3201
3243
| `-t, --token <key>` | `OS_CLOUD_API_KEY` | Bearer token; `$OS_TOKEN` and `~/.objectstack/cloud.json` are the fallbacks |
3244
+
| `--confirm-access-upgrade <token>` | — | Self-hosted target only: confirm the upgrade's access findings with the finding-set token the runtime's refusal printed (as [`os package install`](#os-package-install)). Refused when the target is ObjectOS Cloud |
3202
3245
3203
3246
`os package publish` stays the command for a **release**: it publishes the
3204
3247
version the manifest declares, with `--install` optional.
3205
3248
3249
+
##### To a self-hosted runtime
3250
+
3251
+
When [`os environments use-runtime`](#deploy-to-a-self-hosted-runtime) made a
3252
+
self-hosted runtime the active target, `os deploy` with no flags deploys there
3253
+
instead; `--env` still names an ObjectOS Cloud environment and deploys to it.
3254
+
There is no catalog and no version to mint: the build is sent inline to the
3255
+
runtime's install-local endpoint by [`os package install`](#os-package-install),
3256
+
run in the same processwith the remembered URL and key, so its refusals and
3257
+
answers are the ones printed.
3258
+
3259
+
1.**Build** — the same compile as above. A failed build prints its errors, and
3260
+
nothing is installed.
3261
+
2.**Dry run** — the runtime's upgrade plan of the installed version against this
3262
+
build is printed; nothing is installed. A runtime that refuses it, or does not
3263
+
serve install-local, stops the deploy with exit `1`. A runtime that predates the
3264
+
dry run ignores it and installs: the command says so and exits `1`.
3265
+
3. **Install** — with `--confirm-access-upgrade` passed through. The endpoint's
3266
+
refusals (an access upgrade to confirm, a package the running kernel cannot
3267
+
register, …) stop the deploy with exit `1`.
3268
+
4.**Live** — install-local registers the packagein the running kernel before it
3269
+
answers, so the answer is the verdict:`hotLoaded` prints `Live: … now serves …`
3270
+
and exits `0`.
3271
+
3272
+
The `d` key in [`os dev`](#os-dev) runs the same `os deploy`, so it deploys to the
3273
+
runtime too and asks for no cloud login.
3274
+
3275
+
### MCP
3276
+
3277
+
#### `os mcp connect`
3278
+
3279
+
Registers your environment's MCP server with your MCP client in one command. The
3280
+
client then runs the environment's own OAuth: on first use it follows the
3281
+
server's OAuth discovery, registers itself, and your browser shows the
3282
+
environment's sign-in and consent.
3283
+
3284
+
```bash
3285
+
os mcp connect
3286
+
os mcp connect --print # print the endpoint and the `claude mcp add` line, run nothing
3287
+
os mcp connect --env env_abc123 # your account reaches several environments
3288
+
os mcp connect --url http://localhost:3000 # a self-hosted or local server
3289
+
```
3290
+
3291
+
The ObjectOS Cloud environment is resolved exactly as [`os deploy`](#os-deploy)
3292
+
resolves it:`--env`, then the active environment forthis control plane, then
3293
+
your organization's only environment; none or several is refused, naming
3294
+
`--env`. A self-hosted runtime `os environments use-runtime` remembered is not
3295
+
consulted; name it with `--url`. Its MCP URL is the environment's address, read
3296
+
from the control plane, plus `/api/v1/mcp`, and the server is registered under
3297
+
the environment's own name (its slug, else its display name, else its id,
3298
+
lower-cased with every run of other characters turned into one `-`), so several
3299
+
environments can be registered side by side. `--url` skips ObjectOS Cloud: it
3300
+
takes the base URL of a self-hosted or local server (the command adds
3301
+
`/api/v1/mcp` itself and refuses a URL that already ends in it) and registers it
3302
+
as `objectstack`, the name `os dev`'s banner gives it. `--name` overrides either
3303
+
name.
3304
+
3305
+
For Claude Code — the only `--client` value, and the default — the command runs
3306
+
`claude mcp add --transport http NAME URL`. `--print` prints the endpoint and that
3307
+
line and runs nothing, which is also how to connect any other client: add the
3308
+
endpoint as a remote HTTPMCP server in its settings. Then, in Claude Code, run
3309
+
`/mcp` and authenticate the server. If`claude` is not on your `PATH`, or
3310
+
`claude mcp add`fails (for a name already registered, `claude mcp remove NAME` or
3311
+
pick another `--name`), the command exits non-zero.
3312
+
3313
+
**No token is stored.** The command hands the client the URL alone and writes no
3314
+
token into a client config. `-t, --token` (or the `os cloud login` session) is
3315
+
used only to find the environment and is never handed to the client. To revoke
3316
+
the grant, use the environment's console: **Account → Connect an AI Assistant**.
3317
+
3318
+
| Flag | Env equivalent | Purpose |
3319
+
|---|---|---|
3320
+
| `--env <id>` | `OS_ENVIRONMENT_ID` | Environment to connect to (default: the active one for this control plane, then your organization's only one) |
3321
+
| `--url <url>` | — | Base URL of a self-hosted or local server; skips ObjectOS Cloud |
3322
+
| `--name <name>` | — | Server name in the client: letters, digits, `-` and `_` (default: the environment's name; `objectstack` with `--url`) |
3323
+
| `--client <client>` | — | `claude-code`, the default and only value |
3324
+
| `--print` | — | Print the endpoint and the command that registers it; run nothing |
3325
+
| `-s, --server <url>` | `OS_CLOUD_URL` | Control-plane URL. Default `https://cloud.objectos.ai`, or the URL recorded by `os cloud login` |
3326
+
| `-t, --token <key>` | `OS_CLOUD_API_KEY` | Bearer token, used only to find the environment; `$OS_TOKEN` and `~/.objectstack/cloud.json` are the fallbacks |
3327
+
3206
3328
### Packages
3207
3329
3208
3330
The two commands that move a compiled app onto a platform. They target
@@ -3389,9 +3511,9 @@ write `-u URL` instead.
3389
3511
| Flag | Env equivalent | Purpose |
3390
3512
|---|---|---|
3391
3513
| `package` (positional, required) | — | Package manifest id (`com.acme.crm`) **or** a path to a compiled artifact JSON |
3392
-
| `-u, --url <url>` | `OS_RUNTIME_URL` | Base URL of the runtime to install **into** (default `http://localhost:3000`) |
3514
+
| `-u, --url <url>` | `OS_RUNTIME_URL` | Base URL of the runtime to install **into** (default: the runtime [`os environments use-runtime`](#deploy-to-a-self-hosted-runtime) remembered, else `http://localhost:3000`) |
3393
3515
| `-v, --version <semver>` | — | Version to install in catalog mode (default `latest`). Air-gapped mode takes the version from the artifact |
3394
-
| `-t, --token <token>` | `OS_RUNTIME_TOKEN` | A token the target runtime issued (an API key); instead of `--email` / `--password` |
3516
+
| `-t, --token <token>` | `OS_RUNTIME_TOKEN` | A token the target runtime issued (an API key); instead of `--email` / `--password`. Default: the key `os environments use-runtime` remembered, when the URL is that runtime's and no `--email`/`--password` is given|
3395
3517
|`--email <email>`|`OS_RUNTIME_EMAIL`| Account email on the target runtime |
3396
3518
|`--password <password>`|`OS_RUNTIME_PASSWORD`| Account password on the target runtime |
3397
3519
|`--confirm-global-uniques`| — | Affirm this app's installation-wide `unique` constraints are genuinely platform-wide — see below |
Copy file name to clipboardExpand all lines: skills/objectstack-platform/evals/config-plugins-ops.json
+30Lines changed: 30 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -347,6 +347,36 @@
347
347
"requires: ['storage', 'settings']"
348
348
]
349
349
}
350
+
},
351
+
{
352
+
"id": 21,
353
+
"prompt": "We run ObjectStack's Docker image on our own server at https://objectos.example.com. How do I deploy my app there from the project without typing its URL and key every time?",
354
+
"expected_output": "Remember the runtime once: `os environments use-runtime https://objectos.example.com --token <key>`, with an API key that runtime issued. The key is tried on the runtime before anything is recorded (`--no-verify` skips that), then kept in `~/.objectstack/cloud.json` (0600), across cloud login and logout. From then on `os deploy` (or `d` in `os dev`) deploys there: it builds, prints the runtime's dry-run upgrade plan, installs the build inline, and reports it live when the runtime answers `hotLoaded`; `--confirm-access-upgrade <token>` confirms the access findings a refusal printed. `os package install` falls back to that runtime when `-u` is not given. `os environments use-runtime --forget` or `os environments switch <id>` makes ObjectOS Cloud the target again.",
355
+
"files": [],
356
+
"assertions": {
357
+
"must_contain": [
358
+
"os environments use-runtime",
359
+
"--token"
360
+
],
361
+
"must_not_contain": [
362
+
"os deploy --url"
363
+
]
364
+
}
365
+
},
366
+
{
367
+
"id": 22,
368
+
"prompt": "Connect Claude Code to our ObjectOS Cloud environment's MCP server, and to my local `os dev` server too.",
369
+
"expected_output": "Run `os mcp connect`: it runs `claude mcp add --transport http <name> <url>` for the environment `os deploy` would pick on ObjectOS Cloud (`--env <id>`, else the active one, else your organization's only one), named after that environment. For the local server, `os mcp connect --url http://localhost:3000` registers it as `objectstack`. `--name` overrides the name; `--print` prints the endpoint and the line and runs nothing, which is how to connect another client. No token is stored: in Claude Code run `/mcp` and authenticate, and the server's own sign-in and consent open in the browser.",
0 commit comments