关于 CodeQR
CodeQR 的远程 MCP 服务让 AI 客户端管理 CodeQR 短链接、二维码和分析数据。通过 OAuth 2.0 授权可访问选定项目,无需处理 API 密钥。
主要功能
- 01创建和管理短链接
- 02创建和更新二维码
- 03查询点击分析数据
- 04管理域名、标签和工作区信息
- 05配置条件路由与流量拆分
适用场景
- 01在 AI 工作流中创建短链接
- 02更改已印刷二维码的目标地址
- 03查看链接点击情况
- 04设置条件重定向或流量测试
MCP 相关
通过使用 Streamable HTTP 和 OAuth 2.0 的远程 MCP 端点,提供 CodeQR 链接、二维码、分析和工作区操作。可选的 MCP Apps 会为链接、二维码和分析数据显示交互卡片。
配置
远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。
https://mcp.codeqr.io/mcpclaude mcp add --transport http io-codeqr-codeqr https://mcp.codeqr.io/mcp{"mcpServers":{"io-codeqr-codeqr":{"type":"http","url":"https://mcp.codeqr.io/mcp"}}}在 Cursor 中打开{"servers":{"io-codeqr-codeqr":{"type":"http","url":"https://mcp.codeqr.io/mcp"}}}在 VS Code 中打开{"mcpServers":{"io-codeqr-codeqr":{"type":"http","url":"https://mcp.codeqr.io/mcp"}}}{"mcpServers":{"io-codeqr-codeqr":{"serverUrl":"https://mcp.codeqr.io/mcp"}}}命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。
工具
详细介绍
CodeQR 远程 MCP 服务
适用于 CodeQR 的远程 MCP 服务,使用 OAuth 2.0 进行身份验证。兼容 ChatGPT、OpenAI Agents SDK、Grok (xAI),以及所有支持 Streamable HTTP 传输的 MCP 客户端。
工作原理
┌──────────┐ ┌─────────────────────┐ ┌──────────┐
│ ChatGPT │ │ CodeQR MCP Remote │ │ CodeQR │
│ or any │─────▶│ │─────▶│ API │
│ MCP │◀─────│ OAuth 2.0 + MCP │◀─────│ │
│ client │ │ Streamable HTTP │ │ │
└──────────┘ └─────────────────────┘ └──────────┘
- 客户端通过
/.well-known/oauth-protected-resource发现身份验证端点 - 客户端通过
POST /oauth/register动态注册 GET /oauth/authorize会显示此服务的授权确认页面,其中会显示应用自行声明的名称;除非其重定向 URI 与src/oauth/verified-clients.ts中列出的某个 URI 完全一致,否则会标记为未经验证;页面还会显示该重定向 URI 指向的主机。用户批准后会前往 CodeQR,在那里登录、选择要授权的项目并批准,整个过程中不会处理任何 API 密钥。 只有在批准授权的浏览器中才能完成回调。- CodeQR 会将用户重定向回
GET /oauth/callback,该端点会用授权码换取访问令牌和刷新令牌 - 客户端通过 PKCE 将授权码换取访问令牌
- 客户端携带 Bearer 令牌向
POST /mcp发送 MCP 工具调用
CodeQR 访问令牌有效期为 7 天,并会自动续期。每次续期都会让会话再延长 120 天,因此正在使用的连接不会在固定日期到期;闲置连接会在最后一次续期 120 天后到期;所有连接的有效期都不会超过创建后一年(客户端收到的 expires_in)。
快速开始
# Install dependencies
npm install
# Set environment variables
cp .env.example .env
# Edit .env with your SERVER_URL
# Development
npm run dev
# Production
npm run build
npm start
部署
Vercel(推荐)
此项目已配置为适用于 Vercel 无服务器函数:
# Install Vercel CLI
npm i -g vercel
# Deploy
vercel
# Set environment variables in Vercel dashboard:
# - SERVER_URL — Your public server URL (e.g., https://mcp.codeqr.io)
# - UPSTASH_REDIS_REST_URL — From your Upstash Redis database (REST API)
# - UPSTASH_REDIS_REST_TOKEN — From your Upstash Redis database
# - CODEQR_OAUTH_CLIENT_ID — client_id of the OAuth app registered in CodeQR
# - CODEQR_OAUTH_CLIENT_SECRET — its client_secret
# - CODEQR_APP_URL — Dashboard origin (default: https://app.codeqr.io)
# - MCP_UI_ENABLED — Set to 1 to show the item card in hosts that render MCP Apps (off when unset)
# - STAINLESS_API_KEY — Optional Stainless API key
# - LOG_LEVEL — Log level (default: info)
应用将在 https://your-project.vercel.app 上提供服务。所有路由均由 api/server.ts 中的无服务器函数处理。
**OAuth 存储:**设置 Upstash Redis(UPSTASH_REDIS_REST_URL 和 UPSTASH_REDIS_REST_TOKEN),以便授权码、访问令牌和已注册客户端在无服务器函数调用之间持久保存。如果未设置这些变量,服务会回退到内存存储(仅适用于本地开发)。
Docker
docker build -t codeqr-mcp-remote .
docker run -p 3000:3000 -e SERVER_URL=https://mcp.codeqr.io codeqr-mcp-remote
Railway / Render / Fly.io
设置环境变量:
SERVER_URL— 公共服务 URL(例如,https://mcp.codeqr.io)UPSTASH_REDIS_REST_URL/UPSTASH_REDIS_REST_TOKEN— 多实例部署或重启时建议设置PORT— 端口(通常由平台自动设置)
连接到 ChatGPT
- 将此服务部署到公共 URL
- 在 ChatGPT 中,前往 Settings > Advanced > Developer Mode
- 前往 Connectors 选项卡
- 点击 Add Connector
- 输入服务 URL(例如,
https://mcp.codeqr.io/mcp) - ChatGPT 会自动发现 OAuth 端点并提示你进行授权
连接到 OpenAI Agents SDK
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-4o",
tools=[{
"type": "mcp",
"server_label": "codeqr",
"server_url": "https://mcp.codeqr.io/mcp",
"require_approval": "never",
}],
input="Create a short link for https://codeqr.io",
)
可用工具
| 工具 | 描述 |
|---|---|
create_link | 创建短链接 |
list_links | 列出所有短链接 |
get_link_info | 获取链接详情 |
update_link | 更新链接 |
delete_link | 删除链接 |
create_qrcode | 创建动态二维码,可编码 URL、Wi-Fi 凭据、联系人名片、WhatsApp、电子邮件、SMS、电话号码、文本或加密货币请求 |
list_qrcodes | 列出所有二维码 |
update_qrcode | 更改现有二维码指向的目标,无需重新打印 |
delete_qrcode | 删除二维码;已打印的二维码将无法继续解析 |
get_analytics | 查询点击分析数据 |
list_domains | 列出自定义域名 |
list_tags | 列出标签 |
create_tag | 创建标签 |
get_workspace | 读取已授权工作区的信息:名称、标识和套餐 |
不提供转化事件工具。track_lead 和 track_sale 需要 conversions.write 作用域,该作用域仅由 CodeQR 授予工作区所有者;请求此作用域会导致 CodeQR 拒绝其他所有人的整个授权。每个链接的 trackConversion 开关是 links.write 字段,已通过 create_link/update_link 开放(仅限包含转化跟踪功能的套餐)。
智能规则通过 create_link/update_link 上的 rules 暴露:可根据 API 实现的十二种属性进行条件路由,也可将流量拆分到 2-4 个目标;A/B 测试就是通过一个没有条件、带有 split 的规则来表达。如果工作区未启用智能规则,API 会拒绝整个调用——创建或更新会直接失败,因此不会在缺少所请求规则的情况下创建链接或 QR 码;服务端不会原样转发该拒绝,而是提示此工作区未启用智能规则,并附上详情链接。src/plan-limit-message.ts 会识别它了解的套餐提示语:像这样的功能限制会转换为“此工作区未启用”,配额限制会转换为“已达到 N … 的上限”;无法识别的内容则原样传递。该功能有四项不变量无法用 JSON Schema 表达(权重总和必须为 100、url 与 split 必须二选一、条件必须全部设置或全部不设置、无条件规则必须排在最后),因此会在发送请求前由 src/smart-rules.ts 检查——这样既省去一次往返,也能用一句话作答,而不是返回 SDK 会显示的序列化错误正文。
值得注意的陷阱:value 会与请求中携带的值进行完整且不区分大小写的比较;对于三个属性,实际含义比名称所暗示的更窄。device 指操作系统(iOS、Android、Windows、Mac OS、Linux——绝不是 mobile),language 是两字母代码,referrer 是不带路径的域名。错误的值不会在任何地方触发错误:API 接受任意字符串,规则只会悄然无法匹配。
create_qrcode/update_qrcode 也接受 title 和 walletPass。title 用于设置 QR 码的显示标题,并会以大号字体显示在通过该码保存到 Google/Apple Wallet 的凭证上(取代“QR Code”)。在 walletPass 中,name 和 logo 会覆盖该凭证上显示的工作区名称和徽标;barcodeText 则设置 QR 码下方显示的文字,例如会员姓名或卡号;如果未提供该字段,CodeQR 不会为该行发送文字——标题不会在该处重复显示。自定义品牌标识仅适用于包含该功能的套餐,且试用期间不可用:在其他套餐或试用期间,任何新的非空 walletPass 都会被拒绝并返回 403,而 null(清除设置)始终会被接受。在不包含该功能的套餐中或试用期间,生成凭证时会忽略已保存的值,因此凭证会回退为使用工作区名称和徽标。logo 必须是 https URL:API 会下载并存储自己的副本,因此响应返回的是该副本的 URL,而非所提交的 URL。barcodeText 去除首尾空格后须为 1-40 个字符。在 update_qrcode 中,对象会整体替换已存储的值(对象中省略的字段会被清除,而非合并)——要保留全部三项,请同时发送 name、logo 和 barcodeText;null 会清除覆盖设置并恢复为工作区品牌标识,与 rules: null 结束正在运行的智能规则测试的方式相同。
交互式卡片(MCP Apps)
设置 MCP_UI_ENABLED=1 后,能够呈现 MCP Apps
的宿主(ChatGPT、Claude)会为 create_qrcode、update_qrcode、create_link、update_link 和
get_link_info 返回的二维码或短链接显示一张卡片:其中包含图片、带复制按钮的短链接、是否为动态链接、目标地址和扫描或点击次数,以及一个用于在 CodeQR 控制面板中打开它的按钮和一个用于询问扫描或点击次数的按钮。
- 工具的
_meta.ui.resourceUri指向ui://codeqr/item-card.v1.html,并通过resources/read(src/widgets/)提供。每次读取都会记录为mcp.resource_read。 - 结果包含
structuredContent(字段允许列表;宿主也会将其展示给模型)和_meta["io.codeqr/card"](仅供卡片使用的图片和控制面板 URL)。对于没有 UI 的客户端,content保持不变。 get_analytics会显示一张分析卡片(ui://codeqr/analytics.v1.html):统计的内容及统计周期、总数、趋势线或排名前五的行,以及一个用于在控制面板中打开分析数据的按钮。卡片中的 24h / 7d / 30d 筛选项会通过宿主(tools/call)重新调用,前提是宿主声明支持此功能,且只能使用所有套餐都可读取的时间间隔。- 页面位于
web/item-card/和web/analytics/,与宿主通信的桥接代码位于web/shared/。yarn widgets:build会将它们打包到src/widgets/generated/,并提交到版本库;如果生成文件过期,yarn verify会失败。要在浏览器中查看,请运行node scripts/build-widgets.mjs --html,托管web/dev/,然后打开harness.html?fixture=qr&theme=dark&locale=pt-BR&width=375或harness.html?widget=analytics&fixture=countries&interval=30d。
未设置该变量时,工具列表、资源列表和所有结果均与之前相同。
API 端点
| 方法 | 路径 | 认证 | 描述 |
|---|---|---|---|
| GET | /health | 否 | 健康检查 |
| GET | /.well-known/oauth-protected-resource | 否 | OAuth 资源元数据(RFC 9728) |
| GET | /.well-known/oauth-authorization-server | 否 | OAuth 服务元数据(RFC 8414) |
| POST | /oauth/register | 否 | 动态客户端注册(RFC 7591) |
| GET | /oauth/authorize | 否 | 同意页面:使用哪个应用,以及访问权限将发送到何处 |
| POST | /oauth/authorize | 否 | 同意决定;批准后重定向到 CodeQR |
| GET | /oauth/callback | 否 | 从 CodeQR 返回 |
| POST | /oauth/token | 否 | 令牌交换 |
| POST | /mcp | Bearer | MCP Streamable HTTP 端点 |
架构
src/
├── index.ts # Express app & server startup
├── config.ts # Environment configuration
├── oauth/
│ ├── store.ts # OAuth state: Upstash Redis or in-memory fallback
│ └── pkce.ts # PKCE S256 verification
├── middleware/
│ └── auth.ts # Bearer token validation middleware
└── routes/
├── well-known.ts # OAuth discovery metadata endpoints
├── oauth.ts # Authorization & token endpoints
└── mcp.ts # MCP tool definitions & handlers
生产环境注意事项
- OAuth 持久化: 为无服务器和多实例部署配置 Upstash Redis(参见
.env.example)。未配置时,将使用内存存储(仅限单进程)。 - 为 OAuth 和 MCP 端点添加速率限制
- 启用 HTTPS(通常由反向代理 / 平台处理)
- 添加监控(
/health端点已可用于探测) - 考虑为长期会话轮换令牌
发布到 MCP Registry
此服务已在官方注册表中列为 io.codeqr/codeqr。注册表
仅存储 server.json 中的元数据,不存储代码。
发布授权通过 DNS 完成:codeqr.io 的 apex 上有一条 TXT 记录,其中保存着 Ed25519 密钥对的公钥部分。必须使用 apex,而不是选择器——MCP DNS 身份验证遵循 SPF 风格的记录位置规则;在 _mcp-auth. 下的记录会导致通用签名错误,且不会指出原因。
# 1. Bump the version in package.json, src/config.ts and server.json together.
# `yarn test` fails if they drift — the registry refuses to republish a
# version it already has.
#
# Then bump it in the CodeQR app too: the Server Card at
# app/.well-known/mcp/server-card.json/route.ts advertises this server's
# version, and no test can reach across repos to check. It already drifted
# once, to a release that never existed.
# 2. Authenticate with the private key (kept outside this repo).
PRIVATE_KEY="$(openssl pkey -in /path/to/codeqr-io.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n')"
mcp-publisher login dns --domain codeqr.io --private-key "$PRIVATE_KEY"
# 3. Publish, then confirm the entry is live.
mcp-publisher publish
curl "https://registry.modelcontextprotocol.io/v0/servers?search=codeqr"
如果轮换密钥,请删除旧的 TXT 记录——系统会先尝试使用过期记录,导致验证失败。
目录列表
聚合平台会爬取整个生态并列出服务,无论是否有人认领,因此未认领的条目仍然存在——只是机器人对该服务功能的猜测。认领后,猜测会被替换,你也可以编辑读者看到的名称和描述。这些操作都不通过合并文件完成;每项都需要在聚合平台自己的站点上一次性操作。
| 目录 | 认领所有权的方式 | 状态 |
|---|---|---|
| 官方 MCP Registry | 使用 mcp-publisher + DNS,如上所述 | 已列出 |
| Glama | 在此仓库中添加 glama.json,然后使用 maintainers 中列出的账号运行一次认领流程 | 文件已在仓库中;待认领 |
| Smithery | smithery mcp publish https://mcp.codeqr.io/mcp -n <org>/<name> | 待处理 |
| PulseMCP | 在其站点提交申请并由人工审核 | 待处理 |
| mcp.so | 提交表单 / 创建 GitHub issue | 待处理 |
Glama 还提供 GitHub OAuth 认领方式,但该方式只能关联个人账号下的仓库,而此仓库并非如此——它属于 codeqr-io 组织。因此需要使用文件。
许可证
MIT — CodeQR
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。