@commercetools/tools-core

中文文档
0.7.1发布于 2026/11/09UNLICENSEDTypeScriptESM + CJS近 30 天下载 1万

商业工具工具系统核心

中文使用文档
文档目录7 节
  1. 设计文档
  2. 设计决定
  3. 软件包组件
  4. 构成部分关系
  5. 用法实例
  6. 工具标题和 MCP 说明
  7. 密钥设计模式

商业工具 核心MCP工具

这个软件包以MCP(模式上下文协议)工具的形式暴露出商业工具资源,可以跨多个MCP项目使用.

这些文件描述了详细的设计决定、将暴露工具纳入现有项目的步骤以及取决于项目设计选择的各种使用实例.

设计文档

-- -- 待补 -- --

设计决定

1. 分层建筑

该套件采用分层结构模式,明确区分了所关切的问题:

  • 基层( E)BaseResourceHandler(中文(简体) ):通用,API-不可知处理器,提供工具路由,验证,并命名常规.
  • 平台层( E)CommercetoolsResourceHandler(中文(简体) ):利用工厂的客户端来建造 平台 API 根( 通过 createApiBuilderFromCtpClient 从 @commercetools/platform-sdk) (中文(简体) ). 用于客户,项目,订单等.
  • 取出图层( E)CheckoutResourceHandler(中文(简体) ): 使用同一工厂客户端来构建 检查出 API 根( 通过 createApiBuilderFromCtpClient 从 @commercetools/checkout-sdk 带有取出基准 URL ). 用于支付意图,交易.
  • 资源层:特定资源的具体实施(CustomersHandler,PayingIntentsHandler等).

理由: 此分离允许基接器被再用到任何API平台(Stripe, Shopify等). 商务工具层被分拆,这样资源就可以根据需要使用平台API或Checkout API;两者都使用来自工厂的同为低等客户端.

2. 搬运工登记:装饰或直接证明

工具处理器类可以两种方式中的一种方式注册:

  • 基于装饰的: 应用 @ToolHandler() 以扩展一个基础处理器的类(例如:. CustomerHandler) (中文(简体) ). 当该类被定义时,它会在全球登记册上注册. 获取所有注册的处理器 getDecoratorRegisteredHandlers() 把它们交给你的MCP服务器.
  • 直接即时: 自己创建处理器实例(例如:. new CustomerHandler(), (中文(简体) ), new PaymentIntentsHandler(factory)),并将这一系列实例传递到您的 MCP 服务器。 不涉及装饰或登记.

可以同时混合:为一些处理器使用装饰器,并明确即时处理其他的,然后在构建服务器时将数组组合.

理由: 装饰器允许零配置的发现; 直接即时使构造器参数完全控制( 如自定义) IApiClientFactory),并避免全球状态.

3. 客户端和API根分离

低层 客户端 (从) @commercetools/ts-client由工厂创建并归还; API 根数 (平面或取出)由处理器内部所建. 工厂曝光 getClient(configuration, authToken); 处理器调用然后使用 createApiBuilderFromCtpClient 从合适的SDK(平面-sdk或取出-sdk)来构建它们所需要的根.

理由: 一个客户端实例既可以背靠平台,也可以背靠取出API;处理者拥有他们使用的API.

4. 依赖性注射

API客户工厂可注射,允许:

  • 对模拟工厂进行简单测试
  • 自定义 API 客户端执行
  • 不同的认证战略

理由:提高可检验性和灵活性,同时保持清洁的API.

5. 基于Schema的验证

所有工具参数都使用处理器元数据中定义的Zod schemas验证.

理由: Type-safed 参数验证,带有清晰的错误消息和自动TypeScript类型推论.

6. 基于职能和班级的支助

