Skip to main content

canpoint-ui-mcp — UI 规范查询 MCP

「成果不出门、能力出门」:数据源是本仓库 docs/ 下两套 Design DNA(研学小程序 / 研学后台),服务端用显式 allowlist 投影对外提供 token、组件规格、生成纪律与 截图色彩校验;蓝湖溯源、逐画板中间测量、裁决证据明细等内部数据永不出服务端

0. 三层发布架构(对齐 canpoint-mcp)

使用方(Claude Code / Cursor / Codex)
   │  npx -y canpoint-ui-mcp                ← 第 1 层:npm 包装器(零依赖,按自身版本钉死 PyPI 版本)
   ▼
uvx --from canpoint-ui-mcp==X.Y.Z canpoint-ui-mcp
   │  stdio MCP(本仓库 ui_query_mcp.py)    ← 第 2 层:PyPI 薄客户端(只含客户端代码,wheel 白名单强制)
   │  Bearer usk_xxx(UI_SPEC_API_KEY)
   ▼
http://175.27.156.19:47393/mcp
      远程 FastAPI + FastMCP streamable-http ← 第 3 层:服务端(本仓库 app/,Docker 部署,不进 wheel)
  • 工具(6 个,三层同名同签名):list_platforms / get_tokens / list_components / get_component_spec / get_generation_rules / verify_ui
  • 健康检查:GET /health(不鉴权,DNA 未全部就绪时返回 503 degraded)
  • env 前缀保持 UI_SPEC_* 不变(兼容服务器已部署的 .env):服务端用 UI_SPEC_HOST/PORT/KEY_FILE/DNA_*,客户端用 UI_SPEC_SERVER_URL/API_KEY/TIMEOUT/LOG_LEVEL

1. 使用方接入(两种方式)

A. npx 方式(推荐,stdio 薄客户端)

前置:已安装 uv(提供 uvx)。

Claude Code(项目 .mcp.json):

{
  "mcpServers": {
    "canpoint-ui": {
      "command": "npx",
      "args": ["-y", "canpoint-ui-mcp"],
      "env": {
        "UI_SPEC_SERVER_URL": "http://175.27.156.19:47393",
        "UI_SPEC_API_KEY": "usk_<服务管理员发放的key>"
      }
    }
  }
}

Cursor(mcp.json)同款。Windows 下若 npx 启动失败,把 command 改为 cmdargs 改为 ["/c", "npx", "-y", "canpoint-ui-mcp"](env 表不变)。

不经 npm 直接用 PyPI 包:uvx canpoint-ui-mcp(同样注入两个 env)。

B. 直连 http 方式(streamable-http)

{
  "mcpServers": {
    "canpoint-ui": {
      "type": "http",
      "url": "http://175.27.156.19:47393/mcp",
      "headers": { "Authorization": "Bearer usk_<key>" }
    }
  }
}

2. 175 服务器部署流程(服务端)

构建上下文是仓库根(镜像需要 COPY docs/),Dockerfile 位于 mcp-server/ 下。

# 首次部署
git clone git@github.com:mjwyr/ui-knowledge.git /software/ui-knowledge
cd /software/ui-knowledge/mcp-server
cp .env.example .env            # 按需编辑(密钥路径等;env 前缀 UI_SPEC_* 不变)
cp keys.example.json keys.json  # 编辑发放真实 key(usk_ 前缀随机串)
cd /software/ui-knowledge
docker build -f mcp-server/Dockerfile -t canpoint-ui-mcp:latest .

# 启动(.env 与 keys.json 只读挂载,logs 落宿主机)
docker rm -f canpoint-ui-mcp 2>/dev/null
docker run -d --name canpoint-ui-mcp --restart unless-stopped \
  -p 47393:8002 -e TZ=Asia/Shanghai \
  -v /software/ui-knowledge/mcp-server/.env:/app/mcp-server/.env:ro \
  -v /software/ui-knowledge/mcp-server/keys.json:/app/mcp-server/keys.json:ro \
  -v /software/ui-knowledge/mcp-server/logs:/app/mcp-server/logs \
  canpoint-ui-mcp:latest

# 验证
curl -s http://127.0.0.1:47393/health   # 期望 {"status":"ok","data":{"mini":true,"admin":true}}

更新(数据或代码变更后):

cd /software/ui-knowledge && git pull
docker tag canpoint-ui-mcp:latest canpoint-ui-mcp:prev-$(date +%Y%m%d)   # 回滚锚点
docker build -f mcp-server/Dockerfile -t canpoint-ui-mcp:latest .
docker rm -f canpoint-ui-mcp && docker run -d ...(同上启动命令)

回滚docker tag canpoint-ui-mcp:prev-YYYYMMDD canpoint-ui-mcp:latest 后重跑 docker rm -f + docker run

3. 客户端包发布流程(PyPI + npm)

发布用一键脚本,版本号以 pyproject.toml 为唯一事实来源(自动同步到 npm/package.json):

cd mcp-server
python scripts/publish.py --dry-run                             # 试跑(构建+白名单校验,不真实发布)
python scripts/publish.py --set-version <版本> --platform all   # 正式发布
python scripts/publish.py --bump patch                          # 升补丁版本后双平台发布

