ChatbotX

io.chatbotx由 chatbotx.io 发布官方发布者v1.8.1更新于 Nov 6, 2026

Omnichannel customer messaging, CRM contacts, flows, sequences, broadcasts, and AI automation.

已验证Streamable HTTP可网页运行效率与工作流沟通与协作商业与电商

概览

AI 生成的概览

ChatbotX MCP 让助手接入 ChatbotX 工作区,管理联系人、会话、流程、群发、序列和 AI 智能体。

可以做什么
  • 查询工作区能力、令牌权限范围与流程规范结构
  • 管理联系人:创建、查询、打标签、设置自定义字段、发送消息或流程、订阅序列
  • 处理会话与消息:列出、读取、分配给成员或收件箱团队
  • 操作流程、群发、序列、关键词、管线和迷你应用
  • 创建和更新 AI 智能体,列出 AI 文件与函数
  • 查看分析与错误日志,并在完整 API 中检索其他操作
适用场景
适合让助手直接操作 ChatbotX 客户消息工作区:查询联系人和会话、起草或发布流程、发送消息,或获取群发与流程的分析数据,而无需切换工具。
运行要求
远程端点位于 app.chatbotx.io,使用 Streamable HTTP 或 SSE,需通过 OAuth 2.1 登录并选择工作区,仅工作区所有者与 superAdmin 成员可授权。另有本地 stdio 方式,需 Node.js 24 或更高版本、CHATBOTX_API_URL 以及 CHATBOTX_API_KEY 中的工作区令牌。
安装前请注意
令牌作用于已授权的工作区,切换工作区需断开后重新连接。写操作需显式确认并带 _confirm 重发,这只是防护措施而非授权边界。消息、流程和群发可能发送给真实联系人。connections_create 返回的一次性密钥令牌只显示一次。旧式配置可能把工作区令牌放在 URL 查询参数中。

安装

在 SourceWeft 中

  1. 打开 控制台中的 ChatbotX,将其添加到工作区。
  2. 连接 所需的 凭据。它们会被私密存储,绝不会在公开页面上展示。
  3. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.chatbotx%2Fmcp/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。 客户端会在首次连接时完成 OAuth 登录。

{
  "mcpServers": {
    "chatbotx": {
      "type": "http",
      "url": "https://app.chatbotx.io/mcp/messages"
    }
  }
}

README

ChatbotX MCP Server

Model Context Protocol server for ChatbotX. Gives AI agents (Claude, Cursor, ChatGPT, etc.) access to your ChatbotX workspace through tools that are automatically generated from the ChatbotX OpenAPI spec — no manual tool definitions needed.

Published skill/agent distribution docs live in the separate chatbotx-agent package; this repo owns the MCP server implementation and README.

How it works