该架构支持两个方面:

  • 基于类:有全能处理器(如. CustomerHandler, (中文(简体) ), PaymentIntentsHandler) (中文(简体) ). 通过 装饰器 (单位:千美元)@ToolHandler() + 键 getDecoratorRegisteredHandlers())或通过 直接即时处理 (例如:. new CustomerHandler())并将实例传递给您的服务器.
  • 基于函数:用于快速工具创建的简单函数包(例如. createCustomerHandler() 返回处理器实例.

理由:为不同的使用案例提供灵活性 - 复杂工具受益于类,简单工具可以使用功能;类可以通过装饰者注册或直接即时注册.

软件包组件

packages/core/
├── src/
│   ├── handlers/
│   │   ├── base.handler.ts          # Generic base handler (API-agnostic)
│   │   ├── commercetools.handler.ts # Platform API handler (builds root from client)
│   │   └── checkout.handler.ts      # Checkout API handler (payment-intents, transactions)
│   ├── decorators/
│   │   └── tool.decorator.ts        # @ToolHandler() decorator
│   ├── resources/
│   │   ├── customer/                # Customer resource handler
│   │   ├── project/                 # Project resource handler
│   │   ├── payment-intents/         # Checkout API resource
│   │   ├── transactions/            # Checkout API resource
│   │   └── ...                      # Other resources
│   └── shared/
│       ├── types/                   # TypeScript interfaces (e.g. IApiClientFactory)
│       ├── client/
│       │   └── client.base.ts       # CommercetoolsAPIClient + ApiClientFactory
│       └── errors/                  # Error handling
└── index.ts                         # Public API exports

构成部分关系

┌────────────────────────────────────────────────────────┐
│                    ToolExecutionContext                │
│  (authToken, configuration, toolName, parameters)      │
└────────────────────┬───────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────┐
│              BaseResourceHandler<TConfig>               │
│  • Tool routing & validation                            │
│  • Schema validation                                    │
│  • Tool name generation                                 │
│  • Abstract CRUD methods                                │
└────────────────────┬────────────────────────────────────┘
                     │
                     │ extends
         ┌───────────┴───────────┐
         ▼                       ▼
┌─────────────────────┐  ┌─────────────────────────────┐
│ CommercetoolsResource│  │   CheckoutResourceHandler   │
│      Handler         │  │  • getClient() from factory │
│  • getClient() from  │  │  • getApiRoot() = checkout- │
│    factory           │  │    sdk createApiBuilder…  │
│  • getApiRoot() =    │  │  • payment-intents,         │
│    platform-sdk      │  │    transactions            │
│    createApiBuilder… │  └──────────────┬──────────────┘
│  • customers,        │                 │
│    project, etc.     │                 │ extends
└──────────┬───────────┘                 │
           │ extends                     │
           ▼                             ▼
┌─────────────────────┐  ┌─────────────────────────────┐
│ CustomerHandler /    │  │ PaymentIntentsHandler /     │
│ ProjectHandler /…   │  │ TransactionsHandler         │
└──────────┬───────────┘  └──────────────┬──────────────┘
           │                             │
           └─────────────┬───────────────┘
                         │ registered via
                         ▼
           ┌─────────────────────────────┐
           │     Decorator Registry      │
           │ getDecoratorRegistered…()   │
           └──────────────┬──────────────┘
                          │ used by
                          ▼
           ┌─────────────────────────────┐
           │        MCP Server            │
           └─────────────────────────────┘

用法实例

1. 使用基控工具的自定义工具(基于类)

为任何 API 平台创建自定义工具 :

import { z } from 'zod';
import {
  BaseResourceHandler,
  type ResourceMetadata,
  type ToolExecutionContext,
} from '@commercetools/tools-core';

// Define your custom configuration type
interface CustomApiConfig {
  apiKey: string;
  baseUrl: string;
}

// Create a custom handler
class ProductHandler extends BaseResourceHandler<CustomApiConfig> {
  protected readonly metadata: ResourceMetadata = {
    namespace: 'product',
    description: 'Manage products in custom API',
    toolNamePrefix: 'mcp_custom_',
    schemas: {
      read: z.object({
        id: z.string().describe('Product ID'),
      }),
      create: z.object({
        name: z.string(),
        price: z.number(),
      }),
      update: z.object({
        id: z.string(),
        name: z.string().optional(),
        price: z.number().optional(),
      }),
      delete: z.object({
        id: z.string(),
      }),
    },
  };

  async read(context: ToolExecutionContext<CustomApiConfig>): Promise<unknown> {
    const { id } = context.parameters as { id: string };
    const { apiKey, baseUrl } = context.configuration;

    // Make API call using your custom API client
    const response = await fetch(`${baseUrl}/products/${id}`, {
      headers: { Authorization: `Bearer ${apiKey}` },
    });

    return response.json();
  }

  async create(
    context: ToolExecutionContext<CustomApiConfig>
  ): Promise<unknown> {
    const params = context.parameters as { name: string; price: number };
    const { apiKey, baseUrl } = context.configuration;

    const response = await fetch(`${baseUrl}/products`, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });

    return response.json();
  }

  async update(
    context: ToolExecutionContext<CustomApiConfig>
  ): Promise<unknown> {
    // Implementation similar to create
    return {};
  }

  async delete(
    context: ToolExecutionContext<CustomApiConfig>
  ): Promise<unknown> {
    // Implementation
    return {};
  }

  // other custom functions can go here
}

