@decocms/runtime

中文文档
3.0.2发布于 2026/09/23ES Module构建来源已验证近 30 天下载 8464

Provides the framework for building MCP applications behind Studio with typed tools, bindings, authentication, OAuth, resources, prompts, and triggers.

原始使用文档
文档目录11 节
  1. Overview
  2. Responsibilities
  3. Usage
  4. Architecture
  5. Development
  6. Boundaries
  7. Export surface
  8. Authentication and credential access
  9. Triggers and persistence
  10. Configuration, bindings, and events
  11. Related documentation

@decocms/runtime

Provides the framework for building MCP applications behind Studio with typed tools, bindings, authentication, OAuth, resources, prompts, and triggers.

AttributeValue
Workspace@decocms/runtime (packages/runtime)
KindPublic MCP application framework
RuntimeNode.js 24+; Web Fetch API
DistributionPublic npm package

Overview

@decocms/runtime is the application-facing runtime for MCP servers connected to Studio. It turns declarative tools, prompts, resources, agents, and bindings into a Fetch-compatible handler. The runtime also supplies the request-scoped Studio context that application code uses for identity, connection metadata, credentials, and calls to bound MCPs.

The package exposes source TypeScript through explicit package subpaths. Consumers should import only the subpath that owns the capability they need.

Responsibilities

  • Create MCP tools with Zod input and output schemas.
  • Mount tools, prompts, resources, and event handlers on a Fetch-compatible MCP server.
  • Resolve Studio request context and bound connections for each request.
  • Enforce authenticated access to protected tools, prompts, and resources.
  • Serve OAuth metadata and OAuth routes when an OAuth configuration is present.
  • Expose scoped access to Studio-managed credentials through the vault client.
  • Create trigger-management tools and deliver trigger callbacks to Studio.
  • Provide helpers for connection proxies, MCP client stubs, assets, and Decopilot applications.

Usage

Install the package in an MCP application:

bun add @decocms/runtime

Define a tool and export the runtime handler:

import {
  withRuntime,
} from "@decocms/runtime";
import {
  createTool,
  ensureAuthenticated,
} from "@decocms/runtime/tools";
import { z } from "zod";

const greet = createTool({
  id: "GREET",
  description: "Greet the signed-in user",
  inputSchema: z.object({
    name: z.string(),
  }),
  outputSchema: z.object({
    message: z.string(),
  }),
  execute: async ({ context, runtimeContext }) => {
    const user = ensureAuthenticated(runtimeContext);

    return {
      message: `Hello, ${context.name}. Signed in as ${user.email}.`,
    };
  },
});

export default withRuntime({
  tools: [greet],
});

withRuntime() returns an object with a fetch() handler. It serves the MCP endpoint at /mcp, delegates any unmatched request to the optional application fetch handler, and applies the configured CORS and OAuth behavior.

Prompts and resources use the same request context:

import { createPrompt, createResource } from "@decocms/runtime";
import { z } from "zod";

const reviewPrompt = createPrompt({
  name: "review",
  description: "Review a change",
  argsSchema: {
    path: z.string().optional(),
  },
  execute: ({ args }) => ({
    messages: [
      {
        role: "user",
        content: {
          type: "text",
          text: `Review ${args.path ?? "the current change"}.`,
        },
      },
    ],
  }),
});

const statusResource = createResource({
  uri: "studio://status",
  name: "Status",
  mimeType: "application/json",
  read: () => ({
    uri: "studio://status",
    mimeType: "application/json",
    text: JSON.stringify({ ready: true }),
  }),
});

createPrompt() and createResource() protect their handlers by default. Use the explicit createPublicPrompt() or createPublicResource() variants only when the content is safe to expose without a Studio identity.

Architecture

withRuntime() is the composition root. For each incoming request it:

  1. Normalizes canonical Studio environment fields and supported legacy aliases.
  2. Creates a request-scoped context containing identity and binding state.
  3. Initializes configured bindings.
  4. Dispatches MCP requests to the server created from tools, prompts, resources, agents, and event handlers.
  5. Applies OAuth and CORS behavior around the result.
  6. Falls back to the application's own fetch() handler for non-runtime routes.

The request context is stored with asynchronous request scoping. Tool code receives that context as the second execute() argument; it should not read ambient HTTP objects or reconstruct Studio identity from process-wide state.

Bindings describe MCP capabilities that a connection implements. withBindings() resolves those bindings for a request, while BindingOf, AgentOf, and proxyConnectionForId() provide typed access patterns for consumers that need to call them.

Development

Run package checks from the repository root:

bun run --cwd=packages/runtime check
bun run --cwd=packages/runtime test

Run a focused test file while iterating:

bun test packages/runtime/src/tools.test.ts

Format and lint repository changes before committing:

bun run fmt
bun run lint

Boundaries

  • This package is an MCP application framework, not the Studio control plane. It must not import server implementation details from apps/api or UI details from apps/web.
  • Treat the request-scoped runtime context as the authority for identity, Studio metadata, and bound services. Do not cache it across requests.
  • A tool is not protected merely because it runs behind an MCP endpoint. Call ensureAuthenticated() in tools that require a user.
  • Prompts and resources are authenticated by default. Public variants must expose only non-sensitive data.
  • Credential access is opt-in and scope-limited. Never request more credential material than the application needs, and never persist returned secrets.
  • The published package requires Node.js 24 or newer. Individual helpers use Web Fetch APIs; environment-specific helpers such as file-backed trigger storage and the asset server also require their documented host capabilities.
  • Legacy MESH_* environment fields and meshUrl remain compatibility aliases. New code must use STUDIO_* names and studioUrl.