脚本内置防线:

  • 版本重复探测:发布前 HTTP 探测 PyPI/npm,该版本已存在则拒发;
  • wheel 内容白名单:构建后逐条检查 zip 内容,app/tests/scripts/npm/Dockerfilerequirements*.txtkeys*.json.env 等任何一条命中 即拒发(服务端与密钥绝不进包);
  • npm 官方源钉死:全局 registry 是 npmmirror 只读镜像,脚本显式 --registry https://registry.npmjs.org/
  • 镜像同步:npm 发布成功后自动 PUT https://registry.npmmirror.com/-/package/canpoint-ui-mcp/syncs 触发 npmmirror 同步(同步完成前镜像侧 npx 仍拿旧版本)。

凭据位置(均不进 git):

  • PyPI:PYPI_TOKEN 环境变量,或本机已登录的 uvuv publish 直接发);
  • npm:NPM_TOKEN 环境变量(脚本写临时 npm/.npmrc,用后即删),或 ~/.npmrc 已登录态(npm login;Automation 类型 token 免 OTP)。

npm 包装器按自身版本号钉死 PyPI 包版本(uvx --from canpoint-ui-mcp==<npm版本>), 两平台必须同版本发布

4. key 发放 / 吊销流程

  1. 编辑服务器上的 /software/ui-knowledge/mcp-server/keys.json
    • 发放:追加 {"id":"姓名","key":"usk_<随机串>","enabled":true,"note":"用途"} (随机串生成:python -c "import secrets;print('usk_'+secrets.token_urlsafe(32))");
    • 吊销:把对应条目 enabled 改为 false 或直接删除。
  2. docker restart canpoint-ui-mcp(key 表在启动时加载)。
  3. key 表缺失/为空/解析失败时服务 fail-closed:进程照常启动、/health 可访问,但 /mcp 拒绝一切请求。

5. 审计日志

  • 服务端:mcp-server/logs/ui_audit.log(容器内 /app/mcp-server/logs/,按天轮转、 保留 30 天;服务端运行日志为同目录 ui_spec_server.log)。每次工具调用一行:

    2026-09-08 12:00:00,123 key_id=张三 tool=get_tokens args=platform=mini category=color status=ok took=5ms
    
  • 客户端:logs/ui_client.log(相对客户端进程工作目录,按天轮转、保留 30 天), 每次工具调用记 tool + 参数摘要(截断 80 字符)+ 结果状态 + 耗时;只写文件与 stderr,绝不写 stdout(stdio 协议流)。

  • 安全红线:绝不记录 key 值本身;绝不记录 base64 图片数据(verify_ui 只记 platform 与图片字节数);args 摘要单行化截断 80 字符。

6. 本地开发与测试

cd mcp-server
python --version            # 需要 3.10+
pip install -r requirements.txt   # 服务端依赖(客户端只需 mcp/httpx)
python -m unittest discover -s tests -v
# 本地起服务端
python -m app.main          # 或 uvicorn app.main:app --port 8002
# 本地起 stdio 客户端(连远程或本地服务端)
UI_SPEC_SERVER_URL=http://127.0.0.1:8002 UI_SPEC_API_KEY=usk_xxx python ui_query_mcp.py

环境变量见 .env.example(复制为 .env,不进 git);本地 keys.json 可参照 keys.example.json 制作(不进 git)。

7. 安全设计(投影 allowlist + wheel 白名单)

数据投影——出门的:色彩 token、typography 阶梯、spacing、shape、elevation、 layout/density(admin_chrome 几何、表格密度 token、breakpoints_fact、小程序 chrome)、组件规格、生成纪律(version_policy 结论、missing_states、裁决结论、 设计事实)、design_style 定性字段、visual_effects 结论字段。

永不出门的(app/views.py 结构性排除 + 字符串消毒双保险,测试断言): meta.source_referencesmeasured_palette 聚合、measurement 配置、 meta 其余溯源字段(lanhu_project / original_assets / sampling 说明等)、 任何含 lanhuapp / alipic / image_id / intermediate 路径的字符串、 adjudications 的 values/source 证据明细。

发布物收敛——PyPI wheel 只含 ui_query_mcp.pylogging_config.pyclients/(见 pyproject [tool.setuptools] 白名单),客户端依赖收敛为 mcp>=1.6,<2 + httpxscripts/publish.py 构建后强制校验,违规拒发。 API key 只从环境变量读取,绝不嵌入可分发包;UI_SPEC_SERVER_URL 拒绝内嵌 basic auth(key 是唯一客户端凭据)。

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

canpoint_ui_mcp-0.1.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file canpoint_ui_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: canpoint_ui_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.32 {"installer":{"name":"uv","version":"0.11.32","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for canpoint_ui_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ac025790642aeb4fc05e2e992beb85c0cf3063b7c43361d5d2b10724f74c6306
MD5 5d748273b69c7db3178c33f0a8cc92a3
BLAKE2b-256 39b060ed8cf4983abbff2df9cade5e4f2d992c2cfb82181f64d2d9091e14f98d

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.1

1 file

This release

0.1.0 This release

1 file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page