// Use in MCP server
import { createMCPServer } from './mcp.server';

const server = createMCPServer(
  'auth-token',
  { apiKey: 'key', baseUrl: 'https://api.example.com' },
  [new ProductHandler()]
);

2. 使用基准处理器的自定义工具(基于功能)

对于更简单的工具,使用基于函数的方法:

import { z } from 'zod';
import {
  BaseResourceHandler,
  type ToolExecutionContext,
  type ResourceMetadata,
} from '@commercetools/tools-core';

interface CustomConfig {
  apiKey: string;
}

// Create handler instance with function-based CRUD operations
function createProductHandler(): BaseResourceHandler<CustomConfig> {
  return new (class extends BaseResourceHandler<CustomConfig> {
    protected readonly metadata: ResourceMetadata = {
      namespace: 'product',
      description: 'Manage products',
      toolNamePrefix: 'mcp_custom_',
      schemas: {
        read: z.object({ id: z.string() }),
        create: z.object({ name: z.string(), price: z.number() }),
        update: z.object({ id: z.string(), name: z.string().optional() }),
        delete: z.object({ id: z.string() }),
      },
    };

    async read(context: ToolExecutionContext<CustomConfig>) {
      const { id } = context.parameters as { id: string };
      // Your API call logic
      return { id, name: 'Product' };
    }

    async create(context: ToolExecutionContext<CustomConfig>) {
      return { created: true };
    }

    async update(context: ToolExecutionContext<CustomConfig>) {
      return { updated: true };
    }

    async delete(context: ToolExecutionContext<CustomConfig>) {
      return { deleted: true };
    }
  })();
}

// Use in MCP server
const server = createMCPServer('auth-token', { apiKey: 'key' }, [
  createProductHandler(),
]);

3. 商业工具 核心工具(以装饰品为基础)

扩展商务工具处理器并使用装饰器 :

import {
  CustomerHandler as BaseCustomerHandler,
  ToolHandler,
  getDecoratorRegisteredHandlers,
} from '@commercetools/tools-core';

// Simply extend and decorate - automatically registered!
@ToolHandler()
export class CustomerHandler extends BaseCustomerHandler {
  // Optionally override methods for custom behavior
  override getToolDefinition(
    operation: 'read' | 'create' | 'update' | 'delete'
  ) {
    const base = super.getToolDefinition(operation);
    return {
      ...base,
      description: `Custom: ${base.description}`,
    };
  }
}

// In your MCP server setup
import { createMCPServer } from './mcp.server';
import { getDecoratorRegisteredHandlers } from '@commercetools/tools-core';

// Import handlers to trigger decorator registration
import './handlers/customer.handler';
import './handlers/project.handler';

// Get all registered handlers
const handlers = getDecoratorRegisteredHandlers();

const server = createMCPServer(authToken, configuration, handlers);

4. 核心工具(基于功能)

使用函数创建商务工具处理器 :

import {
  CustomerHandler,
  ProjectHandler,
  BaseResourceHandler,
  type Configuration,
  type IApiClientFactory,
  type ToolExecutionContext,
} from '@commercetools/tools-core';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';

// Create handler instance with custom factory
function createCustomerHandler(
  apiClientFactory?: IApiClientFactory<Configuration>
) {
  return new CustomerHandler(apiClientFactory);
}

