staff-mcp 1.0.10 → 1.0.15
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 +14 -1
- package/README_zh.md +14 -1
- package/dist/src/index.js +29 -8
- package/dist/src/index.js.map +1 -1
- package/dist/src/transports/http.d.ts +8 -0
- package/dist/src/transports/http.js +48 -14
- package/dist/src/transports/http.js.map +1 -1
- package/dist/src/transports/reverse.d.ts +13 -0
- package/dist/src/transports/reverse.js +43 -0
- package/dist/src/transports/reverse.js.map +1 -0
- package/package.json +6 -2
- package/dist/bundle.js +0 -558
package/README.md
CHANGED
|
@@ -46,6 +46,16 @@ Add the following to your `claude_desktop_config.json`:
|
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### 4. Reverse MCP Mode (Intranet Penetration)
|
|
50
|
+
Connect your local machine to a centralized remote gateway (like `chat-ai`) from behind NAT/Firewalls. No local open ports required! It automatically handles disconnects and infinite retries.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx -y staff-mcp@latest -t reverse \
|
|
54
|
+
--ru https://chat.your-domain.com/api/mcp-reverse \
|
|
55
|
+
--rt your_secure_token_here \
|
|
56
|
+
--rn my-macbook-pro
|
|
57
|
+
```
|
|
58
|
+
|
|
49
59
|
---
|
|
50
60
|
|
|
51
61
|
## 🛠️ Core Capabilities
|
|
@@ -91,9 +101,12 @@ It will securely download, configure, and reload the skill without you lifting a
|
|
|
91
101
|
| `-r, --profile` | The active profile for skills (e.g., android-reverse) | `default` |
|
|
92
102
|
| `--docker` | Run inside a Docker container using this image | `undefined` |
|
|
93
103
|
| `-D, --docker-args` | Extra args for `docker run` (e.g., `-e FOO=BAR`) | `[]` |
|
|
94
|
-
| `-t, --transport` | Transport type (`stdio` or `
|
|
104
|
+
| `-t, --transport` | Transport type (`stdio`, `http`, or `reverse`) | `stdio` |
|
|
95
105
|
| `-p, --port` | Port for HTTP server | `3000` |
|
|
96
106
|
| `-h, --host` | Host for HTTP server | `127.0.0.1` |
|
|
107
|
+
| `--ru, --reverse-url` | URL for Reverse MCP Gateway | `undefined` |
|
|
108
|
+
| `--rt, --reverse-token` | Security token for Reverse MCP | `undefined` |
|
|
109
|
+
| `--rn, --reverse-name` | Server name for Reverse MCP | `undefined` |
|
|
97
110
|
|
|
98
111
|
### Hardware Pass-through Example (Android Reverse Engineering)
|
|
99
112
|
If you need the AI to interact with an Android device connected via USB while running inside a container, utilizing network-based ADB pass-through is the most reliable cross-platform solution:
|
package/README_zh.md
CHANGED
|
@@ -46,6 +46,16 @@ npx -y staff-mcp@latest --docker chineseastar/security:latest --profile android-
|
|
|
46
46
|
}
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
### 4. Reverse MCP 模式 (内网穿透)
|
|
50
|
+
身处 NAT 或防火墙深处?无需公网 IP 和端口映射,主动连回中心化的远端网关 (如 `chat-ai`)!自带断线重连与无限重试机制。
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx -y staff-mcp@latest -t reverse \
|
|
54
|
+
--ru https://chat.your-domain.com/api/mcp-reverse \
|
|
55
|
+
--rt your_secure_token_here \
|
|
56
|
+
--rn my-macbook-pro
|
|
57
|
+
```
|
|
58
|
+
|
|
49
59
|
---
|
|
50
60
|
|
|
51
61
|
## 🛠️ 核心能力
|
|
@@ -91,9 +101,12 @@ npx -y staff-mcp@latest --profile android-reverse
|
|
|
91
101
|
| `-r, --profile` | 当前激活的技能档案/工种 (如 android-reverse) | `default` |
|
|
92
102
|
| `--docker` | 在指定的 Docker 镜像内运行 AI | `undefined` |
|
|
93
103
|
| `-D, --docker-args` | 传递给 `docker run` 的自定义底层参数 | `[]` |
|
|
94
|
-
| `-t, --transport` | 传输协议 (`stdio` 或 `
|
|
104
|
+
| `-t, --transport` | 传输协议 (`stdio`, `http`, 或 `reverse`) | `stdio` |
|
|
95
105
|
| `-p, --port` | HTTP 服务的监听端口 | `3000` |
|
|
96
106
|
| `-h, --host` | HTTP 服务的监听地址 | `127.0.0.1` |
|
|
107
|
+
| `--ru, --reverse-url` | Reverse MCP 网关的远端 URL | `undefined` |
|
|
108
|
+
| `--rt, --reverse-token` | Reverse MCP 的安全认证令牌 | `undefined` |
|
|
109
|
+
| `--rn, --reverse-name` | Reverse MCP 的服务注册名称 | `undefined` |
|
|
97
110
|
|
|
98
111
|
### 硬件透传案例 (Android 移动端逆向)
|
|
99
112
|
如果你希望 AI 在容器内运行时,仍能连接并控制物理机上的 Android 手机,利用基于网络端口的 ADB 透传是最稳妥的跨平台方案:
|
package/dist/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@ import { fileURLToPath } from "url";
|
|
|
8
8
|
import { createServer } from "./server.js";
|
|
9
9
|
import { startStdioServer } from "./transports/stdio.js";
|
|
10
10
|
import { startHttpServer } from "./transports/http.js";
|
|
11
|
+
import { startReverseServer } from "./transports/reverse.js";
|
|
11
12
|
import { ensureStaffDirs } from "./utils/paths.js";
|
|
12
13
|
// Global error handlers to prevent the MCP server from crashing due to unhandled child process errors
|
|
13
14
|
process.on("uncaughtException", (err) => {
|
|
@@ -28,9 +29,12 @@ program
|
|
|
28
29
|
.name("staff-mcp")
|
|
29
30
|
.description("MCP Server with file, shell, and LSP capabilities.")
|
|
30
31
|
.version("1.0.0")
|
|
31
|
-
.option("-t, --transport <type>", "Transport type (stdio
|
|
32
|
+
.option("-t, --transport <type>", "Transport type (stdio, http, reverse)", "stdio")
|
|
32
33
|
.option("-p, --port <number>", "Port for HTTP server", "3000")
|
|
33
34
|
.option("-h, --host <address>", "Host for HTTP server", "127.0.0.1")
|
|
35
|
+
.option("--ru, --reverse-url <url>", "URL for Reverse MCP Gateway (e.g. http://localhost:3000/api/mcp-reverse)")
|
|
36
|
+
.option("--rt, --reverse-token <token>", "Security token for Reverse MCP")
|
|
37
|
+
.option("--rn, --reverse-name <name>", "Server name for Reverse MCP")
|
|
34
38
|
.option("-w, --working-dir <path>", "Working directory for the server (defaults to current execution path)", process.cwd())
|
|
35
39
|
.option("-d, --allowed-dir <paths...>", "Additional directories allowed for sandbox", [])
|
|
36
40
|
.option("-r, --profile <name>", "The active profile for skills and instructions (e.g., android-reverse, default)", "default")
|
|
@@ -97,13 +101,23 @@ program
|
|
|
97
101
|
// 9. Reconstruct the command inside the container
|
|
98
102
|
dockerArgs.push("node", "/opt/staff-mcp/dist/src/index.js");
|
|
99
103
|
dockerArgs.push("-t", options.transport);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
if (options.transport === "reverse") {
|
|
105
|
+
if (options.reverseUrl)
|
|
106
|
+
dockerArgs.push("--ru", options.reverseUrl);
|
|
107
|
+
if (options.reverseToken)
|
|
108
|
+
dockerArgs.push("--rt", options.reverseToken);
|
|
109
|
+
if (options.reverseName)
|
|
110
|
+
dockerArgs.push("--rn", options.reverseName);
|
|
104
111
|
}
|
|
105
112
|
else {
|
|
106
|
-
dockerArgs.push("-
|
|
113
|
+
dockerArgs.push("-p", String(options.port));
|
|
114
|
+
// Inside container, we must listen on all interfaces for HTTP to be exposed
|
|
115
|
+
if (options.transport === "http") {
|
|
116
|
+
dockerArgs.push("-h", "0.0.0.0");
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
dockerArgs.push("-h", options.host);
|
|
120
|
+
}
|
|
107
121
|
}
|
|
108
122
|
dockerArgs.push("-w", "/workspace");
|
|
109
123
|
if (options.allowedDir && options.allowedDir.length > 0) {
|
|
@@ -127,8 +141,8 @@ program
|
|
|
127
141
|
// -------------------------------------------------------------
|
|
128
142
|
// Auto-exit if we are running as a proxy child and the host pipe breaks
|
|
129
143
|
if (process.env.STAFF_MCP_IS_DOCKER === "1") {
|
|
130
|
-
if (options.transport
|
|
131
|
-
process.stdin.resume(); // keep reading to detect end in
|
|
144
|
+
if (options.transport !== "stdio") {
|
|
145
|
+
process.stdin.resume(); // keep reading to detect end in non-stdio modes
|
|
132
146
|
}
|
|
133
147
|
process.stdin.on("end", () => {
|
|
134
148
|
console.error("[staff-mcp] Host pipe closed, terminating container...");
|
|
@@ -146,6 +160,13 @@ program
|
|
|
146
160
|
if (options.transport === "http") {
|
|
147
161
|
await startHttpServer(server, parseInt(options.port, 10), options.host);
|
|
148
162
|
}
|
|
163
|
+
else if (options.transport === "reverse") {
|
|
164
|
+
if (!options.reverseUrl || !options.reverseToken || !options.reverseName) {
|
|
165
|
+
console.error("[staff-mcp] Error: --ru (reverse-url), --rt (reverse-token), and --rn (reverse-name) are required for reverse transport.");
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}
|
|
168
|
+
await startReverseServer(server, options.reverseUrl, options.reverseToken, options.reverseName);
|
|
169
|
+
}
|
|
149
170
|
else {
|
|
150
171
|
await startStdioServer(server);
|
|
151
172
|
}
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,sGAAsG;AACtG,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAQ,EAAE,EAAE;IAC3C,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5E,OAAO,CAAC,KAAK,CAAC,+CAA+C,GAAG,CAAC,OAAO,sCAAsC,CAAC,CAAC;IAClH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,iCAAiC,EAAE,GAAG,CAAC,CAAC;IACxD,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;IACnD,OAAO,CAAC,KAAK,CAAC,qCAAqC,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AACnF,CAAC,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,oDAAoD,CAAC;KACjE,OAAO,CAAC,OAAO,CAAC;KAChB,MAAM,CAAC,wBAAwB,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
2
|
/**
|
|
3
3
|
* Starts an Express server that hosts the MCP server over Streamable HTTP.
|
|
4
|
+
*
|
|
5
|
+
* Transport lifecycle:
|
|
6
|
+
* - Each client session gets its own StreamableHTTPServerTransport instance.
|
|
7
|
+
* - When a session ends (DELETE, client disconnect, etc.), the transport fires
|
|
8
|
+
* its onclose callback, which schedules a reset via setTimeout(0).
|
|
9
|
+
* - The setTimeout deferral is critical: it lets Protocol._onclose() finish
|
|
10
|
+
* (setting _transport = undefined) before we call server.connect() again.
|
|
11
|
+
* - During the reset window, incoming requests receive 503 to trigger client retry.
|
|
4
12
|
*/
|
|
5
13
|
export declare function startHttpServer(server: McpServer, port: number, host?: string): Promise<void>;
|
|
@@ -4,33 +4,67 @@ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/
|
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
/**
|
|
6
6
|
* Starts an Express server that hosts the MCP server over Streamable HTTP.
|
|
7
|
+
*
|
|
8
|
+
* Transport lifecycle:
|
|
9
|
+
* - Each client session gets its own StreamableHTTPServerTransport instance.
|
|
10
|
+
* - When a session ends (DELETE, client disconnect, etc.), the transport fires
|
|
11
|
+
* its onclose callback, which schedules a reset via setTimeout(0).
|
|
12
|
+
* - The setTimeout deferral is critical: it lets Protocol._onclose() finish
|
|
13
|
+
* (setting _transport = undefined) before we call server.connect() again.
|
|
14
|
+
* - During the reset window, incoming requests receive 503 to trigger client retry.
|
|
7
15
|
*/
|
|
8
16
|
export async function startHttpServer(server, port, host = "0.0.0.0") {
|
|
9
17
|
const app = express();
|
|
10
18
|
// Enable CORS for all origins, including the MCP Inspector
|
|
11
19
|
app.use(cors());
|
|
12
20
|
// Necessary for processing JSON-RPC messages (POST)
|
|
13
|
-
// We use express.json() but also need to be careful not to consume the stream if transport needs it.
|
|
14
|
-
// However, StreamableHTTPServerTransport.handleRequest accepts parsedBody.
|
|
15
21
|
app.use(express.json());
|
|
16
|
-
//
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
// The currently active transport. Set to null during reset windows.
|
|
23
|
+
let transport = null;
|
|
24
|
+
/**
|
|
25
|
+
* Creates a fresh transport and connects it to the server.
|
|
26
|
+
* Must only be called when server has no active transport
|
|
27
|
+
* (i.e., after Protocol._onclose() has cleared _transport).
|
|
28
|
+
*/
|
|
29
|
+
async function setupTransport() {
|
|
30
|
+
// Mark transport as unavailable during the reset window so incoming
|
|
31
|
+
// requests get a clean 503 instead of hitting a closed transport.
|
|
32
|
+
transport = null;
|
|
33
|
+
const t = new StreamableHTTPServerTransport({
|
|
34
|
+
sessionIdGenerator: () => randomUUID(),
|
|
35
|
+
// Enable JSON responses for POST requests so the client receives
|
|
36
|
+
// tool lists / call results directly in the response body.
|
|
37
|
+
enableJsonResponse: true,
|
|
38
|
+
});
|
|
39
|
+
// Schedule a reset when this session ends.
|
|
40
|
+
// We use setTimeout(0) to defer past Protocol._onclose(), which
|
|
41
|
+
// clears _transport = undefined and makes connect() possible.
|
|
42
|
+
t.onclose = () => {
|
|
43
|
+
setTimeout(() => {
|
|
44
|
+
setupTransport().catch((err) => {
|
|
45
|
+
console.error("[MCP HTTP] Failed to reset transport:", err);
|
|
46
|
+
});
|
|
47
|
+
}, 0);
|
|
48
|
+
};
|
|
49
|
+
await server.connect(t);
|
|
50
|
+
transport = t;
|
|
51
|
+
console.error("[MCP HTTP] Transport ready for new sessions");
|
|
52
|
+
}
|
|
53
|
+
// Initial transport setup.
|
|
54
|
+
await setupTransport();
|
|
26
55
|
/**
|
|
27
56
|
* Unified handler for MCP requests.
|
|
28
57
|
* Handles GET (SSE) and POST (JSON-RPC).
|
|
29
58
|
*/
|
|
30
59
|
const mcpHandler = async (req, res) => {
|
|
60
|
+
const current = transport;
|
|
61
|
+
if (!current) {
|
|
62
|
+
// Transport is being reset — tell the client to retry.
|
|
63
|
+
res.status(503).json({ error: "Server is restarting session, please retry" });
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
31
66
|
try {
|
|
32
|
-
|
|
33
|
-
await transport.handleRequest(req, res, req.body);
|
|
67
|
+
await current.handleRequest(req, res, req.body);
|
|
34
68
|
}
|
|
35
69
|
catch (error) {
|
|
36
70
|
console.error("[MCP HTTP Error]:", error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/transports/http.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/transports/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Start a reverse MCP connection to a public gateway.
|
|
4
|
+
*
|
|
5
|
+
* The ReverseMCPClient handles all transport lifecycle, reconnection,
|
|
6
|
+
* and MCP protocol re-binding automatically.
|
|
7
|
+
*
|
|
8
|
+
* @param server The McpServer instance (with all tools registered)
|
|
9
|
+
* @param url Base URL of the reverse MCP endpoint
|
|
10
|
+
* @param token Authentication token
|
|
11
|
+
* @param name Server name for identification
|
|
12
|
+
*/
|
|
13
|
+
export declare function startReverseServer(server: McpServer, url: string, token: string, name: string): Promise<void>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ReverseMCPClient } from "mcp-reverse/client";
|
|
2
|
+
/**
|
|
3
|
+
* Start a reverse MCP connection to a public gateway.
|
|
4
|
+
*
|
|
5
|
+
* The ReverseMCPClient handles all transport lifecycle, reconnection,
|
|
6
|
+
* and MCP protocol re-binding automatically.
|
|
7
|
+
*
|
|
8
|
+
* @param server The McpServer instance (with all tools registered)
|
|
9
|
+
* @param url Base URL of the reverse MCP endpoint
|
|
10
|
+
* @param token Authentication token
|
|
11
|
+
* @param name Server name for identification
|
|
12
|
+
*/
|
|
13
|
+
export async function startReverseServer(server, url, token, name) {
|
|
14
|
+
const client = await ReverseMCPClient.createSSE(server, {
|
|
15
|
+
url,
|
|
16
|
+
serverName: name,
|
|
17
|
+
authToken: token,
|
|
18
|
+
reconnect: {
|
|
19
|
+
initialDelay: 1000,
|
|
20
|
+
maxDelay: 30000,
|
|
21
|
+
multiplier: 2,
|
|
22
|
+
maxRetries: 0, // 0 = infinite
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
client.on("connected", () => {
|
|
26
|
+
console.log(`[staff-mcp] 🚀 Successfully connected to Reverse Gateway as "${name}"`);
|
|
27
|
+
});
|
|
28
|
+
client.on("disconnected", () => {
|
|
29
|
+
console.log("[staff-mcp] Connection lost, reconnecting...");
|
|
30
|
+
});
|
|
31
|
+
client.on("reconnecting", (attempt) => {
|
|
32
|
+
console.log(`[staff-mcp] Reconnecting, attempt ${attempt}...`);
|
|
33
|
+
});
|
|
34
|
+
client.on("error", (error) => {
|
|
35
|
+
console.error(`[staff-mcp] Transport error:`, error.message);
|
|
36
|
+
});
|
|
37
|
+
client.on("failed", () => {
|
|
38
|
+
console.error("[staff-mcp] Permanent connection failure, exiting");
|
|
39
|
+
process.exit(1);
|
|
40
|
+
});
|
|
41
|
+
await client.start();
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=reverse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reverse.js","sourceRoot":"","sources":["../../../src/transports/reverse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACpC,MAAiB,EACjB,GAAW,EACX,KAAa,EACb,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,SAAS,CAAC,MAAM,EAAE;QACpD,GAAG;QACH,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE;YACP,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,KAAK;YACf,UAAU,EAAE,CAAC;YACb,UAAU,EAAE,CAAC,EAAE,eAAe;SACjC;KACJ,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,gEAAgE,IAAI,GAAG,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE;QAC3B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,CAAC,OAAe,EAAE,EAAE;QAC1C,OAAO,CAAC,GAAG,CAAC,qCAAqC,OAAO,KAAK,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;QAChC,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;IACjE,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACrB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "staff-mcp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/ChineseAStar/staff-mcp.git"
|
|
7
|
+
},
|
|
4
8
|
"type": "module",
|
|
5
9
|
"main": "dist/src/index.js",
|
|
6
10
|
"bin": {
|
|
@@ -26,7 +30,7 @@
|
|
|
26
30
|
"commander": "^12.1.0",
|
|
27
31
|
"cors": "^2.8.5",
|
|
28
32
|
"express": "^4.21.1",
|
|
29
|
-
"
|
|
33
|
+
"mcp-reverse": "^1.0.8",
|
|
30
34
|
"zod": "^3.23.8"
|
|
31
35
|
},
|
|
32
36
|
"devDependencies": {
|