Skip to content

Commit 533f8da

Browse files
committed
docs(ai): MCP docs state the same-origin api forward (connect-mcp exposure policy + troubleshooting row, actions-as-tools dispatch table)
Three sentences that #27506 made stale, aligned with content/docs/ui/actions.mdx: the headless-callable set is script, flow and a same-origin `type: 'api'` action (dispatched in-process through the action door by run_action); an api action whose target is on another origin stays browser-only and is not listed; sys_* objects stay held back for every type; a credential rotation reaches an MCP tool result as the bearer-lane headers only, never Set-Cookie. Prose only — no code, test or changeset semantics move. Claude-Session: https://claude.ai/code/session_01L6bhgWdZYC1P9NBFo7ef6W Co-authored-by: Claude <noreply@anthropic.com>
1 parent a87722d commit 533f8da

2 files changed

Lines changed: 11 additions & 7 deletions

File tree

‎content/docs/ai/actions-as-tools.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ back fail-closed.
108108
|:---|:---|:---|
109109
| `script` | `IDataEngine.executeAction(object, target, ctx)` — the same call Studio makes | open (MCP) + ObjectOS |
110110
| `flow` | automation flow runner — `execute(target, automationContext)` (caller identity forwarded so `runAs` engages) | open (MCP) + ObjectOS; needs the `automation` service registered |
111-
| `api` | HTTP call to `action.target` via a configured `apiClient` | **ObjectOS** runtime only |
111+
| `api` | same-origin `target` (a path starting with `/`): forwarded in-process through the action door to that target, after the door's gates, with the caller's own credentials; a credential rotation the target emits comes back as the bearer-lane headers only (`set-auth-token` / `set-admin-session-token`), never a `Set-Cookie` line | open (MCP) + ObjectOS; an `api` action whose `target` is on another origin stays browser-only and is not listed |
112112

113113
Console-only types (`url`, `modal`, `form`) are always skipped.
114114

‎content/docs/ai/connect-mcp.mdx‎

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -242,11 +242,15 @@ can reach is the **default exposure policy (v1)**:
242242
are blocked fail-closed.
243243
- **Actions require the author's opt-in**: `ai: { exposed: true }` plus an
244244
`ai.description` of at least 40 characters, and the action must be callable
245-
without a UI. In the open framework that means exactly two types — `script`
246-
(with an inline body or a registered handler) and `flow` (with the automation
247-
service registered). `url`, `modal`, `form`, and `api` have no headless
248-
dispatch here. See [Actions as Tools](/docs/ai/actions-as-tools) and
249-
[Actions](/docs/ui/actions).
245+
without a UI. In the open framework that means three types — `script`
246+
(with an inline body or a registered handler), `flow` (with the automation
247+
service registered), and `api` whose `target` is a **same-origin path**
248+
(starting with `/`): `run_action` dispatches it in-process through the
249+
action door to that target, after the door's gates. `url`, `modal`, and
250+
`form` have no headless dispatch here, and neither does an `api` action
251+
whose `target` is on another origin — the browser calls that origin
252+
directly, so it is not exposed. See [Actions as Tools](/docs/ai/actions-as-tools)
253+
and [Actions](/docs/ui/actions).
250254

251255
<Callout type="info">
252256
This is the default policy, not a ceiling. A finer, **metadata-declared** exposure
@@ -392,7 +396,7 @@ skill and a guided `/objectstack:connect` command.
392396
| stdio won't start / boot fails closed | `OS_MCP_STDIO_ENABLED=true` but `OS_MCP_STDIO_API_KEY` is missing, unknown, revoked, or expired — fail-closed by design (ADR-0101). Set a valid `osk_` key; there is no unscoped or `system` fallback |
393397
| `401` on every call | Anonymous or invalid credentials. Interactive clients: complete the browser login (the `WWW-Authenticate` header advertises the OAuth metadata). Headless: check the `osk_` key and header spelling |
394398
| `403 insufficient_scope` | The OAuth token lacks the scope for that tool family (e.g. writes without `data:write`) — reconnect and grant the scope |
395-
| An action is missing from `list_actions` | `ai.exposed` is not `true`, `ai.description` is shorter than 40 characters, the type isn't headless-callable here (only `script` with a body/handler and `flow` with an automation service are — `url`, `modal`, `form`, and `api` never appear), it targets a `sys_*` object, or the caller fails its `requiredPermissions` |
399+
| An action is missing from `list_actions` | `ai.exposed` is not `true`, `ai.description` is shorter than 40 characters, the type isn't headless-callable here (`script` with a body/handler, `flow` with an automation service, and `api` with a same-origin `target` are — `url`, `modal`, `form`, and an `api` action whose `target` is on another origin never appear), it targets a `sys_*` object (held back fail-closed for every type, api included — #27681 tracks that gap), or the caller fails its `requiredPermissions` |
396400
| Reads return few rows / writes denied | Working as designed — the caller's permissions and RLS apply. Verify with the same user in the Console |
397401

398402
## Related

0 commit comments

Comments
 (0)