// Create MCP server with function-based handlers
export function createMCPServer(
  authToken: string,
  configuration: Configuration,
  handlers: BaseResourceHandler<Configuration>[] = []
): McpServer {
  const server = new McpServer({
    name: 'commercetools-mcp-server',
    version: '1.0.0',
  });

  // Use function-created handlers
  const customerHandler = createCustomerHandler();
  const projectHandler = new ProjectHandler();

  const allHandlers =
    handlers.length > 0 ? handlers : [customerHandler, projectHandler];

  // Register each handler's tools
  for (const handler of allHandlers) {
    const toolDefinitions = handler.getAllToolDefinitions();

    for (const toolDef of toolDefinitions) {
      server.registerTool(
        toolDef.name,
        {
          title: toolDef.title,
          description: toolDef.description,
          inputSchema: toolDef.inputSchema as any,
          annotations: toolDef.annotations,
        },
        async (args: any): Promise<any> => {
          const context: ToolExecutionContext<Configuration> = {
            authToken,
            configuration,
            toolName: toolDef.name,
            parameters: args,
          };

          try {
            const result = await handler.execute(context);
            return {
              content: [
                {
                  type: 'text' as const,
                  text: JSON.stringify(result),
                },
              ],
            };
          } catch (e) {
            console.error(e);
            throw e;
          }
        }
      );
    }
  }

  return server;
}

// Usage
const server = createMCPServer(process.env.AUTH_TOKEN!, {
  projectKey: 'my-project',
  correlationId: 'my-correlation-id',
  tools: ['customer', 'project'],
});

5. 完成 MCP 服务器示例(合并两种方法)

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import {
  BaseResourceHandler,
  CustomerHandler,
  ProjectHandler,
  getDecoratorRegisteredHandlers,
  type ToolExecutionContext,
  type Configuration,
} from '@commercetools/tools-core';

// Function to create MCP server with both decorator and manual handlers
export function createMCPServer(
  authToken: string,
  configuration: Configuration
): McpServer {
  const server = new McpServer({
    name: 'commercetools-mcp-server',
    version: '1.0.0',
  });

  // Get decorator-registered handlers (class-based with @ToolHandler())
  const decoratorHandlers = getDecoratorRegisteredHandlers();

  // Create function-based handlers
  const functionHandlers: BaseResourceHandler<Configuration>[] = [
    new CustomerHandler(),
    new ProjectHandler(),
  ];

  // Combine all handlers
  const allHandlers = [...decoratorHandlers, ...functionHandlers];

  // Register tools from all handlers
  for (const handler of allHandlers) {
    const toolDefinitions = handler.getAllToolDefinitions();

    for (const toolDef of toolDefinitions) {
      server.registerTool(
        toolDef.name,
        {
          title: toolDef.title,
          description: toolDef.description,
          inputSchema: toolDef.inputSchema as any,
          annotations: toolDef.annotations,
        },
        async (args: any) => {
          const context: ToolExecutionContext<Configuration> = {
            authToken,
            configuration,
            toolName: toolDef.name,
            parameters: args,
          };

          try {
            const result = await handler.execute(context);
            return {
              content: [
                {
                  type: 'text' as const,
                  text: JSON.stringify(result, null, 2),
                },
              ],
            };
          } catch (error) {
            return {
              content: [
                {
                  type: 'text' as const,
                  text: `Error: ${
                    error instanceof Error ? error.message : String(error)
                  }`,
                },
              ],
              isError: true,
            };
          }
        }
      );
    }
  }

  return server;
}

工具标题和 MCP 说明

每个工具定义都带有人可读性 title 和一个完整的MCP annotations 对象(title, (中文(简体) ), readOnlyHint, (中文(简体) ), destructiveHint, (中文(简体) ), openWorldHint与 name, (中文(简体) ), description 财务报告和审定财务报表 inputSchema,所以一个MCP 客户端知道 read_orders 从 update_orders 当决定运行时 不询问用户.

两者都是 来源于工具名 而不是每个工具存储,通过 src/utils/tool-annotations.ts。一个动词表将工具名的动词映射到 对环境的影响——读取、添加或破坏性——和标题 并随附说明。 稍后添加的工具会自动附加说明, 没有第二个位置更新.

接受两个名称形状,所以同一个表格为服务器服务,以重命名 此软件包定义的工具 : verb_resource (单位:千美元)read_orders)),这是如何 这里的工具被命名,以及 resource.verb (单位:千美元)orders.read) (中文(简体) ). 名称的任意一端 中,无论哪个段都与已知动词相匹配.

import {
  deriveToolAnnotations,
  deriveToolAnnotationsOrConservative,
} from '@commercetools/tools-core';