Export surface

ImportPurpose
@decocms/runtimeRuntime composition, prompts, resources, bindings, request context, MCP stubs, and the Studio vault client
@decocms/runtime/proxyMCP proxy client primitives
@decocms/runtime/clientClient for the runtime tool-call HTTP endpoint
@decocms/runtime/bindingsBinding declarations, registry helpers, and binding initialization
@decocms/runtime/asset-serverStatic and single-page-application asset serving
@decocms/runtime/toolsTool creation plus prompt, resource, agent, and authentication primitives
@decocms/runtime/decopilotDecopilot application helpers
@decocms/runtime/triggersTrigger definitions, configuration tools, and callback delivery
@decocms/runtime/trigger-storageIn-memory, Studio KV, and JSON-file trigger storage adapters

These are the only supported package entry points. Do not import files below @decocms/runtime/src.

Authentication and credential access

ensureAuthenticated(runtimeContext) returns the Studio user or throws when the request is unauthenticated. It is the normal guard for a protected tool.

Applications that need Studio-managed credentials declare an explicit binding-scoped permission and create a client from the bootstrap passed to configuration.onInstall or configuration.onChange:

import {
  CREDENTIAL_ACCESS_TOKEN_READ_SCOPE,
  createStudioVaultClient,
  type ConfigurationScope,
} from "@decocms/runtime";
import type { StudioVaultBootstrap } from "@decocms/runtime/tools";

const scopes = [
  `github::${CREDENTIAL_ACCESS_TOKEN_READ_SCOPE}`,
] satisfies ConfigurationScope[];

function vaultClient(bootstrap: StudioVaultBootstrap) {
  return createStudioVaultClient({
    baseUrl: bootstrap.baseUrl,
    org: bootstrap.org,
    token: bootstrap.token,
  });
}

Use CREDENTIAL_ACCESS_TOKEN_READ_SCOPE for a provider access token and CREDENTIAL_CONFIGURATION_READ_SCOPE for non-token credential configuration. Refresh tokens and OAuth client secrets stay inside the Studio vault and are not part of the application-facing contract.

Triggers and persistence

createTriggers() creates TRIGGER_LIST and TRIGGER_CONFIGURE tools from typed trigger definitions. Its notify() method is intentionally fire-and-forget: delivery failures are logged and are not thrown back into a webhook handler.

Trigger configuration is process-local unless the application supplies a TriggerStorage. Use StudioKV when Studio KV is available, JsonFileStorage only for an appropriate local Node/Bun deployment, or provide an adapter backed by the application's durable store.

Configuration, bindings, and events

configuration.state accepts a Zod schema for persisted MCP configuration. BindingOf() fields in that schema resolve configured connection references into typed clients on STUDIO_REQUEST_CONTEXT.state. Declare required permissions in configuration.scopes; Studio evaluates those scopes when it configures the connection.

configuration.onChange runs for configuration updates and receives the parsed state, granted scopes, and optional vault bootstrap. configuration.onInstall runs on the first saved configuration and also receives the agent-provisioning helper. Handlers must be idempotent because network or deployment failures can interrupt work around these callbacks.

events.handlers declares CloudEvent handlers by binding key or SELF. The runtime exposes the corresponding ON_EVENTS tool and supports both batch results and per-event results. This subscriber contract does not provide a publisher or delivery queue. Callers own delivery and retries; handlers must handle repeated events idempotently.

When oauth is configured, the runtime serves protected-resource metadata, authorization-server metadata, authorization, callback, token, and dynamic client registration routes. The application supplies provider-specific authorization and token-exchange behavior.

The optional cors property controls runtime CORS handling; set it to false to disable the built-in layer. The optional application fetch() handler receives requests that do not match the runtime, OAuth, or tool-call routes.

版本与发布记录

@decocms/runtime 共发布 108 个版本,首次发布于 2025/11/11;过去 12 个月发布了 107 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
3.0.2latest2026/09/231 个月前
3.0.12026/09/221 个月前
3.0.02026/08/202 个月前
2.4.22026/08/132 个月前
2.4.12026/08/043 个月前
2.4.02026/07/303 个月前

其他发布通道:next → 1.0.0-alpha.42。

关于 @decocms/runtime 的常见问题

@decocms/runtime 是什么?

Provides the framework for building MCP applications behind Studio with typed tools, bindings, authentication, OAuth, resources, prompts, and triggers.

如何安装 @decocms/runtime?

在项目目录运行 npm install @decocms/runtime,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:ai(^7.0.107)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@decocms/runtime 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/decocms__runtime 是否存在。

@decocms/runtime 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@decocms/runtime 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@decocms/runtime 可以商用吗?

@decocms/runtime 使用 未声明 许可。package.json 没有声明许可证。没有许可证的代码默认保留全部权利,商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括,不构成法律意见,请以许可原文为准。

@decocms/runtime 的下载量有多少?

根据 npm 官方下载统计,@decocms/runtime 在 2026/10/12 – 2026/11/10 这 30 天内被下载 8,464 次,日均约 282 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@decocms/runtime 还在维护吗?

最新版本 3.0.2 发布于 2026/09/23(1 个月前);至今共发布 108 个版本,其中过去 12 个月发布了 107 个;首次发布于 2025/11/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。