@xuanling-rs/xuanling-mcp 0.2.2 → 0.2.3
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/LICENSE +21 -0
- package/README-ZH.md +111 -0
- package/README.md +122 -0
- package/bin/xuanling-mcp.js +9 -0
- package/lib/launcher.js +120 -0
- package/lib/targets.js +130 -0
- package/package.json +21 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 umbrella22 and XuanLing contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README-ZH.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# XuanLing MCP
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 简体中文
|
|
4
|
+
|
|
5
|
+
`@xuanling-rs/xuanling-mcp` 是面向编码 Agent 的跨平台本地 Model Context Protocol 服务器。它通过
|
|
6
|
+
stdio 提供 42 个类型化工具,覆盖文件系统操作、进程执行、项目探测、Artifact、Session 和
|
|
7
|
+
proposal-first SQLite Memory。
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
启动器要求 Node.js 18.17 或更高版本。
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npm install --global @xuanling-rs/xuanling-mcp@0.2.3
|
|
15
|
+
xuanling-mcp --version
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
MCP Client 也可以使用 `npx` 固定版本:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"mcpServers": {
|
|
23
|
+
"xuanling": {
|
|
24
|
+
"command": "npx",
|
|
25
|
+
"args": [
|
|
26
|
+
"-y",
|
|
27
|
+
"@xuanling-rs/xuanling-mcp@0.2.3",
|
|
28
|
+
"--workspace-root",
|
|
29
|
+
"/absolute/path/to/project",
|
|
30
|
+
"--tool-profile",
|
|
31
|
+
"core",
|
|
32
|
+
"--tool-profile",
|
|
33
|
+
"fs",
|
|
34
|
+
"--tool-profile",
|
|
35
|
+
"memory"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
固定版本可以保持活动项目发现的 MCP 合同稳定。频繁启动服务器时,全局安装或项目内安装可以
|
|
43
|
+
省去 package 解析过程。
|
|
44
|
+
|
|
45
|
+
## 支持平台
|
|
46
|
+
|
|
47
|
+
| 操作系统 | 架构 | 运行时要求 |
|
|
48
|
+
| --- | --- | --- |
|
|
49
|
+
| macOS | Apple Silicon (`arm64`) | 原生二进制 |
|
|
50
|
+
| Linux | `x64` | glibc 2.35 或更高版本 |
|
|
51
|
+
| Windows | `x64` | MSVC runtime |
|
|
52
|
+
|
|
53
|
+
不支持的 OS、CPU 或 libc 组合会返回明确错误。安装过程不编译 Rust、不运行 `postinstall`,
|
|
54
|
+
也不下载可执行文件。启动器会在启动前校验 package metadata 和所选原生 binary 的 SHA-256。
|
|
55
|
+
|
|
56
|
+
## 工具 Profile
|
|
57
|
+
|
|
58
|
+
默认 catalog 暴露全部 42 个工具。重复使用 `--tool-profile` 可以组合多个较小的工具组:
|
|
59
|
+
|
|
60
|
+
| Profile | 工具数 | 能力族 |
|
|
61
|
+
| --- | ---: | --- |
|
|
62
|
+
| `core` | 3 | 系统信息与可移植路径检查 |
|
|
63
|
+
| `fs` | 16 | 文件读取、搜索、预览与修改 |
|
|
64
|
+
| `process` | 5 | 直接进程执行与项目探测/执行 |
|
|
65
|
+
| `memory` | 9 | Memory v2 提案、评审、召回与反馈 |
|
|
66
|
+
| `advanced` | 9 | Artifact、ChangeSet、Pipeline 与 Session |
|
|
67
|
+
| `all` | 42 | 完整 catalog 和默认选择 |
|
|
68
|
+
|
|
69
|
+
## 文件系统能力
|
|
70
|
+
|
|
71
|
+
- `--workspace-root <PATH>` 可重复,允许读取、写入、删除,并允许在该 root 内设置子进程
|
|
72
|
+
工作目录。
|
|
73
|
+
- `--read-root <PATH>` 可重复,只允许读取、列出、搜索和计算 hash;拒绝写入、删除和设置
|
|
74
|
+
子进程工作目录。
|
|
75
|
+
- 两个 flag 都未提供时,XuanLing 文件系统访问不受限制。仅提供 `--read-root` 时为只读部署。
|
|
76
|
+
|
|
77
|
+
修改类工具支持 SHA-256 preimage 校验。支持窗口输出的工具可以设置显式 byte budget,并返回
|
|
78
|
+
类型化 cursor 或 resume token,不会静默截断结果。
|
|
79
|
+
|
|
80
|
+
路径能力不是子进程的 OS sandbox。工具审批和恶意进程隔离由 MCP Host 与执行环境负责。
|
|
81
|
+
|
|
82
|
+
## Memory v2
|
|
83
|
+
|
|
84
|
+
Create、replace 和 archive 调用只产生 pending proposal。只有显式 `memory_review` 决策才能
|
|
85
|
+
原子推进不可变的 canonical record。严格的 `global`、`project` 和 `workspace` scope 防止
|
|
86
|
+
sibling project 之间发生召回泄漏。
|
|
87
|
+
|
|
88
|
+
召回使用确定性 SQLite FTS5 query plan 和稳定词法重排,不要求或下载 embedding 模型。默认
|
|
89
|
+
数据库路径为 `~/.xuanling/memory.db`;使用 `--memory-db <PATH>` 可以覆盖该路径。
|
|
90
|
+
|
|
91
|
+
## Server 选项
|
|
92
|
+
|
|
93
|
+
```text
|
|
94
|
+
--base-dir <PATH> 相对路径解析上下文
|
|
95
|
+
--workspace-root <PATH> 可重复的读写 capability root
|
|
96
|
+
--read-root <PATH> 可重复的只读 capability root
|
|
97
|
+
--memory-db <PATH> 共享 SQLite Memory 数据库
|
|
98
|
+
--default-namespace <VALUE> 默认 Memory namespace
|
|
99
|
+
--sqlite-busy-timeout-ms <NUMBER> SQLite busy timeout(默认 5000)
|
|
100
|
+
--tool-profile <PROFILE> 可重复工具组;默认 all
|
|
101
|
+
--compat-lenient-object-params 受影响 Host 的可选兼容模式
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## 源码与文档
|
|
105
|
+
|
|
106
|
+
- 源码:<https://github.com/umbrella22/xuanling>
|
|
107
|
+
- 集成指南:<https://github.com/umbrella22/xuanling/blob/main/docs/guides/xuanling-mcp-integration.md>
|
|
108
|
+
- DeepSeek Harness 集成:<https://github.com/umbrella22/xuanling/tree/main/integrations/deepseek-harness>
|
|
109
|
+
- Issues:<https://github.com/umbrella22/xuanling/issues>
|
|
110
|
+
|
|
111
|
+
本项目采用 [MIT License](LICENSE)。
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# XuanLing MCP
|
|
2
|
+
|
|
3
|
+
English | [Simplified Chinese](README-ZH.md)
|
|
4
|
+
|
|
5
|
+
`@xuanling-rs/xuanling-mcp` is a cross-platform local Model Context Protocol server for
|
|
6
|
+
coding agents. It exposes 42 typed tools over stdio for filesystem work,
|
|
7
|
+
process execution, project discovery, artifacts, sessions, and proposal-first
|
|
8
|
+
SQLite memory.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
The launcher requires Node.js 18.17 or newer.
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
npm install --global @xuanling-rs/xuanling-mcp@0.2.3
|
|
16
|
+
xuanling-mcp --version
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
MCP clients can also pin the version with `npx`:
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
{
|
|
23
|
+
"mcpServers": {
|
|
24
|
+
"xuanling": {
|
|
25
|
+
"command": "npx",
|
|
26
|
+
"args": [
|
|
27
|
+
"-y",
|
|
28
|
+
"@xuanling-rs/xuanling-mcp@0.2.3",
|
|
29
|
+
"--workspace-root",
|
|
30
|
+
"/absolute/path/to/project",
|
|
31
|
+
"--tool-profile",
|
|
32
|
+
"core",
|
|
33
|
+
"--tool-profile",
|
|
34
|
+
"fs",
|
|
35
|
+
"--tool-profile",
|
|
36
|
+
"memory"
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Pinning the version keeps the discovered MCP contract stable for an active
|
|
44
|
+
project. A global or project-local installation avoids the package resolution
|
|
45
|
+
step when the host starts the server frequently.
|
|
46
|
+
|
|
47
|
+
## Supported Platforms
|
|
48
|
+
|
|
49
|
+
| Operating system | Architecture | Runtime requirement |
|
|
50
|
+
| --- | --- | --- |
|
|
51
|
+
| macOS | Apple Silicon (`arm64`) | native binary |
|
|
52
|
+
| Linux | `x64` | glibc 2.35 or newer |
|
|
53
|
+
| Windows | `x64` | MSVC runtime |
|
|
54
|
+
|
|
55
|
+
Unsupported OS, CPU, and libc combinations fail with an explicit error. The
|
|
56
|
+
package does not compile Rust, run a `postinstall` script, or download
|
|
57
|
+
executables. The launcher validates package metadata and the selected native
|
|
58
|
+
binary's SHA-256 before startup.
|
|
59
|
+
|
|
60
|
+
## Tool Profiles
|
|
61
|
+
|
|
62
|
+
The default catalog exposes all 42 tools. Repeat `--tool-profile` to combine
|
|
63
|
+
smaller groups:
|
|
64
|
+
|
|
65
|
+
| Profile | Tools | Capability family |
|
|
66
|
+
| --- | ---: | --- |
|
|
67
|
+
| `core` | 3 | system and portable path inspection |
|
|
68
|
+
| `fs` | 16 | filesystem read, search, preview, and mutation |
|
|
69
|
+
| `process` | 5 | direct processes and project detection/execution |
|
|
70
|
+
| `memory` | 9 | Memory v2 proposal, review, recall, and feedback |
|
|
71
|
+
| `advanced` | 9 | artifacts, ChangeSets, pipelines, and sessions |
|
|
72
|
+
| `all` | 42 | complete catalog and default selection |
|
|
73
|
+
|
|
74
|
+
## Filesystem Capabilities
|
|
75
|
+
|
|
76
|
+
- `--workspace-root <PATH>` is repeatable and grants read/write/delete access
|
|
77
|
+
plus child-process working-directory admission inside the root.
|
|
78
|
+
- `--read-root <PATH>` is repeatable and grants read/list/search/hash access
|
|
79
|
+
while rejecting writes, deletion, and child-process working directories.
|
|
80
|
+
- With neither flag, XuanLing filesystem access is unrestricted. With only
|
|
81
|
+
`--read-root`, the deployment is read-only.
|
|
82
|
+
|
|
83
|
+
Mutating tools support SHA-256 preimage checks. Window-capable tools support
|
|
84
|
+
explicit byte budgets and return typed cursors or resume tokens instead of
|
|
85
|
+
silently truncating results.
|
|
86
|
+
|
|
87
|
+
The pathname capability is not an OS sandbox for child programs. Tool
|
|
88
|
+
approval and hostile process isolation belong to the MCP host and execution
|
|
89
|
+
environment.
|
|
90
|
+
|
|
91
|
+
## Memory v2
|
|
92
|
+
|
|
93
|
+
Create, replace, and archive calls produce pending proposals. Only an explicit
|
|
94
|
+
`memory_review` decision can atomically advance an immutable canonical record.
|
|
95
|
+
Strict `global`, `project`, and `workspace` scopes prevent sibling-project
|
|
96
|
+
recall.
|
|
97
|
+
|
|
98
|
+
Recall uses deterministic SQLite FTS5 query planning and stable lexical
|
|
99
|
+
reranking. It does not require or download an embedding model. The default
|
|
100
|
+
database is `~/.xuanling/memory.db`; use `--memory-db <PATH>` to override it.
|
|
101
|
+
|
|
102
|
+
## Server Options
|
|
103
|
+
|
|
104
|
+
```text
|
|
105
|
+
--base-dir <PATH> Relative-path resolution context
|
|
106
|
+
--workspace-root <PATH> Repeatable read/write capability root
|
|
107
|
+
--read-root <PATH> Repeatable read-only capability root
|
|
108
|
+
--memory-db <PATH> Shared SQLite memory database
|
|
109
|
+
--default-namespace <VALUE> Default memory namespace
|
|
110
|
+
--sqlite-busy-timeout-ms <NUMBER> SQLite busy timeout (default: 5000)
|
|
111
|
+
--tool-profile <PROFILE> Repeatable tool group; default: all
|
|
112
|
+
--compat-lenient-object-params Opt-in compatibility for affected hosts
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Source and Documentation
|
|
116
|
+
|
|
117
|
+
- Source: <https://github.com/umbrella22/xuanling>
|
|
118
|
+
- Integration guide: <https://github.com/umbrella22/xuanling/blob/main/docs/guides/xuanling-mcp-integration.md>
|
|
119
|
+
- DeepSeek Harness integration: <https://github.com/umbrella22/xuanling/tree/main/integrations/deepseek-harness>
|
|
120
|
+
- Issues: <https://github.com/umbrella22/xuanling/issues>
|
|
121
|
+
|
|
122
|
+
Licensed under the [MIT License](LICENSE).
|
package/lib/launcher.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { spawn as nodeSpawn } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { existsSync as nodeExistsSync, readFileSync as nodeReadFileSync } from "node:fs";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import { constants as osConstants } from "node:os";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
|
|
8
|
+
import { detectTarget } from "./targets.js";
|
|
9
|
+
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
|
|
12
|
+
export function resolveNativeBinary(
|
|
13
|
+
target,
|
|
14
|
+
{
|
|
15
|
+
existsSync = nodeExistsSync,
|
|
16
|
+
readFileSync = nodeReadFileSync,
|
|
17
|
+
resolvePackageJson = (specifier) => require.resolve(specifier),
|
|
18
|
+
} = {},
|
|
19
|
+
) {
|
|
20
|
+
let packageJsonPath;
|
|
21
|
+
try {
|
|
22
|
+
packageJsonPath = resolvePackageJson(`${target.alias}/package.json`);
|
|
23
|
+
} catch {
|
|
24
|
+
throw new Error(
|
|
25
|
+
`Missing optional dependency ${target.alias}. Reinstall the current xuanling-mcp package before retrying`,
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
30
|
+
const metadata = packageJson.xuanlingBinary;
|
|
31
|
+
if (
|
|
32
|
+
metadata?.target !== target.rustTarget ||
|
|
33
|
+
metadata?.binary !== target.binary ||
|
|
34
|
+
!/^[0-9a-f]{64}$/.test(metadata?.sha256 ?? "")
|
|
35
|
+
) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Installed package ${target.alias} does not match target ${target.rustTarget}`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const binaryPath = path.join(path.dirname(packageJsonPath), metadata.binary);
|
|
42
|
+
if (!existsSync(binaryPath)) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Native binary is missing from ${target.alias}. Reinstall the current xuanling-mcp package before retrying`,
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const actualSha256 = createHash("sha256")
|
|
48
|
+
.update(readFileSync(binaryPath))
|
|
49
|
+
.digest("hex");
|
|
50
|
+
if (actualSha256 !== metadata.sha256) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`Native binary checksum mismatch in ${target.alias}. Reinstall the current xuanling-mcp package before retrying`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
return binaryPath;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function exitCodeForSignal(signal) {
|
|
59
|
+
const number = osConstants.signals?.[signal];
|
|
60
|
+
return typeof number === "number" ? 128 + number : 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export async function launch({
|
|
64
|
+
argv = process.argv.slice(2),
|
|
65
|
+
env = process.env,
|
|
66
|
+
runtime = process,
|
|
67
|
+
spawn = nodeSpawn,
|
|
68
|
+
target = detectTarget(),
|
|
69
|
+
binaryPath = resolveNativeBinary(target),
|
|
70
|
+
} = {}) {
|
|
71
|
+
const child = spawn(binaryPath, argv, {
|
|
72
|
+
env,
|
|
73
|
+
stdio: "inherit",
|
|
74
|
+
windowsHide: true,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const signalHandlers = new Map();
|
|
78
|
+
for (const signal of ["SIGINT", "SIGTERM", "SIGHUP"]) {
|
|
79
|
+
const handler = () => {
|
|
80
|
+
if (!child.killed) {
|
|
81
|
+
try {
|
|
82
|
+
child.kill(signal);
|
|
83
|
+
} catch {
|
|
84
|
+
// A concurrent child exit can make signal forwarding fail.
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
signalHandlers.set(signal, handler);
|
|
89
|
+
runtime.on(signal, handler);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let result;
|
|
93
|
+
try {
|
|
94
|
+
result = await new Promise((resolve, reject) => {
|
|
95
|
+
child.once("error", reject);
|
|
96
|
+
child.once("exit", (code, signal) => {
|
|
97
|
+
resolve(signal ? { signal } : { code: code ?? 1 });
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
for (const [signal, handler] of signalHandlers) {
|
|
102
|
+
runtime.removeListener(signal, handler);
|
|
103
|
+
}
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const [signal, handler] of signalHandlers) {
|
|
108
|
+
runtime.removeListener(signal, handler);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (result.signal) {
|
|
112
|
+
if (runtime.platform === "win32") {
|
|
113
|
+
runtime.exit(exitCodeForSignal(result.signal));
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
runtime.kill(runtime.pid, result.signal);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
runtime.exit(result.code);
|
|
120
|
+
}
|
package/lib/targets.js
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
export const NPM_SCOPE = "@xuanling-rs";
|
|
2
|
+
export const PACKAGE_BASENAME = "xuanling-mcp";
|
|
3
|
+
export const PACKAGE_NAME = `${NPM_SCOPE}/${PACKAGE_BASENAME}`;
|
|
4
|
+
|
|
5
|
+
export const DSH_BUNDLES = Object.freeze([
|
|
6
|
+
Object.freeze({ id: "xuanling-dsh-memory", packageName: `${NPM_SCOPE}/xuanling-dsh-memory` }),
|
|
7
|
+
Object.freeze({ id: "xuanling-dsh-skills", packageName: `${NPM_SCOPE}/xuanling-dsh-skills` }),
|
|
8
|
+
Object.freeze({ id: "xuanling-dsh-tools", packageName: `${NPM_SCOPE}/xuanling-dsh-tools` }),
|
|
9
|
+
Object.freeze({
|
|
10
|
+
id: "xuanling-dsh-tools-replace",
|
|
11
|
+
packageName: `${NPM_SCOPE}/xuanling-dsh-tools-replace`,
|
|
12
|
+
}),
|
|
13
|
+
]);
|
|
14
|
+
|
|
15
|
+
export const TARGETS = Object.freeze({
|
|
16
|
+
"darwin-arm64": Object.freeze({
|
|
17
|
+
id: "darwin-arm64",
|
|
18
|
+
alias: "xuanling-mcp-darwin-arm64",
|
|
19
|
+
packageName: `${NPM_SCOPE}/xuanling-mcp-darwin-arm64`,
|
|
20
|
+
binary: "bin/xuanling-mcp",
|
|
21
|
+
cpu: "arm64",
|
|
22
|
+
os: "darwin",
|
|
23
|
+
rustTarget: "aarch64-apple-darwin",
|
|
24
|
+
distTag: "platform-darwin-arm64",
|
|
25
|
+
}),
|
|
26
|
+
"linux-x64-gnu": Object.freeze({
|
|
27
|
+
id: "linux-x64-gnu",
|
|
28
|
+
alias: "xuanling-mcp-linux-x64-gnu",
|
|
29
|
+
packageName: `${NPM_SCOPE}/xuanling-mcp-linux-x64-gnu`,
|
|
30
|
+
binary: "bin/xuanling-mcp",
|
|
31
|
+
cpu: "x64",
|
|
32
|
+
libc: "glibc",
|
|
33
|
+
os: "linux",
|
|
34
|
+
rustTarget: "x86_64-unknown-linux-gnu",
|
|
35
|
+
distTag: "platform-linux-x64-gnu",
|
|
36
|
+
}),
|
|
37
|
+
"win32-x64-msvc": Object.freeze({
|
|
38
|
+
id: "win32-x64-msvc",
|
|
39
|
+
alias: "xuanling-mcp-win32-x64-msvc",
|
|
40
|
+
packageName: `${NPM_SCOPE}/xuanling-mcp-win32-x64-msvc`,
|
|
41
|
+
binary: "bin/xuanling-mcp.exe",
|
|
42
|
+
cpu: "x64",
|
|
43
|
+
os: "win32",
|
|
44
|
+
rustTarget: "x86_64-pc-windows-msvc",
|
|
45
|
+
distTag: "platform-win32-x64-msvc",
|
|
46
|
+
}),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
export function platformVersion(releaseVersion, targetId) {
|
|
50
|
+
if (!/^\d+\.\d+\.\d+$/.test(releaseVersion)) {
|
|
51
|
+
throw new Error(
|
|
52
|
+
`XuanLing npm releases require a stable semver version, received ${JSON.stringify(releaseVersion)}`,
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
if (!Object.hasOwn(TARGETS, targetId)) {
|
|
56
|
+
throw new Error(`Unknown XuanLing npm target: ${targetId}`);
|
|
57
|
+
}
|
|
58
|
+
return `${releaseVersion}-${targetId}`;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function expectedOptionalDependencies(releaseVersion) {
|
|
62
|
+
return Object.fromEntries(
|
|
63
|
+
Object.values(TARGETS)
|
|
64
|
+
.sort((left, right) => left.alias.localeCompare(right.alias))
|
|
65
|
+
.map((target) => [
|
|
66
|
+
target.alias,
|
|
67
|
+
`npm:${target.packageName}@${platformVersion(releaseVersion, target.id)}`,
|
|
68
|
+
]),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const MINIMUM_GLIBC = Object.freeze({ major: 2, minor: 35 });
|
|
73
|
+
|
|
74
|
+
function runtimeGlibcVersion(report) {
|
|
75
|
+
try {
|
|
76
|
+
const header = report?.getReport?.()?.header;
|
|
77
|
+
return typeof header?.glibcVersionRuntime === "string"
|
|
78
|
+
? header.glibcVersionRuntime
|
|
79
|
+
: undefined;
|
|
80
|
+
} catch {
|
|
81
|
+
return undefined;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function supportsMinimumGlibc(version) {
|
|
86
|
+
const match = /^(\d+)\.(\d+)/.exec(version);
|
|
87
|
+
if (!match) {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
const major = Number(match[1]);
|
|
91
|
+
const minor = Number(match[2]);
|
|
92
|
+
return (
|
|
93
|
+
major > MINIMUM_GLIBC.major ||
|
|
94
|
+
(major === MINIMUM_GLIBC.major && minor >= MINIMUM_GLIBC.minor)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function detectTarget({
|
|
99
|
+
platform = process.platform,
|
|
100
|
+
arch = process.arch,
|
|
101
|
+
report = process.report,
|
|
102
|
+
} = {}) {
|
|
103
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
104
|
+
return TARGETS["darwin-arm64"];
|
|
105
|
+
}
|
|
106
|
+
if (platform === "win32" && arch === "x64") {
|
|
107
|
+
return TARGETS["win32-x64-msvc"];
|
|
108
|
+
}
|
|
109
|
+
if (platform === "linux" && arch === "x64") {
|
|
110
|
+
const glibcVersion = runtimeGlibcVersion(report);
|
|
111
|
+
if (!glibcVersion) {
|
|
112
|
+
throw new Error(
|
|
113
|
+
"Unsupported Linux libc: xuanling-mcp currently publishes an x64 glibc binary, not musl",
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
if (!supportsMinimumGlibc(glibcVersion)) {
|
|
117
|
+
throw new Error(
|
|
118
|
+
`Unsupported Linux glibc ${glibcVersion}: xuanling-mcp requires glibc 2.35 or newer`,
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
return TARGETS["linux-x64-gnu"];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const supported = Object.values(TARGETS)
|
|
125
|
+
.map((target) => `${target.os}/${target.cpu}${target.libc ? `/${target.libc}` : ""}`)
|
|
126
|
+
.join(", ");
|
|
127
|
+
throw new Error(
|
|
128
|
+
`Unsupported platform: ${platform}/${arch}. Published targets: ${supported}`,
|
|
129
|
+
);
|
|
130
|
+
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xuanling-rs/xuanling-mcp",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "XuanLing
|
|
3
|
+
"version": "0.2.3",
|
|
4
|
+
"description": "Cross-platform stdio MCP server for XuanLing typed filesystem, process, project, artifact, session, and memory tools.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "umbrella22 and XuanLing contributors",
|
|
7
7
|
"type": "module",
|
|
8
|
+
"bin": {
|
|
9
|
+
"xuanling-mcp": "bin/xuanling-mcp.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin",
|
|
13
|
+
"lib",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
"README.md",
|
|
16
|
+
"README-ZH.md"
|
|
17
|
+
],
|
|
8
18
|
"engines": {
|
|
9
19
|
"node": ">=18.17.0"
|
|
10
20
|
},
|
|
@@ -24,9 +34,17 @@
|
|
|
24
34
|
"url": "git+https://github.com/umbrella22/xuanling.git",
|
|
25
35
|
"directory": "npm/packages/xuanling-mcp"
|
|
26
36
|
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"xuanling-mcp-darwin-arm64": "npm:@xuanling-rs/xuanling-mcp-darwin-arm64@0.2.3-darwin-arm64",
|
|
39
|
+
"xuanling-mcp-linux-x64-gnu": "npm:@xuanling-rs/xuanling-mcp-linux-x64-gnu@0.2.3-linux-x64-gnu",
|
|
40
|
+
"xuanling-mcp-win32-x64-msvc": "npm:@xuanling-rs/xuanling-mcp-win32-x64-msvc@0.2.3-win32-x64-msvc"
|
|
41
|
+
},
|
|
27
42
|
"publishConfig": {
|
|
28
43
|
"access": "public",
|
|
44
|
+
"provenance": true,
|
|
29
45
|
"registry": "https://registry.npmjs.org"
|
|
30
46
|
},
|
|
31
|
-
"
|
|
47
|
+
"xuanlingRelease": {
|
|
48
|
+
"sourceCommit": "eec429d009481e193295678b9aa244d44c5d52a2"
|
|
49
|
+
}
|
|
32
50
|
}
|