cloudflare-mcp-smart-proxy 1.5.0 → 1.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,16 +44,30 @@ npx -y -p cloudflare-mcp-smart-proxy cloudmcp-connector activate codex \
44
44
  --cloud-url https://your-cloudmcp.example.com
45
45
  ```
46
46
 
47
- 第一次运行会生成设备密钥并发起接入申请,不会取得任何租户配置或凭证。管理员在 CloudMCP 后台的“生态连接中心”选择精确生态与工作区并批准后,将一次性审批密令回传给智能体。智能体随后运行:
47
+ 第一次运行会生成设备密钥并发起接入申请,不会取得任何租户配置或凭证。管理员在 CloudMCP 后台“生态连接中心”的专用审批表单中核对申请者,勾选一个或多个环境空间和原子能力并批准后,将一次性审批密令回传给智能体。智能体随后运行:
48
48
 
49
49
  ```bash
50
- CLOUDMCP_APPROVAL_CODE='<一次性审批密令>' \
50
+ printf '请输入一次性审批密令:'
51
+ read -s CLOUDMCP_APPROVAL_CODE
52
+ printf '\n'
53
+ export CLOUDMCP_APPROVAL_CODE
51
54
  npx -y -p cloudflare-mcp-smart-proxy cloudmcp-connector activate codex \
52
55
  --cloud-url https://your-cloudmcp.example.com
56
+ unset CLOUDMCP_APPROVAL_CODE
53
57
  ```
54
58
 
55
59
  审批密令 10 分钟内有效、只能成功领取一次,并且只能由原申请设备签名领取。连接凭证写入权限为 `0600` 的独立文件,IDE 配置只保存该文件路径。CloudMCP 的机器可发现入口为 `/.well-known/cloudmcp`。
56
60
 
61
+ 如果本机申请已被拒绝或过期,直接再次运行无审批密令的 `activate` 命令会复用原设备身份并自动创建新申请。也可显式要求重新申请:
62
+
63
+ ```bash
64
+ npx -y -p cloudflare-mcp-smart-proxy cloudmcp-connector activate codex \
65
+ --cloud-url https://your-cloudmcp.example.com \
66
+ --reapply
67
+ ```
68
+
69
+ 该操作不会删除或重建设备身份,也不会在新申请创建成功前改写现有凭证。若设备连接仍处于有效状态,后台会拒绝重复申请;管理员应先撤销该连接,再运行上述命令。
70
+
57
71
  ## 目标配置文件
58
72
 
59
73
  ### Codex
package/connector-cli.js CHANGED
@@ -40,6 +40,7 @@ function printUsage() {
40
40
  console.error(' --dry-run Show output without writing');
41
41
  console.error(' --show-secrets Explicitly include credentials in print output');
42
42
  console.error(' --approval-code <code> One-time code shown by the CloudMCP administrator');
43
+ console.error(' --reapply Reuse this device identity and create a new approval request');
43
44
  console.error('');
44
45
  console.error('The reload codex command uses the existing Codex config and requires no credentials.');
45
46
  }
@@ -58,7 +59,7 @@ function parseArgs(argv) {
58
59
  }
59
60
 
60
61
  const key = token.slice(2);
61
- if (key === 'dry-run' || key === 'show-secrets') {
62
+ if (key === 'dry-run' || key === 'show-secrets' || key === 'reapply') {
62
63
  options[key === 'dry-run' ? 'dryRun' : key] = true;
63
64
  continue;
64
65
  }
@@ -144,6 +145,10 @@ async function runActivation(options) {
144
145
  const identity = new DeviceIdentity({ identityPath: paths.deviceIdentityPath });
145
146
  const device = await identity.loadOrCreate();
146
147
  const approvalCode = options['approval-code'] || process.env.CLOUDMCP_APPROVAL_CODE || '';
148
+ const reapply = options.reapply === true;
149
+ if (approvalCode && reapply) {
150
+ throw new Error('--reapply cannot be combined with --approval-code');
151
+ }
147
152
  let pending = null;
148
153
  try {
149
154
  pending = JSON.parse(fs.readFileSync(paths.pendingPath, 'utf8'));
@@ -192,14 +197,7 @@ async function runActivation(options) {
192
197
  console.error(`credential: ${paths.credentialPath}`);
193
198
  };
194
199
 
195
- if (fs.existsSync(paths.credentialPath)) {
196
- const connection = JSON.parse(fs.readFileSync(paths.credentialPath, 'utf8'));
197
- await installClaimedConnection(connection);
198
- return;
199
- }
200
-
201
- if (!pending) {
202
- if (approvalCode) throw new Error('No local activation request matches this CloudMCP URL and workspace');
200
+ const createApprovalRequest = async ({ replacesRequestId = '' } = {}) => {
203
201
  const requested = await activationFetch(`${paths.cloudUrl}/connectors/activation-requests`, {
204
202
  method: 'POST',
205
203
  headers: { 'Content-Type': 'application/json' },
@@ -221,9 +219,21 @@ async function runActivation(options) {
221
219
  createdAt: Date.now()
222
220
  };
223
221
  writeFileAtomically(paths.pendingPath, `${JSON.stringify(pending, null, 2)}\n`);
222
+ if (replacesRequestId) console.error(`replaced approval request: ${replacesRequestId}`);
224
223
  console.error(`approval request: ${pending.requestId}`);
225
224
  console.error('status: pending administrator approval');
226
225
  console.error('After approval, rerun this command with --approval-code <code>.');
226
+ };
227
+
228
+ if (fs.existsSync(paths.credentialPath) && !reapply) {
229
+ const connection = JSON.parse(fs.readFileSync(paths.credentialPath, 'utf8'));
230
+ await installClaimedConnection(connection);
231
+ return;
232
+ }
233
+
234
+ if (!pending || reapply) {
235
+ if (approvalCode) throw new Error('No local activation request matches this CloudMCP URL and workspace');
236
+ await createApprovalRequest({ replacesRequestId: reapply ? pending?.requestId : '' });
227
237
  return;
228
238
  }
229
239
 
@@ -232,8 +242,14 @@ async function runActivation(options) {
232
242
  `${paths.cloudUrl}/connectors/activation-requests/${encodeURIComponent(pending.requestId)}`,
233
243
  { headers: { Authorization: `Activation ${pending.requestToken}` } }
234
244
  );
245
+ const currentStatus = status.activationRequest.status;
246
+ if (currentStatus === 'rejected' || currentStatus === 'expired') {
247
+ console.error(`approval request ${pending.requestId} is ${currentStatus}; creating a new request with the same device identity.`);
248
+ await createApprovalRequest({ replacesRequestId: pending.requestId });
249
+ return;
250
+ }
235
251
  console.error(`approval request: ${pending.requestId}`);
236
- console.error(`status: ${status.activationRequest.status}`);
252
+ console.error(`status: ${currentStatus}`);
237
253
  console.error('When approved, rerun with --approval-code <code>.');
238
254
  return;
239
255
  }
@@ -364,4 +380,8 @@ async function main() {
364
380
  }
365
381
  }
366
382
 
367
- main();
383
+ if (process.argv[1] && path.resolve(process.argv[1]) === __filename) {
384
+ main();
385
+ }
386
+
387
+ export { parseArgs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cloudflare-mcp-smart-proxy",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Smart proxy for Cloudflare MCP - routes tools to cloud or local execution",
5
5
  "repository": {
6
6
  "type": "git",