deriveToolAnnotations('read_orders');
// { title: 'Read Orders', readOnlyHint: true, destructiveHint: false, openWorldHint: false }

deriveToolAnnotations('update_orders');
// { title: 'Update Orders', readOnlyHint: false, destructiveHint: true, openWorldHint: false }

// The `resource.verb` shape resolves to the same effect.
deriveToolAnnotations('orders.read');
// { title: 'Orders Read', readOnlyHint: true, destructiveHint: false, openWorldHint: false }

两个入站点,按呼叫站点划分:

  • deriveToolAnnotations 掷出 在一个无法识别的动词上。 用在楼上 路径——计划发射器,代码生成器——所以 CI 失败而不是发布 一个猜测的安全提示.
  • deriveToolAnnotationsOrConservative 倒计时 readOnlyHint: false 编号 : destructiveHint: true 然后通过可选的回调报告倒计时 所以可以登录 在服务路径上使用, 其中必须有一个未知的工具 不带 tools/list 给整个房客.

关于分类的说明:

  • 全体 update_* 工具为 破坏性。删除商务工具更新动作 线性项目和覆盖字段,而不只是添加.
  • create_* 财务报告和审定财务报表 replicate_carts 为: 添加剂 他们带来了新的资源 并留下剩下的东西.
  • openWorldHint 实值 false 到处都是 每个工具都使用一个单一工具 商业工具项目,通过一个范围化的符号进行,这是一个封闭的域名 感知到MCP的特性.
  • idempotentHint 省略。 写作用乐观货币保管 版本,所以重复的呼叫被拒绝而不是被吸收; spec's 默认 false 是诚实的答案.
  • writeHint 实值 没有 在 MCP 谱中,并且永远不会被排放。 光谱 表示写作 readOnlyHint: false。 。 。 .

如果你不同意分类, VERB_EFFECTS 内 src/utils/tool-annotations.ts 是改变它的唯一地方.

密钥设计模式

  1. 模板方法模式数字 : BaseResourceHandler.execute() 定义算法结构,而子类则执行特定的 CRUD 操作.

  2. 战略模式数字 : IApiClientFactory 曝光情况 getClient(configuration, authToken) 并允许注入不同的客户端创建策略(例如默认) ApiClientFactory 用于 CommercetoolsAPIClient) (中文(简体) ).

  3. 客户端/ API 根分离: 工厂只返回低层 客户端处理器获得该客户端并构建适当的 API 根 (格式或退出)使用 createApiBuilderFromCtpClient 从相应的SDK.

  4. 装饰图案数字 : @ToolHandler() 装饰者将注册行为添加到处理类. 处理器也可以通过直接即时(例如:. new CustomerHandler())而不使用装饰或注册.

  5. 工厂模式数字 : ApiClientFactory 通过 CommercetoolsAPIClient;处理器然后从该客户端建立平台或检查出 API 根.

  6. 依赖性注射: 处理器接受可选 IApiClientFactory 在其构建器中,允许测试性和定制客户端执行.

版本与发布记录

@commercetools/tools-core 共发布 28 个版本,首次发布于 2026/01/26;过去 12 个月发布了 28 个版本。

版本发布日期距今
0.7.1latest2026/11/091 天前
0.6.22026/10/1525 天前
0.6.12026/10/1526 天前
0.0.140.0-lts2026/10/1427 天前
0.6.02026/10/1427 天前
0.5.02026/09/301 个月前

关于 @commercetools/tools-core 的常见问题

@commercetools/tools-core 是什么?

商业工具工具系统核心

如何安装 @commercetools/tools-core?

在项目目录运行 npm install @commercetools/tools-core,或使用 pnpm add / yarn add / bun add。

@commercetools/tools-core 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@commercetools/tools-core 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@commercetools/tools-core 需要什么版本的 Node.js?

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

@commercetools/tools-core 可以商用吗?

@commercetools/tools-core 使用 UNLICENSED 许可。作者声明为 UNLICENSED,即不授予公开使用许可(与公共领域的 Unlicense 不同)。使用前需获得作者授权。以上为概括,不构成法律意见,请以许可原文为准。

@commercetools/tools-core 的下载量有多少?

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

@commercetools/tools-core 还在维护吗?

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