On startup the server fetches {CHATBOTX_API_URL}/public-spec.json and registers one MCP tool per API operation the spec marks x-mcp.visibility: "default". CHATBOTX_API_URL is the origin including the /api path prefix (e.g. https://app.chatbotx.io/api). Adding a new default-visible API endpoint in ChatbotX automatically makes it available as a tool — the spec is re-fetched in the background whenever it's older than CHATBOTX_SPEC_TTL_MS (default 5 minutes), so a new/changed operation shows up on the next tools/list call without a server restart.

OAuth 2.1

Remote MCP clients should authenticate through OAuth 2.1. The production endpoints are https://app.chatbotx.io/mcp/messages for Streamable HTTP and https://app.chatbotx.io/mcp/sse for legacy SSE — the same URL for every account, so it works as a Claude or ChatGPT marketplace connector. The user picks the target workspace on the consent screen, and every token the client holds acts on that workspace; to switch, disconnect and connect again. Only workspace owners and superAdmin members can authorize. An explicit ?workspace_id=<id> (or x-workspace-id header) may select a workspace only for legacy connections that predate the picker. A different workspace than the one consented for a new connection is rejected; disconnect and connect again to switch. The builder settings block Settings → Integrations → ChatbotX MCP provides the exact connection URL and lets each user revoke their OAuth grants.

Legacy workspace tokens remain supported for stdio and existing connections.

Default tools vs. the full API

ChatbotX's public API has ~350 operations. Listing all of them as MCP tools overwhelms an agent's context and its ability to pick the right one, so tools/list returns only a curated default set (see below) plus three meta-tools:

ToolDescription
search_toolsSearch the full API for a tool not in the default set. Returns { matches, hint? }, where each match has its name, description, and input schema.
call_toolExecute any tool by name, including ones search_tools found but tools/list doesn't show.
get_guideRead an operational safety guide when a workflow involves approvals, flows, inbox handover, contacts, or pipelines.

Use search_tools when the task needs something outside the default set (e.g. deleting a resource, managing AI agents, coupons, products) — then invoke it with call_tool.

search_tools's catalog (tool names, summaries, descriptions) is entirely English. The calling client must translate the user's intent into an English "action + resource" query before searching; the ranker does not translate. When an accented Latin or non-Latin query reaches the server, search_tools returns a hint asking the client to translate and retry in English.

  • Name normalization: a dotted or camelCase operation label (contacts.get, contactsGet) is accepted and re-derived to the executable snake_case name — you don't have to pass the exact string search_tools returned.
  • Unknown-tool suggestions: an unrecognized name returns the closest matching tool names instead of a bare error, so a model can self-correct without another search_tools round trip.
  • Pre-flight argument check: a call_tool invocation missing a field the selected tool's inputSchema marks required is rejected immediately with the missing field names, instead of waiting for the real API's 422. A common wrapper mistake (nesting every field under body/params/input instead of passing them at the top level) is called out explicitly.
  • Contact identifier auto-prefix: a bare email, +-prefixed or local 0-prefixed phone number, or numeric id passed as identifier to a contact tool is automatically prefixed (email:/phone:/id:) before the request is sent, matching what the API actually requires.

Human approval

Every operation carries an x-mcp.hitlPolicy from the public OpenAPI spec; reads use none. Mutating operations return CONFIRMATION_REQUIRED with the policy, proposed arguments, and current state when available; show that response to the user, then repeat the same call with _confirm: true only after explicit approval. _confirm is a compatibility guardrail, not an authorization boundary.

Writes that are read-only computations declare hitlPolicy: "none" in the backend. Destructive writes also carry the MCP destructiveHint annotation. When a current-state read fails for any reason, currentState is omitted and currentStateUnavailable explains why; the failed read never blocks confirmation.

Every tools/list definition also includes a human-readable title and explicit readOnlyHint, destructiveHint, idempotentHint, and openWorldHint annotations. Dynamic tool titles come from the OpenAPI operation summary. The loader marks confirm_outbound operations as open-world by default; an x-mcp.openWorldHint override takes precedence.

Scope-based filtering

tools/list is further narrowed to what the calling token can actually use, resolved once per token via GET /v1/token (introspectToken, cached per token value for CHATBOTX_SPEC_TTL_MS):

  • A token missing a scope never sees that scope's tools (they still exist for search_tools/call_tool, which always hit the real API and get a real 403 if unauthorized).
  • A read_only token only sees tools whose readOnlyHint annotation is true — every GET by default, plus any POST explicitly marked x-mcp.readOnlyHint: true for an endpoint that reads without writing (no default tool currently uses this).
  • capabilities_get and token_get are always visible regardless of scope — an agent needs them to discover what it can do and what its token allows before anything else works.
  • If token introspection itself fails (network blip, unreachable API), filtering fails open — tools/list falls back to the full default set. The actual API call still enforces the token's real permissions either way.

Discovery tools an agent should call first

ToolDescription
capabilities_getDiscover workspace entities and query channel before authoring a channel-bound FlowSpec to receive its supported blocks and limits.
token_getGet the calling token's workspace id, permission (read_only/full), and scopes — check before attempting a write.
schemas_flow_specGet the JSON Schema for the spec object flows_publish/flows_update_draft/flows_validate accept — the authoritative reference for every flow step type.

Available tools

Tool names are derived from the OpenAPI operationId converted to snake_case (e.g. tags.list → tags_list). The current default set has 52 tools:

Capabilities

ToolDescription
capabilities_getDiscover workspace entities and a requested channel's FlowSpec policy
schemas_flow_specGet JSON Schema for flow-spec DSL
token_getGet calling token workspace id, permission, and scopes

AI Agents

ToolDescription
ai_agents_listList AI agents
ai_agents_createCreate AI agent
ai_agents_updateUpdate AI agent
ai_files_listList AI files
ai_functions_listList AI functions

Analytics

ToolDescription
analytics_new_contact_counts_per_dayGet new contact counts per day
analytics_blocked_contacts_per_dayGet blocked contacts per day
analytics_flow_statsGet flow analytics
analytics_broadcast_statsGet broadcast stats
analytics_sequence_step_statsGet sequence step stats

Broadcasts

ToolDescription
broadcasts_listList broadcasts
broadcasts_getGet broadcast
broadcasts_stopStop broadcast

Connections

ToolDescription
connections_createConnect channel or integration
connection_providers_listList connection providers
connect_sessions_getGet connect session

For connections_create with provider: "api", the response includes a one-time secret.token. Store it before discarding the response; it is never retrievable again.

Contacts

ToolDescription
contacts_createCreate contact
contacts_getGet contact by identifier (id:123, email:[email protected], phone:+84...)
contacts_listList contacts
contacts_list_tagsGet all tags added to contact
contacts_add_tags_by_nameAdd tags to contact by name
contacts_list_custom_fieldsGet all custom fields from contact
contacts_set_custom_fieldSet contact custom field value
contacts_list_messagesList messages for contact
contacts_send_messageSend message to contact
contacts_send_flowSend flow to contact
contacts_list_sequencesList contact sequence subscriptions
contacts_subscribe_sequencesSubscribe contact to sequences

Conversations

ToolDescription
conversations_listList conversations
conversations_getGet conversation
conversations_assignAssign or unassign conversation to user or inbox team

Error Logs

ToolDescription
error_logs_listList error logs

Flows

ToolDescription
flows_listList flows
flows_getGet flow
flows_createCreate flow
flows_update_draftUpdate flow draft
flows_publishPublish flow
flows_validateCompile and validate flow spec without publishing

Keywords

ToolDescription
keywords_listList keywords (automated responses)

Messages

ToolDescription
messages_listList messages on conversation

Mini Apps

ToolDescription
mini_apps_listList Mini Apps
mini_apps_createCreate Mini App

Pipelines

ToolDescription
pipelines_listList pipelines
pipelines_list_itemsList pipeline items
pipelines_create_itemCreate pipeline item
pipelines_move_itemMove item to stage

Sequences

ToolDescription
sequences_listList sequences
sequences_getGet sequence
sequences_updateUpdate sequence name or active state

Everything else — deletes, less-common resources (coupons, products, webhooks, saved replies, tags/triggers/inboxes/custom-fields management, workspace members, etc.), connection lifecycle management beyond the initial connect (disconnect, reconnect, refresh, verify, rename) — is reachable via search_tools → call_tool, not tools/list.

Operations whose security names no workspace-token scheme are not tools at all — isWorkspaceTokenOperation (src/openapi-loader.ts) drops them, so neither tools/list nor search_tools returns them. That covers deprecated operations, channel-token operations (/v1/channels/api/*), and the mobile-app-only member surface (/v1/me*, /v1/realtime/connect-token, marked by MOBILE_APP_TOKEN_ONLY_PATHS in apps/builder/src/lib/orpc/public-spec.ts): an MCP OAuth or workspace token has no member identity and would always get 401.

conversations_list accepts view: "compact" to drop ad attribution and thread-control metadata from each conversation's contact inboxes (default full); flows_list accepts enableInInbox: true to return only flows that can be started from the inbox.

Prerequisites

  • Node.js >= 24
  • A workspace token only for the stdio and workspace-token connection options.

Quick start

Option A — OAuth (recommended, remote)

Use the builder-hosted MCP endpoint. The client opens a browser for sign-in and consent; no workspace token belongs in the client configuration.

Claude Code:

bash
claude mcp add chatbotx -t http -s user \  "https://app.chatbotx.io/mcp/messages"

Claude Desktop / Cursor:

json
{  "mcpServers": {    "chatbotx": {      "type": "http",      "url": "https://app.chatbotx.io/mcp/messages"    }  }}

ChatGPT: add https://app.chatbotx.io/mcp/sse as a custom connector. ChatGPT completes OAuth in the browser.

The load balancer must forward /mcp/* to the MCP server without stripping the /mcp prefix. The builder serves protected-resource discovery under /.well-known/oauth-protected-resource/mcp/*.

Option B — stdio (workspace token, local use)

Claude spawns the server process on demand. No server needs to be running. The workspace token is supplied via CHATBOTX_API_KEY.

The package is published to npm as chatbotx-mcp — npx -y chatbotx-mcp fetches and runs it with no local checkout or build required. Use a local node /path/to/dist/index.mjs instead when developing against this repo.

Claude Code CLI:

bash
claude mcp add chatbotx \  -e CHATBOTX_API_KEY=<your-token> \  -e CHATBOTX_API_URL=https://your-instance.com/api \  -e CHATBOTX_MCP_TRANSPORT=stdio \  -s user \  -- npx -y chatbotx-mcp

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):

json
{  "mcpServers": {    "chatbotx": {      "command": "npx",      "args": ["-y", "chatbotx-mcp"],      "env": {        "CHATBOTX_API_KEY": "<your-token>",        "CHATBOTX_API_URL": "https://your-instance.com/api",        "CHATBOTX_MCP_TRANSPORT": "stdio"      }    }  }}

Running from a local checkout instead (e.g. node /path/to/dist/index.mjs) works the same way — swap command/args accordingly.

Option C — SSE (workspace token, shared / remote access)

Run the server once and multiple clients connect via URL. Pass the workspace token in the request header.

bash
# Start the serverpnpm start
# Add to Claude Code CLIclaude mcp add chatbotx \  -t sse \  -H "x-workspace-token: <your-token>" \  -s user \  "https://your-mcp-server.com/sse"

Claude Desktop:

json
{  "mcpServers": {    "chatbotx": {      "type": "sse",      "url": "https://your-mcp-server.com/sse",      "headers": {        "x-workspace-token": "<your-token>"      }    }  }}

Option D — ChatGPT.com (workspace-token SSE)

ChatGPT.com connects via SSE. The server must be publicly reachable. Because ChatGPT does not support custom request headers, pass the workspace token directly in the URL:

  1. Start the server with CHATBOTX_MCP_TRANSPORT=sse (or both).
  2. In ChatGPT Settings → Connectors → Add custom connector, set the URL:
    https://your-mcp-server.com/sse?workspace_token=<your-token>
    When using this URL in a shell command, always quote it to prevent ? being interpreted as a glob:
    bash
    claude mcp add chatbotx -t sse -s user "https://your-mcp-server.com/sse?workspace_token=<your-token>"
  3. Set CHATBOTX_MCP_SERVER_INSTRUCTIONS so ChatGPT uses tools instead of its training data. Leave it unset unless replacing the full built-in workflow, including OAuth checkpoints.

Token resolution order

TransportPriority
SSE / Streamable HTTPAuthorization: Bearer (OAuth access token or workspace token) → ?workspace_token= or ?token= query param → x-workspace-token / x-chatbo-token header → CHATBOTX_API_KEY env
stdioCHATBOTX_API_KEY env

Configuration

Copy .env.example to .env and fill in the values:

bash
cp .env.example .env
VariableDescriptionDefaultRequired
CHATBOTX_API_KEYWorkspace token for stdio only; leave empty on shared HTTP deployments—Yes (stdio)
CHATBOTX_API_URLChatbotX API origin, including /api (e.g. https://app.chatbotx.io/api)https://app.chatbotx.io/apiYes
CHATBOTX_ALLOW_SELF_SIGNED_CERTDisable TLS verification (true/false)—No
CHATBOTX_SPEC_TTL_MSHow long the fetched OpenAPI spec/tool list and a token's introspected scopes are trusted before a background re-fetch300000No
CHATBOTX_HTTP_TIMEOUT_MSMaximum duration for each OpenAPI, token introspection, or tool-call HTTP request30000No
CHATBOTX_MCP_TRANSPORTstdio | sse | bothbothNo
CHATBOTX_MCP_HOSTSSE server host0.0.0.0No
CHATBOTX_MCP_PORTSSE server port3333No
CHATBOTX_MCP_SSE_PATHSSE endpoint path/sseNo
CHATBOTX_MCP_MESSAGES_PATHJSON-RPC messages path/messagesNo
CHATBOTX_MCP_CORS_ORIGINCORS origin allowed to call the SSE/HTTP endpoints*No
CHATBOTX_MCP_SERVER_NAMEDisplay name sent to AI clientspackage nameNo
CHATBOTX_MCP_SERVER_INSTRUCTIONSInstructions sent to AI clients on connect (helps ChatGPT know when to call tools)built-in defaultNo
CHATBOTX_MCP_OAUTH_ENABLEDEnable OAuth 2.1 protected-resource metadata and bearer challengestrueNo
CHATBOTX_MCP_OAUTH_ISSUERAuthorization server issuer URLderived from CHATBOTX_API_URLNo
CHATBOTX_MCP_PUBLIC_URLCanonical public origin; required in production so metadata advertises the TLS endpointderived from request headersYes (production)

Scripts

bash
# Development with watch modepnpm dev:mcp
# Build for productionpnpm build
# Run built serverpnpm start
# Type checkpnpm check-types
# List loaded tools (requires CHATBOTX_API_URL and CHATBOTX_API_KEY in .env)dotenv -e .env -- tsx src/test-tools.ts

Evaluating tool selection

Two layers of evaluation cover search_tools/call_tool accuracy — a fast offline gate and a full LLM-driven business eval.

eval:search — offline ranking gate (no API key, seconds)

Scores every prompt in the eval corpus (evals/cases.ts) through the real searchTools() ranker against a real generated spec, with no LLM in the loop. Use this after any change to src/server/search/ or to a public route's summary/description.

  1. Dump the current OpenAPI spec (the builder test already has a hook for this — see apps/builder/__tests__/public-spec-operations.test.ts):
    bash
    MCP_EVAL_SPEC_OUTPUT=/absolute/path/public-spec.json \  pnpm --filter builder test -- public-spec-operations.test.ts
  2. Run the gate against it:
    bash
    pnpm --filter chatbotx-mcp eval:search --spec /absolute/path/public-spec.json [--min-top1 0.65] [--min-top3 0.85] [--verbose]
    Prints per-locale top-1/top-3/empty-result rates, but enforces the configured thresholds only for English. --verbose also lists every prompt that missed the top 3, with the ranker's actual top matches, for targeted ranking or description fixes.

eval:business — full LLM-driven business eval

Spins up a synthetic HTTP sandbox implementing the generated spec's operations, connects a real MCP client, and drives gpt-4o-mini/gpt-4.1-mini (or any @ai-sdk/openai-supported model) through the selected corpus. business contains 240 prompts (48 families × 5 locales: vi, vi-unaccented, colloquial, en, mixed); multilingual is the 80-case smoke matrix (16 families × en, vi-natural, es, fr, zh). Requires OPENAI_API_KEY.

bash
pnpm --filter chatbotx-mcp eval:business \  --spec /absolute/path/public-spec.json \  --out /absolute/path/out/baseline \  --phase smoke \  --seed 20260923 \  --models gpt-4o-mini,gpt-4.1-mini \  [--repeat N] \  [--corpus business|multilingual] \  [--exposure default|meta-only|both] \  [--cases family-a,family-b] \  [--server-source /absolute/path/to/apps/mcp-server]
  • --repeat N runs every selected case under every model and exposure N times. Smoke runs default to 3; baseline and candidate runs default to 1.
  • --exposure meta-only restricts the model's tool set to search_tools/call_tool only (no directly-listed default tools) — the path a client using only the default connection payload takes for any request outside the ~45 default-visible tools. both (the default) runs every case under both exposures.
  • Each episode is graded on semantic arguments, ordered tool sequences, its expected final HTTP state, API-error claims, post-failure mutations, and step exhaustion. The summary reports the pass rate per model × exposure × locale × family; episodes also record searchRank, callToolErrorCount, and unknownToolCount.
  • The smoke sandbox includes contact, conversation reply, flow, broadcast, appointment, and analytics fixtures. No public appointment-availability operation exists, so unavailable-slot coverage exercises appointments_book returning 422.
  • Compare two runs (regressions fail the command):
    bash
    pnpm --filter chatbotx-mcp eval:business --compare /absolute/path/out/baseline /absolute/path/out/candidate
    Reports any case that regressed from pass to non-pass, plus the average searchRank and total callToolErrorCount delta between the two runs.

Evaluation output is written under evals/out/ (gitignored) unless --out points elsewhere.

Project structure

src/├── index.ts                # Entry point — loads spec, starts transport(s)├── env.ts                  # Environment variable schema├── guides/                 # Packaged markdown operational guides├── http.ts                 # Timed fetch helper for OpenAPI, token, and tool requests├── openapi-loader.ts       # Fetches OpenAPI spec → DynamicTool list, x-mcp│                           # visibility/scope/HITL parsing, scope-filtered getVisibleTools()├── token-introspection.ts  # GET /v1/token → cached {permission, scopes} per token├── test-tools.ts           # Dev utility — prints loaded tools└── server/    ├── create-mcp-server.ts   # MCP server factory, resources, tools/list + tools/call    ├── hitl-gate.ts           # Two-step confirmation gate for mutations    ├── meta-tools.ts          # search_tools / call_tool / get_guide definitions    ├── execute-tool.ts        # Shared HTTP dispatch, confirmation, argument normalization    ├── search/                # search_tools ranking: normalization and IDF scoring    ├── sse-server.ts          # SSE / Streamable HTTP transport    └── stdio-server.ts        # stdio transport
evals/├── cases.ts           # Eval corpus: business-intent prompts × 5 locale variants├── sandbox.ts         # Synthetic HTTP server implementing the generated spec├── run.ts             # eval:business — drives an LLM through the MCP server└── search-audit.ts    # eval:search — offline ranking gate, no LLM

Troubleshooting

Tools not showing up

  • Check that CHATBOTX_API_URL is reachable and {CHATBOTX_API_URL}/public-spec.json returns a valid OpenAPI spec.
  • Only operations the spec marks x-mcp.visibility: "default" appear in tools/list — everything else is reachable via search_tools/call_tool. See "Default tools vs. the full API" above.
  • The spec/tool list refreshes automatically every CHATBOTX_SPEC_TTL_MS (default 5 minutes); a brand-new operation may take that long to appear without a restart.
  • A token missing a required scope, or a read_only token calling a write endpoint's tool, will not see that tool — see "Scope-based filtering" above.
  • Check stderr output on startup — the server logs Loaded N tools from OpenAPI spec.

Port already in use

bash
lsof -ti:3333 | xargs kill -9

Self-signed certificate errors

bash
CHATBOTX_ALLOW_SELF_SIGNED_CERT=true

SSE connection fails in Claude

  • Prefer stdio mode for local use — it has no network dependency.
  • For SSE, verify the server is running and the URL/port are reachable from the client.

ChatGPT uses its training knowledge instead of calling tools

  • Set CHATBOTX_MCP_SERVER_INSTRUCTIONS to explicitly instruct ChatGPT to use tools (see .env.example).
  • Make sure the connector URL includes ?workspace_token=<your-token> so authentication is handled automatically.

来源:apps/mcp-server/README.md,提交 14c9034

工具

0
该服务器需要登录,因此 SourceWeft 无法在没有账号的情况下读取其工具,也未收录。已连接账号所能看到的内容可能因账号及其权限而异。

版本历史

1
  1. v1.8.1最新Nov 6, 2026

评分

已满足适用检查项的 75%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

    请在仓库或注册中心条目中声明许可证。