@taptap/instant-games-open-mcp 1.24.13 → 1.24.14
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 +10 -4
- package/dist/proxy.js +66 -28
- package/dist/server.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -265,9 +265,10 @@ Maker MCP 初始化时会通过标准 `initialize.instructions` 向 AI 客户端
|
|
|
265
265
|
检查实现”不应自动触发 Maker 远端构建,除非用户明确要求构建、运行或预览 Maker 游戏。
|
|
266
266
|
普通构建会先 push 到 Maker 远端再触发远端 build:本地有改动时提交改动,已有未推送 commit 时
|
|
267
267
|
直接 push,本地干净且没有未推送 commit 时创建 `chore: wake maker build server` 空提交来唤醒远端
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
Maker
|
|
268
|
+
服务。提交前如果本地仅落后于 Maker 远端,会自动执行 fast-forward 后继续提交;如果远端更新会
|
|
269
|
+
覆盖本地未提交修改,则会在创建 commit 前停止并保留本地文件。分叉、非 `main`、鉴权或网络失败仍
|
|
270
|
+
按原有提示处理。push 成功但 build 失败时,会明确说明代码已到 Maker 远端但构建失败。只有用户明确
|
|
271
|
+
说“不提交,只构建云端版本”时,才传
|
|
271
272
|
`confirm_remote_build_without_submit=true`;该模式只构建 Maker 远端已提交版本,不会自动打开
|
|
272
273
|
Maker 页面。
|
|
273
274
|
|
|
@@ -579,6 +580,10 @@ maker_build_current_directory
|
|
|
579
580
|
远端 proxy tools 使用版本化的本地完整定义在首次 `tools/list` 时立即注册,不等待 cwd、Maker 项目绑定、
|
|
580
581
|
PAT/TapTap token 或远端 proxy 连接。项目定位和鉴权只在实际调用 tool 时校验;远端 schema 不会在运行时
|
|
581
582
|
替换本地定义。schema 变更通过本地 MCP 版本更新发布,远端不可用不会让 proxy tools 从当前会话消失。
|
|
583
|
+
唯一例外是 Maker Server 明确返回 `BLACKLISTED` 的账号:MCP 每个进程启动时只检查一次账号状态,
|
|
584
|
+
`tools/list` 只保留 `maker_status_lite`,任何 tool call 和 `maker://status` 都直接返回限制提示,不进入
|
|
585
|
+
本地构建或远端 proxy。PAT 缺失、过期、网络超时和其它非黑名单错误不会隐藏工具;账号状态变化需要
|
|
586
|
+
重连或重启 MCP 后生效。
|
|
582
587
|
Maker 内嵌代理不打开可选的 standalone SSE GET,远端 RPC 响应和构建进度统一通过 POST SSE 返回;
|
|
583
588
|
这避免 Node.js 26 中长连接占用后续 `tools/list` 请求而触发固定 60 秒超时。普通 MCP Proxy 默认仍保留
|
|
584
589
|
standalone SSE,只有显式设置 `disable_standalone_sse` 才会关闭。
|
|
@@ -751,7 +756,8 @@ graph LR
|
|
|
751
756
|
|
|
752
757
|
- **[docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)** - 架构文档
|
|
753
758
|
- **[docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)** - 部署指南(本地、Docker、开发者测试)
|
|
754
|
-
- **[docs/PROXY.md](docs/PROXY.md)** - MCP Proxy 开发指南(面向 TapCode
|
|
759
|
+
- **[docs/PROXY.md](docs/PROXY.md)** - MCP Proxy 开发指南(面向 TapCode 等平台)。
|
|
760
|
+
通用 Proxy 默认不添加 `local` 来源标记;本地 Maker 嵌入入口显式启用,服务端无需修改配置。
|
|
755
761
|
- **[docs/PATH_RESOLUTION.md](docs/PATH_RESOLUTION.md)** - 路径解析系统
|
|
756
762
|
|
|
757
763
|
## Maker 持久化 Proxy 与多项目
|
package/dist/proxy.js
CHANGED
|
@@ -29151,7 +29151,7 @@ var LogWriter = class {
|
|
|
29151
29151
|
};
|
|
29152
29152
|
|
|
29153
29153
|
// src/mcp-proxy/config.ts
|
|
29154
|
-
var DEFAULT_TOOL_CALL_TIMEOUT_MS =
|
|
29154
|
+
var DEFAULT_TOOL_CALL_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
29155
29155
|
function readStdin() {
|
|
29156
29156
|
return new Promise((resolve, reject) => {
|
|
29157
29157
|
const chunks = [];
|
|
@@ -29306,8 +29306,7 @@ function applyDefaults(config2) {
|
|
|
29306
29306
|
}
|
|
29307
29307
|
|
|
29308
29308
|
// src/mcp-proxy/proxy.ts
|
|
29309
|
-
var VERSION = true ? "1.24.
|
|
29310
|
-
var LOCAL_PROXY_TAG = "local";
|
|
29309
|
+
var VERSION = true ? "1.24.14" : "dev";
|
|
29311
29310
|
var DEFAULT_RECONNECT_INTERVAL_MS = 5e3;
|
|
29312
29311
|
var MAX_RECONNECT_INTERVAL_MS = 60 * 1e3;
|
|
29313
29312
|
function createNonReplayableToolResult(name, executionState) {
|
|
@@ -29369,20 +29368,23 @@ function isHttpClientError(error2) {
|
|
|
29369
29368
|
return numericCode !== void 0 && numericCode >= 400 && numericCode < 500 || /\bHTTP\s+4\d\d\b/i.test(error2.message);
|
|
29370
29369
|
}
|
|
29371
29370
|
var TapTapMCPProxy = class {
|
|
29372
|
-
constructor(config2) {
|
|
29371
|
+
constructor(config2, runtimeOptions = {}) {
|
|
29373
29372
|
this.connected = false;
|
|
29374
29373
|
this.reconnecting = false;
|
|
29375
29374
|
this.reconnectTimer = null;
|
|
29376
29375
|
this.healthCheckTimer = null;
|
|
29377
29376
|
this.pendingRequests = [];
|
|
29378
|
-
this.reconnectDelayMs = DEFAULT_RECONNECT_INTERVAL_MS;
|
|
29379
29377
|
// 会话验证相关
|
|
29380
29378
|
this.sessionValidated = false;
|
|
29381
29379
|
this.lastValidationTime = 0;
|
|
29382
29380
|
this.SESSION_VALIDATION_INTERVAL = 3e4;
|
|
29383
|
-
var _a3;
|
|
29381
|
+
var _a3, _b;
|
|
29384
29382
|
this.config = config2;
|
|
29385
|
-
this.
|
|
29383
|
+
this.sourceTag = runtimeOptions.sourceTag;
|
|
29384
|
+
this.remoteErrorMode = runtimeOptions.remoteErrorMode ?? "passthrough";
|
|
29385
|
+
this.recoveryMode = runtimeOptions.recoveryMode ?? "compatible";
|
|
29386
|
+
this.reconnectDelayMs = ((_a3 = config2.options) == null ? void 0 : _a3.reconnect_interval) ?? DEFAULT_RECONNECT_INTERVAL_MS;
|
|
29387
|
+
this.cookieJar = new CookieJar(((_b = config2.options) == null ? void 0 : _b.verbose) ?? false);
|
|
29386
29388
|
this.logWriter = this.createLogWriter();
|
|
29387
29389
|
this.client = this.createClient();
|
|
29388
29390
|
this.server = new Server(
|
|
@@ -29480,11 +29482,13 @@ var TapTapMCPProxy = class {
|
|
|
29480
29482
|
* - X-TapTap-Project-Path: 项目路径
|
|
29481
29483
|
* - X-TapTap-Mac-Token: MAC 认证令牌(JSON)
|
|
29482
29484
|
* - X-TapTap-Custom-Fields: 业务自定义字段(JSON)
|
|
29483
|
-
* - X-TapTap-Tag:
|
|
29485
|
+
* - X-TapTap-Tag: 调用来源标记,仅在嵌入入口显式启用时发送
|
|
29484
29486
|
*/
|
|
29485
29487
|
buildSessionHeaders() {
|
|
29486
29488
|
const headers = {};
|
|
29487
|
-
|
|
29489
|
+
if (this.sourceTag !== void 0) {
|
|
29490
|
+
headers["X-TapTap-Tag"] = this.sourceTag;
|
|
29491
|
+
}
|
|
29488
29492
|
if (this.config.tenant.user_id) {
|
|
29489
29493
|
headers["X-TapTap-User-Id"] = this.config.tenant.user_id;
|
|
29490
29494
|
}
|
|
@@ -29512,12 +29516,14 @@ var TapTapMCPProxy = class {
|
|
|
29512
29516
|
* - _project_id: 项目标识(可选)
|
|
29513
29517
|
* - _project_path: 项目路径(可选)
|
|
29514
29518
|
* - _custom_fields: 业务自定义字段(可选)
|
|
29515
|
-
* - _tag:
|
|
29519
|
+
* - _tag: 调用来源标记,仅在嵌入入口显式启用时注入
|
|
29516
29520
|
*/
|
|
29517
29521
|
injectPrivateParams(args) {
|
|
29518
29522
|
const injected = { ...args || {} };
|
|
29519
29523
|
injected._mac_token = this.config.auth;
|
|
29520
|
-
|
|
29524
|
+
if (this.sourceTag !== void 0) {
|
|
29525
|
+
injected._tag = this.sourceTag;
|
|
29526
|
+
}
|
|
29521
29527
|
if (this.config.tenant.user_id) {
|
|
29522
29528
|
injected._user_id = this.config.tenant.user_id;
|
|
29523
29529
|
}
|
|
@@ -29568,6 +29574,18 @@ var TapTapMCPProxy = class {
|
|
|
29568
29574
|
const replayableTools = (_a3 = this.config.options) == null ? void 0 : _a3.replayable_tools;
|
|
29569
29575
|
return replayableTools === void 0 || replayableTools.includes(name);
|
|
29570
29576
|
}
|
|
29577
|
+
toolErrorResult(error2) {
|
|
29578
|
+
return this.remoteErrorMode === "tool-result" ? convertMcpApplicationErrorToToolResult(error2) : void 0;
|
|
29579
|
+
}
|
|
29580
|
+
shouldReplayToolFailure(name, error2) {
|
|
29581
|
+
if (!this.isToolReplayable(name) || !(error2 instanceof Error)) return false;
|
|
29582
|
+
if (this.recoveryMode === "resilient") return true;
|
|
29583
|
+
if (this.isSessionInvalidError(error2) || error2.message.toLowerCase().includes("not connected")) {
|
|
29584
|
+
return true;
|
|
29585
|
+
}
|
|
29586
|
+
const code = error2.code;
|
|
29587
|
+
return !isTransientHttpServerError(error2) && code !== ErrorCode.ConnectionClosed && code !== ErrorCode.RequestTimeout;
|
|
29588
|
+
}
|
|
29571
29589
|
/**
|
|
29572
29590
|
* 连接到 TapTap MCP Server
|
|
29573
29591
|
*/
|
|
@@ -29604,8 +29622,13 @@ var TapTapMCPProxy = class {
|
|
|
29604
29622
|
this.log("info", "✅ Connected and session validated");
|
|
29605
29623
|
this.startHealthCheck();
|
|
29606
29624
|
if (this.reconnecting) {
|
|
29625
|
+
if (this.recoveryMode === "compatible") {
|
|
29626
|
+
await this.notifyReconnected();
|
|
29627
|
+
}
|
|
29607
29628
|
await this.processPendingRequests();
|
|
29608
|
-
|
|
29629
|
+
if (this.recoveryMode === "resilient") {
|
|
29630
|
+
await this.notifyReconnected();
|
|
29631
|
+
}
|
|
29609
29632
|
this.reconnecting = false;
|
|
29610
29633
|
}
|
|
29611
29634
|
} catch (error2) {
|
|
@@ -29760,15 +29783,17 @@ var TapTapMCPProxy = class {
|
|
|
29760
29783
|
var _a3, _b, _c;
|
|
29761
29784
|
this.clearReconnectTimer();
|
|
29762
29785
|
const configuredInterval = ((_a3 = this.config.options) == null ? void 0 : _a3.reconnect_interval) ?? DEFAULT_RECONNECT_INTERVAL_MS;
|
|
29763
|
-
const interval = this.reconnectDelayMs
|
|
29786
|
+
const interval = this.recoveryMode === "resilient" ? this.reconnectDelayMs : configuredInterval;
|
|
29764
29787
|
this.reconnectTimer = setTimeout(() => {
|
|
29765
29788
|
this.reconnectToServer();
|
|
29766
29789
|
}, interval);
|
|
29767
29790
|
(_c = (_b = this.reconnectTimer).unref) == null ? void 0 : _c.call(_b);
|
|
29768
|
-
this.
|
|
29769
|
-
Math.
|
|
29770
|
-
|
|
29771
|
-
|
|
29791
|
+
if (this.recoveryMode === "resilient") {
|
|
29792
|
+
this.reconnectDelayMs = Math.min(
|
|
29793
|
+
Math.max(interval * 2, configuredInterval),
|
|
29794
|
+
Math.max(MAX_RECONNECT_INTERVAL_MS, configuredInterval)
|
|
29795
|
+
);
|
|
29796
|
+
}
|
|
29772
29797
|
}
|
|
29773
29798
|
/**
|
|
29774
29799
|
* 清除重连定时器
|
|
@@ -29809,15 +29834,18 @@ var TapTapMCPProxy = class {
|
|
|
29809
29834
|
* 检测是否是需要重连的错误(网络错误或会话无效)
|
|
29810
29835
|
*/
|
|
29811
29836
|
isNetworkError(error2) {
|
|
29837
|
+
var _a3;
|
|
29812
29838
|
if (!(error2 instanceof Error)) return false;
|
|
29813
29839
|
if (convertMcpApplicationErrorToToolResult(error2)) {
|
|
29814
29840
|
return false;
|
|
29815
29841
|
}
|
|
29816
29842
|
if (isHttpClientError(error2)) {
|
|
29817
|
-
|
|
29818
|
-
|
|
29819
|
-
|
|
29820
|
-
|
|
29843
|
+
if (this.isMcpApplicationError(error2)) {
|
|
29844
|
+
return false;
|
|
29845
|
+
}
|
|
29846
|
+
const code = error2.code;
|
|
29847
|
+
const status = typeof code === "number" && code >= 400 && code < 500 ? code : typeof code === "string" && /^4\d\d$/.test(code) ? Number(code) : Number((_a3 = error2.message.match(/\bHTTP\s+(4\d\d)\b/i)) == null ? void 0 : _a3[1]);
|
|
29848
|
+
return (status === 400 || status === 404) && this.isSessionInvalidError(error2);
|
|
29821
29849
|
}
|
|
29822
29850
|
const errorMsg = error2.message.toLowerCase();
|
|
29823
29851
|
const errorCode = error2.code;
|
|
@@ -29845,11 +29873,14 @@ var TapTapMCPProxy = class {
|
|
|
29845
29873
|
if (errorCode === ErrorCode.ConnectionClosed || errorCode === ErrorCode.RequestTimeout) {
|
|
29846
29874
|
return true;
|
|
29847
29875
|
}
|
|
29876
|
+
if (this.isMcpApplicationError(error2)) {
|
|
29877
|
+
return false;
|
|
29878
|
+
}
|
|
29848
29879
|
if (errorMsg.includes("not connected") || this.isSessionInvalidError(error2)) {
|
|
29849
29880
|
return true;
|
|
29850
29881
|
}
|
|
29851
|
-
if (
|
|
29852
|
-
return
|
|
29882
|
+
if (isTransientHttpServerError(error2)) {
|
|
29883
|
+
return true;
|
|
29853
29884
|
}
|
|
29854
29885
|
const networkErrorKeywords = [
|
|
29855
29886
|
"fetch failed",
|
|
@@ -29876,7 +29907,6 @@ var TapTapMCPProxy = class {
|
|
|
29876
29907
|
async processPendingRequests() {
|
|
29877
29908
|
var _a3, _b, _c;
|
|
29878
29909
|
const timeout = ((_a3 = this.config.options) == null ? void 0 : _a3.request_timeout) ?? 3e4;
|
|
29879
|
-
const now = Date.now();
|
|
29880
29910
|
this.log("info", `Processing ${this.pendingRequests.length} pending requests...`);
|
|
29881
29911
|
while (this.pendingRequests.length > 0) {
|
|
29882
29912
|
const req = this.pendingRequests.shift();
|
|
@@ -29884,7 +29914,7 @@ var TapTapMCPProxy = class {
|
|
|
29884
29914
|
req.resolve(createNonReplayableToolResult(req.name, req.executionState ?? "unknown"));
|
|
29885
29915
|
continue;
|
|
29886
29916
|
}
|
|
29887
|
-
if (now - req.timestamp > timeout) {
|
|
29917
|
+
if (Date.now() - req.timestamp > timeout) {
|
|
29888
29918
|
req.reject(new Error("Request timeout while waiting for reconnection"));
|
|
29889
29919
|
continue;
|
|
29890
29920
|
}
|
|
@@ -29904,7 +29934,7 @@ var TapTapMCPProxy = class {
|
|
|
29904
29934
|
);
|
|
29905
29935
|
req.resolve(result);
|
|
29906
29936
|
} catch (error2) {
|
|
29907
|
-
const toolErrorResult =
|
|
29937
|
+
const toolErrorResult = this.toolErrorResult(error2);
|
|
29908
29938
|
if (toolErrorResult) {
|
|
29909
29939
|
req.resolve(toolErrorResult);
|
|
29910
29940
|
continue;
|
|
@@ -29912,7 +29942,11 @@ var TapTapMCPProxy = class {
|
|
|
29912
29942
|
if (this.isNetworkError(error2)) {
|
|
29913
29943
|
this.connected = false;
|
|
29914
29944
|
this.sessionValidated = false;
|
|
29915
|
-
this.
|
|
29945
|
+
if (this.recoveryMode === "resilient") {
|
|
29946
|
+
this.pendingRequests.unshift(req);
|
|
29947
|
+
} else {
|
|
29948
|
+
req.reject(error2);
|
|
29949
|
+
}
|
|
29916
29950
|
throw error2;
|
|
29917
29951
|
}
|
|
29918
29952
|
req.reject(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
@@ -30051,19 +30085,23 @@ var TapTapMCPProxy = class {
|
|
|
30051
30085
|
);
|
|
30052
30086
|
return result;
|
|
30053
30087
|
} catch (error2) {
|
|
30054
|
-
const toolErrorResult =
|
|
30088
|
+
const toolErrorResult = this.toolErrorResult(error2);
|
|
30055
30089
|
if (toolErrorResult) {
|
|
30056
30090
|
return toolErrorResult;
|
|
30057
30091
|
}
|
|
30058
30092
|
if (this.isNetworkError(error2)) {
|
|
30059
30093
|
this.log("error", "❌ Network error detected, marking connection as lost");
|
|
30060
30094
|
this.connected = false;
|
|
30095
|
+
this.sessionValidated = false;
|
|
30061
30096
|
if (!this.reconnecting) {
|
|
30062
30097
|
this.log("info", "Triggering immediate reconnection...");
|
|
30063
30098
|
this.reconnectToServer();
|
|
30064
30099
|
if (!this.isToolReplayable(name)) {
|
|
30065
30100
|
return createNonReplayableToolResult(name, "unknown");
|
|
30066
30101
|
}
|
|
30102
|
+
if (!this.shouldReplayToolFailure(name, error2)) {
|
|
30103
|
+
throw error2;
|
|
30104
|
+
}
|
|
30067
30105
|
this.log("info", `⏳ Queueing current request: ${name}`);
|
|
30068
30106
|
return new Promise((resolve, reject) => {
|
|
30069
30107
|
this.pendingRequests.push({
|
package/dist/server.js
CHANGED
|
@@ -6101,7 +6101,7 @@ class MultiplayerManager {
|
|
|
6101
6101
|
// 导出
|
|
6102
6102
|
// export default MultiplayerManager;
|
|
6103
6103
|
// module.exports = MultiplayerManager;
|
|
6104
|
-
// window.MultiplayerManager = MultiplayerManager;`}]}}};var Es;Es="1.24.
|
|
6104
|
+
// window.MultiplayerManager = MultiplayerManager;`}]}}};var Es;Es="1.24.14";async function $De(){return Jo(jm,"api_event_relations")}async function PDe(){return Jo(jm,"protocol_template")}async function DD(){return Jo(jm,"complete_example")}async function TDe(){return`# TapTap 多人联机集成指南
|
|
6105
6105
|
|
|
6106
6106
|
---
|
|
6107
6107
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taptap/instant-games-open-mcp",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "TapTap Open API MCP Server - Documentation and Management APIs for TapTap Minigame and H5 Games (Leaderboard, and more features coming)",
|
|
6
6
|
"main": "dist/server.js",
|