- Updated dependencies [9e45b63]
- Updated dependencies [b20201f]
- @objectstack/spec@16.1.0
- @objectstack/core@16.1.0
- @objectstack/formula@16.1.0
- @objectstack/types@16.1.0
-
15dbe18: feat(mcp)!: stdio transport requires an API-key principal — fail-closed, no unscoped bridge (ADR-0101, #3246)
The long-lived MCP stdio transport no longer reads data unscoped. It now runs under an env-supplied identity, closing the platform's last identity-less execution surface (the
mcp-stdio-authorityconformance row graduatesexperimental→enforced).OS_MCP_STDIO_API_KEY=osk_...supplies the stdio identity, resolved through the SAME@objectstack/coreverify + authorization chain as the HTTP/REST surfaces; therecord_by_idresource reads viaql.find(obj, { where:{id}, context }), so RLS/FLS/tenant apply exactly as on REST/data. Re-resolved per read, so a revoked/expired key stops working on a live session.- Fail-closed — enabling stdio auto-start (
OS_MCP_STDIO_ENABLED=true/autoStart) without a resolvable key throws and refuses to start. There is no unscoped fallback and deliberately nosystembypass; full authority is a key minted on a platform-admin or dedicated service identity.
BREAKING (stdio auto-start only): previously
OS_MCP_STDIO_ENABLED=true(or the pluginautoStartoption) started stdio with full, unscoped authority and no credential. It now requiresOS_MCP_STDIO_API_KEY; without it, boot fails closed. The default-on HTTP surface and any deployment that never enables stdio auto-start are unaffected. -
83e8f7d: feat(mcp): decouple the stdio auto-start switch from the HTTP surface + surface the MCP endpoint on
os devboot (#3167)The MCP HTTP surface (
/api/v1/mcp) and the long-lived stdio transport used to share one env var:OS_MCP_SERVER_ENABLED=trueturned the HTTP surface on and silently auto-started the stdio transport — which bridges the raw metadata service- data engine with no per-request principal (unscoped). An operator setting it to "make sure MCP is on" got an unscoped transport as a side effect.
@objectstack/types— newresolveMcpStdioAutoStart(). Stdio auto-start is now its own switch,OS_MCP_STDIO_ENABLED(default off);OS_MCP_SERVER_ENABLEDgoverns only the HTTP surface. The legacyOS_MCP_SERVER_ENABLED=truetrigger still starts stdio for one release, flagged as deprecated.=falseis unchanged (it only ever gated HTTP).@objectstack/mcp—MCPServerPlugin.start()gates stdio on the new switch and logs a one-time deprecation warning when started via the legacy alias.@objectstack/cli—os devnow prints the MCP endpoint, the agent-skill URL, and a ready-to-pasteclaude mcp addcommand on boot (gated on the HTTP surface being on), so the "an agent operates the app it's building" loop is discoverable at dev time.create-objectstack— the blank scaffold README documents that the app is itself an MCP server (the serve side), distinct from the consume-side connector.
-
230358c: feat(mcp):
validate_expressiontool — validate a CEL expression against a schema before authoring (#1928)Adds an agent-callable MCP tool that runs the same build-time expression checks as
objectstack build, so an AI can validate a formula / predicate / flow condition while authoring instead of shipping one that silently evaluates tonull. Given{ objectName, expression, site? }it resolves the object's real schema (field names + types, via the principal-bounddescribeObjectbridge) and returns:- errors — bare field refs (
amount→record.amount), unknown fields (with a did-you-mean), unknown functions; - warnings — text/boolean fields misused in arithmetic, date-equality pitfalls;
- inScope — the fields, stdlib functions, and namespace roots available, so the model can self-correct;
- inferredType for a
formulasite.
site(formula|validation|flow_condition|template, defaultformula) maps to the validator's role + scope —flow_conditionbinds fields bare, the rest bindrecord.<field>. Read-only, gated by thedata:readOAuth scope, and fail-closed onsys_*objects like the other schema tools. This is the authoring-time surface the guardrail series (#1928) always pointed at;@objectstack/mcpgains a@objectstack/formuladependency (acyclic; formula is a leaf). - errors — bare field refs (
- Updated dependencies [f972574]
- Updated dependencies [6289ec3]
- Updated dependencies [22013aa]
- Updated dependencies [3ad3dd5]
- Updated dependencies [8efa395]
- Updated dependencies [3a18b60]
- Updated dependencies [a8aa34c]
- Updated dependencies [e057f42]
- Updated dependencies [a3823b2]
- Updated dependencies [43a3efb]
- Updated dependencies [524696a]
- Updated dependencies [6b51346]
- Updated dependencies [80273c8]
- Updated dependencies [bfa3c3f]
- Updated dependencies [5e3301d]
- Updated dependencies [dd9f223]
- Updated dependencies [46e876c]
- Updated dependencies [7125007]
- Updated dependencies [5f05de2]
- Updated dependencies [021ba4c]
- Updated dependencies [158aa14]
- Updated dependencies [62a2117]
- Updated dependencies [83e8f7d]
- Updated dependencies [d2723e2]
- Updated dependencies [fefcd54]
- Updated dependencies [beaf2de]
- Updated dependencies [369eb6e]
- Updated dependencies [06ff734]
- Updated dependencies [b659111]
- Updated dependencies [5754a23]
- Updated dependencies [6c270a6]
- Updated dependencies [290e2f0]
- Updated dependencies [668dd17]
- Updated dependencies [8abf133]
- Updated dependencies [e0859b1]
- Updated dependencies [92f5f19]
- Updated dependencies [32899e6]
- Updated dependencies [04ecd4e]
- Updated dependencies [4d5a892]
- Updated dependencies [16cebeb]
- Updated dependencies [86d30af]
- Updated dependencies [8923843]
- Updated dependencies [ea32ec7]
- Updated dependencies [a2795f6]
- Updated dependencies [f16b492]
- Updated dependencies [4b6fde8]
- Updated dependencies [2018df9]
- Updated dependencies [fc5a3a2]
- Updated dependencies [8ff9210]
- @objectstack/spec@16.0.0
- @objectstack/core@16.0.0
- @objectstack/formula@16.0.0
- @objectstack/types@16.0.0
- Updated dependencies [6289ec3]
- Updated dependencies [8efa395]
- Updated dependencies [bfa3c3f]
- Updated dependencies [7125007]
- Updated dependencies [62a2117]
- Updated dependencies [06ff734]
- @objectstack/spec@16.0.0-rc.1
- @objectstack/formula@16.0.0-rc.1
- @objectstack/core@16.0.0-rc.1
- @objectstack/types@16.0.0-rc.1
-
15dbe18: feat(mcp)!: stdio transport requires an API-key principal — fail-closed, no unscoped bridge (ADR-0101, #3246)
The long-lived MCP stdio transport no longer reads data unscoped. It now runs under an env-supplied identity, closing the platform's last identity-less execution surface (the
mcp-stdio-authorityconformance row graduatesexperimental→enforced).OS_MCP_STDIO_API_KEY=osk_...supplies the stdio identity, resolved through the SAME@objectstack/coreverify + authorization chain as the HTTP/REST surfaces; therecord_by_idresource reads viaql.find(obj, { where:{id}, context }), so RLS/FLS/tenant apply exactly as on REST/data. Re-resolved per read, so a revoked/expired key stops working on a live session.- Fail-closed — enabling stdio auto-start (
OS_MCP_STDIO_ENABLED=true/autoStart) without a resolvable key throws and refuses to start. There is no unscoped fallback and deliberately nosystembypass; full authority is a key minted on a platform-admin or dedicated service identity.
BREAKING (stdio auto-start only): previously
OS_MCP_STDIO_ENABLED=true(or the pluginautoStartoption) started stdio with full, unscoped authority and no credential. It now requiresOS_MCP_STDIO_API_KEY; without it, boot fails closed. The default-on HTTP surface and any deployment that never enables stdio auto-start are unaffected. -
83e8f7d: feat(mcp): decouple the stdio auto-start switch from the HTTP surface + surface the MCP endpoint on
os devboot (#3167)The MCP HTTP surface (
/api/v1/mcp) and the long-lived stdio transport used to share one env var:OS_MCP_SERVER_ENABLED=trueturned the HTTP surface on and silently auto-started the stdio transport — which bridges the raw metadata service- data engine with no per-request principal (unscoped). An operator setting it to "make sure MCP is on" got an unscoped transport as a side effect.
@objectstack/types— newresolveMcpStdioAutoStart(). Stdio auto-start is now its own switch,OS_MCP_STDIO_ENABLED(default off);OS_MCP_SERVER_ENABLEDgoverns only the HTTP surface. The legacyOS_MCP_SERVER_ENABLED=truetrigger still starts stdio for one release, flagged as deprecated.=falseis unchanged (it only ever gated HTTP).@objectstack/mcp—MCPServerPlugin.start()gates stdio on the new switch and logs a one-time deprecation warning when started via the legacy alias.@objectstack/cli—os devnow prints the MCP endpoint, the agent-skill URL, and a ready-to-pasteclaude mcp addcommand on boot (gated on the HTTP surface being on), so the "an agent operates the app it's building" loop is discoverable at dev time.create-objectstack— the blank scaffold README documents that the app is itself an MCP server (the serve side), distinct from the consume-side connector.
-
230358c: feat(mcp):
validate_expressiontool — validate a CEL expression against a schema before authoring (#1928)Adds an agent-callable MCP tool that runs the same build-time expression checks as
objectstack build, so an AI can validate a formula / predicate / flow condition while authoring instead of shipping one that silently evaluates tonull. Given{ objectName, expression, site? }it resolves the object's real schema (field names + types, via the principal-bounddescribeObjectbridge) and returns:- errors — bare field refs (
amount→record.amount), unknown fields (with a did-you-mean), unknown functions; - warnings — text/boolean fields misused in arithmetic, date-equality pitfalls;
- inScope — the fields, stdlib functions, and namespace roots available, so the model can self-correct;
- inferredType for a
formulasite.
site(formula|validation|flow_condition|template, defaultformula) maps to the validator's role + scope —flow_conditionbinds fields bare, the rest bindrecord.<field>. Read-only, gated by thedata:readOAuth scope, and fail-closed onsys_*objects like the other schema tools. This is the authoring-time surface the guardrail series (#1928) always pointed at;@objectstack/mcpgains a@objectstack/formuladependency (acyclic; formula is a leaf). - errors — bare field refs (
- Updated dependencies [f972574]
- Updated dependencies [22013aa]
- Updated dependencies [3ad3dd5]
- Updated dependencies [3a18b60]
- Updated dependencies [a8aa34c]
- Updated dependencies [e057f42]
- Updated dependencies [a3823b2]
- Updated dependencies [43a3efb]
- Updated dependencies [524696a]
- Updated dependencies [6b51346]
- Updated dependencies [80273c8]
- Updated dependencies [5e3301d]
- Updated dependencies [dd9f223]
- Updated dependencies [46e876c]
- Updated dependencies [5f05de2]
- Updated dependencies [021ba4c]
- Updated dependencies [158aa14]
- Updated dependencies [83e8f7d]
- Updated dependencies [d2723e2]
- Updated dependencies [fefcd54]
- Updated dependencies [beaf2de]
- Updated dependencies [369eb6e]
- Updated dependencies [b659111]
- Updated dependencies [5754a23]
- Updated dependencies [6c270a6]
- Updated dependencies [290e2f0]
- Updated dependencies [668dd17]
- Updated dependencies [8abf133]
- Updated dependencies [e0859b1]
- Updated dependencies [92f5f19]
- Updated dependencies [32899e6]
- Updated dependencies [04ecd4e]
- Updated dependencies [4d5a892]
- Updated dependencies [16cebeb]
- Updated dependencies [86d30af]
- Updated dependencies [8923843]
- Updated dependencies [ea32ec7]
- Updated dependencies [a2795f6]
- Updated dependencies [f16b492]
- Updated dependencies [4b6fde8]
- Updated dependencies [2018df9]
- Updated dependencies [fc5a3a2]
- @objectstack/spec@16.0.0-rc.0
- @objectstack/core@16.0.0-rc.0
- @objectstack/formula@16.0.0-rc.0
- @objectstack/types@16.0.0-rc.0
- @objectstack/spec@15.1.1
- @objectstack/core@15.1.1
- @objectstack/types@15.1.1
-
f531a26: feat(mcp):
aggregate_recordstool — GROUP BY aggregation over the engine read pathNew MCP tool
aggregate_records(count/sum/avg/min/max/count_distinct, optional groupBy incl. date bucketing, where filter, IANA timezone) in thedata:readfamily. Execution routes through the ObjectQL ENGINE (callData('aggregate')deliberately never uses the raw per-env driver), so RLS/tenant scoping and the D10 delegator intersection apply exactly as on find.Security hardening shipped with it:
- plugin-security: new FLS aggregate-INPUT gate — result masking never runs for
aggregate(output rows carry only aliases), so any groupBy / aggregation reference to an FLS-unreadable field is now rejected fail-closed with the offending field names (mirrors the FLS write gate). - runtime:
aggregatemaps to thelistApiMethod in the object exposure gate (an object whoseapiMethodswhitelist excludeslistcannot leak row statistics through GROUP BY), and the aggregate action requires at least one aggregation (the engine's in-memory path would otherwise degrade to raw rows that the FLS masker does not cover).
The bridge seam is optional: a runtime that does not implement
McpDataBridge.aggregatesimply does not register the tool (graceful degradation, same contract as the action tools). - plugin-security: new FLS aggregate-INPUT gate — result masking never runs for
-
f531a26: fix(security): enforce the
ai.exposedopt-in on the MCP action surface (#2849)Business-action bodies execute as trusted code: their engine facade carries no
ExecutionContext, so a body's internal reads/writes bypass RLS/FLS/CRUD and tenant scoping — the caller's permissions and an agent's ADR-0090 D10 data ceiling do NOT bound what an invoked action does. The MCPrun_actionbridge nevertheless allowed invoking ANY headless action, ignoring the spec'sai.exposedgovernance gate (ADR-0011) entirely.The MCP bridge now fail-closes on
ai.exposed:list_actionsonly enumerates — andrun_actiononly dispatches — actions the app author explicitly opted into the AI surface withai: { exposed: true, description }. Flow-type actions additionally receive the caller's identity (userId/positions/permissions/tenantId) as a properAutomationContext(replacing the formertriggerDataenvelope the engine never read), so arunAs: 'user'flow enforces RLS as the invoker instead of running unscoped (ADR-0049). Trusted body dispatches are now audit-logged on both the MCP and REST action paths, and the MCP tool/README/docs wording no longer claims action bodies run under the caller's RLS.Migration: actions that should stay invokable by AI agents through MCP must declare
ai: { exposed: true, description: '…' }(≥40-char description). All other invocation surfaces (UI, REST/actions/...) are unchanged. -
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [3fe9df1]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [4109153]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [627f225]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
-
Updated dependencies [f531a26]
- @objectstack/spec@15.1.0
- @objectstack/core@15.1.0
- @objectstack/types@15.1.0
- Updated dependencies [28b7c28]
- Updated dependencies [13749ec]
- Updated dependencies [e62c233]
- Updated dependencies [ed61c9b]
- Updated dependencies [31d04d4]
- @objectstack/spec@15.0.0
- @objectstack/core@15.0.0
- @objectstack/types@15.0.0
- Updated dependencies [16b4bf6]
- Updated dependencies [16b4bf6]
- Updated dependencies [10e8983]
- Updated dependencies [607aaf4]
- Updated dependencies [bb71321]
- @objectstack/spec@14.8.0
- @objectstack/core@14.8.0
- @objectstack/types@14.8.0
- Updated dependencies [d6a72eb]
- Updated dependencies [824a395]
- @objectstack/spec@14.7.0
- @objectstack/types@14.7.0
- @objectstack/core@14.7.0
- Updated dependencies [609cb13]
- Updated dependencies [ce6d151]
- @objectstack/spec@14.6.0
- @objectstack/core@14.6.0
- @objectstack/types@14.6.0
- e8cedec: Docs accuracy: correct how the MCP SKILL.md describes an agent's authority to match the shipped ADR-0090 D10 model. An OAuth-connected client is an agent acting on behalf of the signing-in user — every call is bounded by the intersection of the consent scopes and that user's own permissions/RLS (a
data:readtoken can never write, even where the user could), not simply "runs as you". (Companion doc-only edits tocontent/docs/ai/agents.mdxanddocs/design/permission-model.mdcorrect the same framing and honestly mark the still-planned agent guardrails — the grant-ceiling lint, destructive-action co-sign, and double-signature audit provenance.) - Updated dependencies [526805e]
- Updated dependencies [d79ca07]
- Updated dependencies [33ebd34]
- Updated dependencies [c044f08]
- Updated dependencies [01274eb]
- @objectstack/spec@14.5.0
- @objectstack/core@14.5.0
- @objectstack/types@14.5.0
- Updated dependencies [7953832]
- Updated dependencies [82e745e]
- Updated dependencies [f3035bd]
- Updated dependencies [82c0d94]
- Updated dependencies [7449476]
- @objectstack/spec@14.4.0
- @objectstack/core@14.4.0
- @objectstack/types@14.4.0
- Updated dependencies [2a71f48]
- Updated dependencies [02f6af4]
- Updated dependencies [c1064f1]
- @objectstack/spec@14.3.0
- @objectstack/core@14.3.0
- @objectstack/types@14.3.0
- Updated dependencies [ac8f029]
- Updated dependencies [4ab9958]
- @objectstack/spec@14.2.0
- @objectstack/core@14.2.0
- @objectstack/types@14.2.0
- Updated dependencies [5a8465f]
- Updated dependencies [7f8620b]
- Updated dependencies [82ba3a6]
- @objectstack/spec@14.1.0
- @objectstack/core@14.1.0
- @objectstack/types@14.1.0
-
332b711: feat(mcp): plugin-carried "Connect an agent" Setup page (#2714 Phase 1)
The MCP plugin now registers a Setup page (
connect_agent) plus its navigation entry under Integrations — the nav lives and dies with the capability (cloud ADR-0009 principle) and follows the surface's default-on switch: an opted-out deployment (OS_MCP_SERVER_ENABLED=false) gets no page and no entry. The page body is themcp:connect-agentSDUI widget provided by objectui (objectui#2372): env MCP URL, per-client connect cards, SKILL.md download, API-key minting. zh-CN nav label included. -
bc26360: feat(mcp):
GET /api/v1/mcp/skill— download the environment-customized Agent SkillrenderSkillMarkdown()was export-only; nothing served it over HTTP, so the "one generic skill" distributable (ADR-0036 Amendment C) had no self-serve outlet. The runtime dispatcher now serves it atGET /api/v1/mcp/skillastext/markdown— public like/discovery(generic agent instructions plus a URL the caller already knows; no schema, no tenant data), gated on the same default-on MCP switch (404 when opted out), 501 when the MCP plugin isn't loaded. The environment URL comes from the auth service's canonicalgetMcpResourceUrl()with a request-host fallback.MCPServerRuntimegainsrenderSkill()so hosts reach the renderer via the registered'mcp'service without a package dependency. Feeds the Setup "Connect an agent" page (objectui#2363) and the distribution shells (#2714).
- Updated dependencies [0a8e685]
- Updated dependencies [afa8115]
- Updated dependencies [80f12ca]
- Updated dependencies [e2fa074]
- Updated dependencies [23c8668]
- Updated dependencies [29f017d]
- Updated dependencies [216fa9a]
- Updated dependencies [6c22b12]
- @objectstack/spec@14.0.0
- @objectstack/core@14.0.0
- @objectstack/types@14.0.0
-
57b89b4: feat(mcp): the MCP surface is now default-on — a core platform capability (#2698)
/api/v1/mcpis served (and advertised in/discovery) out of the box; the OAuth 2.1 authorization track and Dynamic Client Registration follow it, so a fresh deployment is connectable by any MCP client with zero configuration. Operators opt OUT withOS_MCP_SERVER_ENABLED=false.- New single decision point
isMcpServerEnabled()in@objectstack/types(default on; explicitfalse/0/off/nodisables). The runtime dispatcher's/mcproute gate, the CLI's MCP plugin auto-load, the REST/discoveryadvertisement, and the auth service's OAuth/DCR follow-defaults all delegate to it — the served route, the advertised route, and the authorization track can never disagree. - The env var is now effectively tri-state: unset → HTTP surface on;
explicit
true→ additionally auto-start the long-lived stdio transport at boot (unchanged, still opt-in — a default must not claim the process's stdin/stdout); explicitfalse→ everything off, fail-closed (404, no metadata, no DCR). - The OAuth 2.1 TLS rule is unaffected: on a plain-HTTP non-loopback origin the OAuth track stays dark and the default-on surface remains API-key-only.
- New single decision point
-
5be00c3: feat(mcp): spec-compliant OAuth 2.1 authorization for
/api/v1/mcp(#2698)Any OAuth-capable MCP client (claude.ai custom connectors, Claude Desktop, Claude Code) can now connect to a deployment self-serve: no admin-minted API key, no central registry — you sign in through the browser as yourself and every tool call runs under your own permissions and row-level security.
Each deployment is its own authorization server, backed by the embedded better-auth instance (
@better-auth/oauth-provider). Rationale for the design decisions lives in #2698; the moving parts:- Discovery:
/.well-known/oauth-protected-resource(RFC 9728, incl. the path-inserted variant for/api/v1/mcp) and/.well-known/oauth-authorization-server(RFC 8414, incl. the path-inserted variant for the/api/v1/authissuer) are served from the deployment origin. 401s from/api/v1/mcpadvertise the resource metadata viaWWW-Authenticate, so clients bootstrap the flow automatically. - Dynamic Client Registration (RFC 7591) is enabled (unauthenticated, as
the MCP spec requires) whenever the MCP surface is on — every deployment is a
distinct AS, so clients cannot ship pre-registered IDs. Force it either way
with
OS_OIDC_DCR_ENABLEDor the newplugins.dynamicClientRegistrationauth-config field. The embedded AS itself auto-enables whenever the MCP surface is on — which is now the default (explicitOS_OIDC_PROVIDER_ENABLED=falsestill wins). - Authorization-code + PKCE flow with RFC 8707 resource binding: access
tokens are minted with
aud=<origin>/api/v1/mcpand verified locally (signature/issuer/audience/expiry) against the deployment's own JWKS — fail-closed parity with API keys: unknown/expired/wrong-audience tokens, sub-less M2M tokens, or a presented-but-invalid bearer never fall back to an ambient session, they 401. - Token → ExecutionContext: a valid access token resolves to the same
principal-bound
ExecutionContextas every other credential, single-sourced throughresolveAuthzContext— OAuth adds a second provenance for the principal, not a second authz model.ExecutionContextgains an optionaloauthScopesfield carrying the token's granted scopes. - Coarse scopes → tool families, enforced at tool dispatch:
data:read(list/describe/query/get),data:write(create/update/delete),actions:execute(list_actions/run_action). Constants live in@objectstack/spec/ai(MCP_OAUTH_SCOPES). Tools outside the grant are not registered — and therefore rejected — for that request. API-key and session principals are unaffected (not scope-limited). - TLS required, localhost exempt (OAuth 2.1): on a plain-HTTP non-loopback origin the OAuth track stays dark (no metadata, no bearer acceptance) and the endpoint remains API-key-only. Local clients reach intranet deployments; claude.ai web connectors additionally need public HTTPS reachability.
API keys are unchanged (dual-track):
x-api-key/Authorization: ApiKey/Authorization: Bearer osk_…keep working exactly as before for CI and headless agents — covered by new regression tests. - Discovery:
-
e097576: fix(mcp): the generated SKILL.md now documents the business-action tools
renderSkillMarkdown()listed only the 7 object-CRUD tools; the MCP surface exposes 9 —list_actions/run_action(business actions) were missing, so agents installing the skill never learned they can run approvals, conversions, or flow triggers directly. The skill now covers the full native tool surface and teaches action preference: whenlist_actionsoffers a matching action, call it instead of hand-editing the records it would have touched (actions carry the app's validation and side effects), confirming destructive or confirmation-flagged actions with the user first.Prerequisite for the distribution shells (#2714 Phase 0): every shell repo copies this rendered content, so the gap had to close before fan-out.
-
148beb4: test(mcp): drift guard — SKILL.md must document every registered native tool
The registered surface is obtained by driving the real registration path (a
tools/listround-trip againstMCPServerRuntimewith a full data+action bridge), not a hand-maintained list, so adding a tool tomcp-http-tools.tswithout teachingskill.tsfails the suite. Guards against a recurrence of the 7-of-9 gap fixed in #2715; red-proven by temporarily removingrun_actionfrom the skill. -
Updated dependencies [6d83431]
-
Updated dependencies [01917c2]
-
Updated dependencies [b271691]
-
Updated dependencies [a5a1e41]
-
Updated dependencies [466adf6]
-
Updated dependencies [57b89b4]
-
Updated dependencies [5be00c3]
-
Updated dependencies [466adf6]
-
Updated dependencies [2bee609]
-
Updated dependencies [fc7e7f7]
- @objectstack/spec@13.0.0
- @objectstack/core@13.0.0
- @objectstack/types@13.0.0
- Updated dependencies [6cebf22]
- Updated dependencies [21420d9]
- @objectstack/spec@12.6.0
- @objectstack/core@12.6.0
- @objectstack/types@12.6.0
- Updated dependencies [8b3d363]
- @objectstack/spec@12.5.0
- @objectstack/core@12.5.0
- @objectstack/types@12.5.0
- Updated dependencies [60dc3ba]
- @objectstack/spec@12.4.0
- @objectstack/core@12.4.0
- @objectstack/types@12.4.0
- Updated dependencies [e7eceec]
- @objectstack/spec@12.3.0
- @objectstack/core@12.3.0
- @objectstack/types@12.3.0
- Updated dependencies [fce8ff4]
- Updated dependencies [3962023]
- Updated dependencies [2bb193d]
- Updated dependencies [0426d27]
- Updated dependencies [da807f7]
- Updated dependencies [4f5b791]
- @objectstack/spec@12.2.0
- @objectstack/core@12.2.0
- @objectstack/types@12.2.0
- Updated dependencies [93e6d02]
- @objectstack/spec@12.1.0
- @objectstack/core@12.1.0
- @objectstack/types@12.1.0
- Updated dependencies [a8df396]
- Updated dependencies [e695fe0]
- Updated dependencies [7c09621]
- Updated dependencies [7709db4]
- Updated dependencies [2082109]
- Updated dependencies [7c09621]
- Updated dependencies [9860de4]
- Updated dependencies [069c205]
- @objectstack/spec@12.0.0
- @objectstack/core@12.0.0
- @objectstack/types@12.0.0
- Updated dependencies [6a9397e]
- Updated dependencies [c0efe5d]
- @objectstack/spec@11.10.0
- @objectstack/core@11.10.0
- @objectstack/types@11.10.0
- Updated dependencies [d3595d9]
- @objectstack/spec@11.9.0
- @objectstack/core@11.9.0
- @objectstack/types@11.9.0
- @objectstack/spec@11.8.0
- @objectstack/core@11.8.0
- @objectstack/types@11.8.0
- Updated dependencies [5178906]
- @objectstack/spec@11.7.0
- @objectstack/core@11.7.0
- @objectstack/types@11.7.0
- @objectstack/spec@11.6.0
- @objectstack/core@11.6.0
- @objectstack/types@11.6.0
- Updated dependencies [6ee4f04]
- Updated dependencies [c1e3a65]
- @objectstack/spec@11.5.0
- @objectstack/core@11.5.0
- @objectstack/types@11.5.0
- Updated dependencies [5821c51]
- Updated dependencies [a0fce3f]
- @objectstack/spec@11.4.0
- @objectstack/core@11.4.0
- @objectstack/types@11.4.0
- Updated dependencies [58e8e31]
- Updated dependencies [b4a5df0]
- @objectstack/spec@11.3.0
- @objectstack/core@11.3.0
- @objectstack/types@11.3.0
- Updated dependencies [d0f4b13]
- Updated dependencies [302bdab]
- @objectstack/spec@11.2.0
- @objectstack/core@11.2.0
- @objectstack/types@11.2.0
- Updated dependencies [ce0b4f6]
- Updated dependencies [9ccfcd6]
- Updated dependencies [ecf193f]
- Updated dependencies [51bec81]
- Updated dependencies [3e593a7]
- Updated dependencies [fdb41c0]
- Updated dependencies [63d5403]
- @objectstack/core@11.1.0
- @objectstack/spec@11.1.0
- @objectstack/types@11.1.0
- Updated dependencies [ab5718a]
- Updated dependencies [4845c12]
- Updated dependencies [c1a754a]
- Updated dependencies [6fbe91f]
- Updated dependencies [715d667]
- Updated dependencies [5eef4cf]
- Updated dependencies [72759e1]
- Updated dependencies [6c4fbd9]
- Updated dependencies [ef3ed67]
- Updated dependencies [cd51229]
- Updated dependencies [7697a0e]
- Updated dependencies [e7e04f1]
- Updated dependencies [cfd5ac4]
- Updated dependencies [2be5c1f]
- Updated dependencies [ad143ce]
- Updated dependencies [5c4a8c8]
- Updated dependencies [3afaeed]
- Updated dependencies [795b6d1]
- Updated dependencies [8801c02]
- Updated dependencies [3d04e06]
- Updated dependencies [4a84c98]
- Updated dependencies [c715d25]
- Updated dependencies [aa33b02]
- Updated dependencies [d980f0d]
- Updated dependencies [a658523]
- Updated dependencies [82ff91c]
- Updated dependencies [638f472]
- @objectstack/spec@11.0.0
- @objectstack/types@11.0.0
- @objectstack/core@11.0.0
- @objectstack/spec@10.3.0
- @objectstack/core@10.3.0
- @objectstack/types@10.3.0
- Updated dependencies [b496498]
- @objectstack/spec@10.2.0
- @objectstack/core@10.2.0
- @objectstack/types@10.2.0
- Updated dependencies [49da36e]
- Updated dependencies [ac79f16]
- @objectstack/spec@10.1.0
- @objectstack/core@10.1.0
- @objectstack/types@10.1.0
- Updated dependencies [d7ff626]
- Updated dependencies [2a1b16b]
- Updated dependencies [e16f2a8]
- Updated dependencies [e411a82]
- Updated dependencies [a581385]
- Updated dependencies [d5f6d29]
- Updated dependencies [220ce5b]
- Updated dependencies [3efe334]
- Updated dependencies [feead7e]
- Updated dependencies [6ca20b3]
- Updated dependencies [5f875fe]
- Updated dependencies [b469950]
- @objectstack/spec@10.0.0
- @objectstack/core@10.0.0
- @objectstack/types@10.0.0
- Updated dependencies [e7f6539]
- Updated dependencies [2365d07]
- Updated dependencies [6595b53]
- Updated dependencies [fa8964d]
- Updated dependencies [36138c7]
- Updated dependencies [a8e4f3b]
- Updated dependencies [4c213c2]
- Updated dependencies [2afb612]
- @objectstack/spec@9.11.0
- @objectstack/core@9.11.0
- @objectstack/types@9.11.0
- Updated dependencies [db02bd5]
- Updated dependencies [641675d]
- Updated dependencies [94e9040]
- Updated dependencies [1f88fd9]
- Updated dependencies [1f88fd9]
- @objectstack/spec@9.10.0
- @objectstack/core@9.10.0
- @objectstack/types@9.10.0
- @objectstack/spec@9.9.1
- @objectstack/core@9.9.1
- @objectstack/types@9.9.1
- Updated dependencies [84249a4]
- Updated dependencies [11af299]
- Updated dependencies [d5774b5]
- Updated dependencies [134043a]
- Updated dependencies [90108e0]
- Updated dependencies [9afeb2d]
- Updated dependencies [6bec07e]
- Updated dependencies [601cc11]
- Updated dependencies [575448d]
- @objectstack/spec@9.9.0
- @objectstack/core@9.9.0
- @objectstack/types@9.9.0
- Updated dependencies [97c55b3]
- Updated dependencies [1b1f490]
- @objectstack/spec@9.8.0
- @objectstack/core@9.8.0
- @objectstack/types@9.8.0
- @objectstack/spec@9.7.0
- @objectstack/core@9.7.0
- @objectstack/types@9.7.0
- Updated dependencies [d1e930a]
- Updated dependencies [71578f2]
- Updated dependencies [5e3a301]
- Updated dependencies [5db2742]
- @objectstack/spec@9.6.0
- @objectstack/core@9.6.0
- @objectstack/types@9.6.0
- Updated dependencies [ee72aae]
- @objectstack/spec@9.5.1
- @objectstack/core@9.5.1
- @objectstack/types@9.5.1
- Updated dependencies [d08551c]
- Updated dependencies [707aeed]
- Updated dependencies [7a103d4]
- Updated dependencies [4b01250]
- @objectstack/spec@9.5.0
- @objectstack/core@9.5.0
- @objectstack/types@9.5.0
- Updated dependencies [060467a]
- Updated dependencies [0856476]
- Updated dependencies [b678d8c]
- Updated dependencies [b678d8c]
- Updated dependencies [b678d8c]
- @objectstack/spec@9.4.0
- @objectstack/core@9.4.0
- @objectstack/types@9.4.0
- Updated dependencies [1ada658]
- Updated dependencies [3219191]
- Updated dependencies [290f631]
- Updated dependencies [50b7b47]
- Updated dependencies [f15d6f6]
- Updated dependencies [f8684ea]
- Updated dependencies [b4765be]
- @objectstack/spec@9.3.0
- @objectstack/core@9.3.0
- @objectstack/types@9.3.0
- Updated dependencies [2f57b75]
- Updated dependencies [2f57b75]
- @objectstack/spec@9.2.0
- @objectstack/core@9.2.0
- @objectstack/types@9.2.0
- Updated dependencies [b9062c9]
- @objectstack/spec@9.1.0
- @objectstack/core@9.1.0
- @objectstack/types@9.1.0
- Updated dependencies [1817845]
- @objectstack/spec@9.0.1
- @objectstack/core@9.0.1
- @objectstack/types@9.0.1
- Updated dependencies [4c3f693]
- Updated dependencies [0bf39f1]
- Updated dependencies [f533f42]
- Updated dependencies [1c83ee8]
- @objectstack/spec@9.0.0
- @objectstack/core@9.0.0
- @objectstack/types@9.0.0
- d8c5374: ai
- @objectstack/spec@8.0.1
- @objectstack/core@8.0.1
- @objectstack/types@8.0.1
-
d9f72fe: refactor(mcp)!: rename
@objectstack/plugin-mcp-server→@objectstack/mcp(ADR-0036)The outbound MCP-server package drops the legacy
plugin-prefix and moves to the top level (packages/mcp), parallel to@objectstack/rest— both are "your app exposed over a protocol". Inbound MCP (consuming external servers) stays@objectstack/connector-mcp.Breaking: the package name changed. Update imports
@objectstack/plugin-mcp-server→@objectstack/mcp. The exported API (MCPServerPlugin,MCPServerRuntime,registerObjectTools,McpDataBridge, …) is unchanged. The internal plugin id is nowcom.objectstack.mcp. Pre-launch clean break — no compatibility shim (only@objectstack/clidepended on it internally).
-
87cb13c: feat(mcp): generic ObjectStack Agent Skill generator (ADR-0036 Phase 2b)
Adds
renderSkillMarkdown({ mcpUrl, envName })— produces a portableSKILL.md(open Agent Skills standard: Claude Code, OpenAI Codex, Gemini CLI, Copilot, Cursor, …) that teaches any skills-capable agent how to drive an ObjectStack environment over MCP.Per ADR-0036 Amendment C, this is ONE generic skill, not a per-app artifact:
- the content never enumerates a tenant's schema — it instructs the agent to
discover live via
list_objects/describe_object, so one install works for every app the caller's key can reach and a new app needs no reinstall; - only the connection URL is environment-specific, slotted in by the caller;
- it documents the object-CRUD tools, auth via
x-api-key(Bearer is session auth), and the governance model (every call runs under the caller's permissions + RLS — fewer rows / write rejections are expected, not bugs).
Exported:
renderSkillMarkdown,OBJECTSTACK_SKILL_NAME,OBJECTSTACK_SKILL_DESCRIPTION,RenderSkillOptions. The objectui/cloud surfacing layer calls this to offer a one-click skill download alongside the env's remote-MCP URL and a show-once key. - the content never enumerates a tenant's schema — it instructs the agent to
discover live via
-
bc0d85b: feat(mcp): Streamable HTTP transport — every app is a network-reachable MCP server (ADR-0036 Phase 2)
The MCP server plugin spoke stdio only, so a remote agent (Claude Desktop / Cursor) could not connect to a hosted env. This adds the Streamable HTTP transport and wires it into the runtime's request path, building on the Phase 1a
sys_api_keyauth foundation.-
@objectstack/mcp(renamed from@objectstack/plugin-mcp-server— see the rename changeset)MCPServerRuntime.handleHttpRequest(request, { bridge, parsedBody })— serves one MCP request over the Web-standardWebStandardStreamableHTTPServerTransport(runs on Node 18+, Workers, Deno, Bun). Stateless: a fresh, isolatedMcpServer+ transport is built per request (the SDK-recommended pattern), in JSON-response mode so the response is fully buffered — no streaming pass-through concerns over the Worker→container hop.- New
registerObjectTools+McpDataBridge(mcp-http-tools.ts): the object-CRUD tool set (list_objects,describe_object,query_records,get_record,create_record,update_record,delete_record). All execution is delegated to an injected, principal-bound bridge — the tool layer never touches the data engine directly. System (sys_*) objects are not exposed by default (fail-closed guard on every object-scoped tool). The internal AI/authoring toolRegistry is deliberately NOT bridged onto the external surface.
-
@objectstack/runtimeHttpDispatcherserves/mcp: opt-in viaOS_MCP_SERVER_ENABLED=true(404 when off, so the surface isn't advertised); fail-closed auth (anonymous → 401 — requires the principal resolved by Phase 1a's API-key path or a session). It builds anMcpDataBridgethat runs every operation through the existingcallDatapath bound to the request'sExecutionContext, so external agents run under the key's permissions + RLS, never a parallel or escalated path. The discovery endpoint advertisesmcponly when enabled.
Security: every external MCP entry runs as the scoped
sys_api_keyprincipal under existing object permissions + RLS; MCP is opt-in per env; no raw keys or secrets cross the wire. Fully unit-tested (transport handshake/tools, gate, auth, principal binding). -
- Updated dependencies [a46c017]
- Updated dependencies [b990b89]
- Updated dependencies [99111ec]
- Updated dependencies [d5a8161]
- Updated dependencies [5cf1f1b]
- Updated dependencies [9ef89d4]
- Updated dependencies [3306d2f]
- Updated dependencies [c262301]
- Updated dependencies [bc44195]
- Updated dependencies [9e2e229]
- @objectstack/spec@8.0.0
- @objectstack/core@8.0.0
- @objectstack/types@8.0.0
- @objectstack/spec@7.9.0
- @objectstack/core@7.9.0
- @objectstack/types@7.9.0
- Updated dependencies [06f2bbb]
- Updated dependencies [36719db]
- Updated dependencies [424ab26]
- @objectstack/spec@7.8.0
- @objectstack/core@7.8.0
- @objectstack/types@7.8.0
- Updated dependencies [b391955]
- Updated dependencies [f06b64e]
- Updated dependencies [023bf93]
- @objectstack/spec@7.7.0
- @objectstack/core@7.7.0
- @objectstack/types@7.7.0
- Updated dependencies [955d4c8]
- Updated dependencies [c4a4cbd]
- Updated dependencies [b046ec2]
- Updated dependencies [2170ad9]
- Updated dependencies [02d6359]
- Updated dependencies [7648242]
- Updated dependencies [8fa1e7f]
- Updated dependencies [55866f5]
- Updated dependencies [60f9c45]
- @objectstack/spec@7.6.0
- @objectstack/core@7.6.0
- @objectstack/types@7.6.0
- @objectstack/spec@7.5.0
- @objectstack/core@7.5.0
- @objectstack/types@7.5.0
- @objectstack/spec@7.4.1
- @objectstack/core@7.4.1
- @objectstack/types@7.4.1
- Updated dependencies [23c7107]
- Updated dependencies [c72daad]
- Updated dependencies [f115182]
- Updated dependencies [2faf9f2]
- Updated dependencies [2faf9f2]
- Updated dependencies [2faf9f2]
- Updated dependencies [58b450b]
- Updated dependencies [82eb6cf]
- Updated dependencies [13d8653]
- Updated dependencies [ff3d006]
- Updated dependencies [5e831de]
- @objectstack/spec@7.4.0
- @objectstack/core@7.4.0
- @objectstack/types@7.4.0
- Updated dependencies [5e7c554]
- @objectstack/spec@7.3.0
- @objectstack/core@7.3.0
- @objectstack/types@7.3.0
-
9096dfe:
OS_env-var prefix migration (issue #1382).All ObjectStack-owned environment variables now use the
OS_prefix. Legacy names still work for one release and emit a one-shot deprecation warning via the newreadEnvWithDeprecation()helper in@objectstack/types.Renamed (with legacy fallback):
New Legacy (deprecated) OS_AUTH_SECRETAUTH_SECRET,BETTER_AUTH_SECRETOS_AUTH_URLAUTH_BASE_URL,BETTER_AUTH_URL,OS_AUTH_BASE_URLOS_PORTPORTOS_DATABASE_URLDATABASE_URLOS_ROOT_DOMAINROOT_DOMAINOS_MULTI_ORG_ENABLEDOS_MULTI_TENANTOS_CORS_ENABLEDCORS_ENABLEDOS_CORS_ORIGINCORS_ORIGINOS_CORS_CREDENTIALSCORS_CREDENTIALSOS_CORS_MAX_AGECORS_MAX_AGEOS_AI_MODELAI_MODELOS_MCP_SERVER_ENABLEDMCP_SERVER_ENABLEDOS_MCP_SERVER_NAMEMCP_SERVER_NAMEOS_MCP_SERVER_TRANSPORTMCP_SERVER_TRANSPORTOS_NODE_IDOBJECTSTACK_NODE_IDOS_METADATA_WRITABLEOBJECTSTACK_METADATA_WRITABLEOS_DEV_CRYPTO_KEYOBJECTSTACK_DEV_CRYPTO_KEYOS_HOMEOBJECTSTACK_HOMEMigration: rename in your
.env. Legacy names continue to work this release and will be removed in a future major. Industry-standard names (NODE_ENV,HOME,OPENAI_API_KEY,TURSO_*, OAuth*_CLIENT_ID/SECRET,RESEND_API_KEY,POSTMARK_TOKEN,AI_GATEWAY_*,SMTP_*) are NOT renamed. -
Updated dependencies [9096dfe]
- @objectstack/types@7.2.1
- @objectstack/spec@7.2.1
- @objectstack/core@7.2.1
- @objectstack/spec@7.2.0
- @objectstack/core@7.2.0
- Updated dependencies [47a92f4]
- @objectstack/spec@7.1.0
- @objectstack/core@7.1.0
- Updated dependencies [74470ad]
- Updated dependencies [d29617e]
- Updated dependencies [dc72172]
- @objectstack/spec@7.0.0
- @objectstack/core@7.0.0
- @objectstack/spec@6.9.0
- @objectstack/core@6.9.0
- @objectstack/spec@6.8.1
- @objectstack/core@6.8.1
- Updated dependencies [6e88f77]
- Updated dependencies [c8b9f57]
- @objectstack/spec@6.8.0
- @objectstack/core@6.8.0
- @objectstack/spec@6.7.1
- @objectstack/core@6.7.1
- Updated dependencies [430067b]
- Updated dependencies [4f9e9d4]
- @objectstack/spec@6.7.0
- @objectstack/core@6.7.0
- Updated dependencies [a49cfc2]
- @objectstack/spec@6.6.0
- @objectstack/core@6.6.0
- @objectstack/spec@6.5.1
- @objectstack/core@6.5.1
- @objectstack/spec@6.5.0
- @objectstack/core@6.5.0
- Updated dependencies [f8651cc]
- Updated dependencies [f8651cc]
- Updated dependencies [0bf6f9a]
- @objectstack/spec@6.4.0
- @objectstack/core@6.4.0
- @objectstack/spec@6.3.0
- @objectstack/core@6.3.0
- Updated dependencies [b4c74a9]
- @objectstack/spec@6.2.0
- @objectstack/core@6.2.0
- @objectstack/spec@6.1.1
- @objectstack/core@6.1.1
- Updated dependencies [93c0589]
- @objectstack/spec@6.1.0
- @objectstack/core@6.1.0
- Updated dependencies [629a716]
- Updated dependencies [dbc4f7d]
- Updated dependencies [944f187]
- @objectstack/spec@6.0.0
- @objectstack/core@6.0.0
- Updated dependencies [bab2b20]
- Updated dependencies [fa011d8]
- Updated dependencies [b806f58]
- @objectstack/spec@5.2.0
- @objectstack/core@5.2.0
- Updated dependencies [75f4ee6]
- Updated dependencies [823d559]
- @objectstack/spec@5.1.0
- @objectstack/core@5.1.0
- Updated dependencies [2f9073a]
- @objectstack/spec@5.0.0
- @objectstack/core@5.0.0
- Updated dependencies [2869891]
- @objectstack/spec@4.2.0
- @objectstack/core@4.2.0
- @objectstack/spec@4.1.1
- @objectstack/core@4.1.1
- Updated dependencies [2108c30]
- Updated dependencies [23db640]
- @objectstack/spec@4.1.0
- @objectstack/core@4.1.0
- 15e0df6: chore: unify all package versions to a single patch release
- Updated dependencies [15e0df6]
- @objectstack/spec@4.0.5
- @objectstack/core@4.0.5
- Updated dependencies [326b66b]
- @objectstack/spec@4.0.4
- @objectstack/core@4.0.4
- @objectstack/spec@4.0.3
- @objectstack/core@4.0.3