@fruitbars/xfyun-ai-mcp 0.4.0 → 0.4.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
@@ -3,11 +3,19 @@
3
3
  Cross-platform `npx` launcher for the `xfyun-ai-mcp` stdio MCP server.
4
4
 
5
5
  ```bash
6
- npx -y @fruitbars/xfyun-ai-mcp@0.4.0
6
+ npx -y @fruitbars/xfyun-ai-mcp@0.4.2
7
7
  ```
8
8
 
9
9
  The launcher selects an npm optional dependency for Windows, macOS, or Linux on x64/arm64 and starts the native Go server with inherited stdio and environment variables. Configure `XFYUN_APP_ID`, `XFYUN_API_KEY`, and `XFYUN_API_SECRET` in the MCP host.
10
10
 
11
+ To configure Codex without editing TOML by hand, run:
12
+
13
+ ```bash
14
+ npx -y @fruitbars/xfyun-ai-mcp@latest setup codex
15
+ ```
16
+
17
+ This writes the MCP command and environment-variable names only; set the three credential values in the host environment and restart Codex.
18
+
11
19
  The optional media helper is passed to the native server automatically. TTS text over the 64 KiB service-session limit is split at safe text boundaries and written to one audio output. IFASR audio over 5 hours or 500 MiB is probed, losslessly split, submitted as multiple orders, and merged by the result tool. Users do not need to prepare chunks themselves.
12
20
 
13
21
  PDF OCR uses embedded PDFium WebAssembly: no CGO, Poppler, or other system renderer is required. Text, vector, and scanned PDFs render at 150 DPI by default. Rendering, compression, OCR, NDJSON result writing, and cleanup happen one page at a time, so memory use does not grow with the full document. The PDFium runtime has a 512 MiB hard limit and concurrent PDFs are serialized within one server process. Multi-page MCP calls return an `output_path` instead of accumulating every page in one response.
@@ -2,6 +2,8 @@
2
2
  "use strict";
3
3
 
4
4
  const path = require("node:path");
5
+ const fs = require("node:fs");
6
+ const os = require("node:os");
5
7
  const { spawn } = require("node:child_process");
6
8
 
7
9
  const TARGETS = Object.freeze({
@@ -51,7 +53,69 @@ function resolveFFmpeg(options = {}) {
51
53
  }
52
54
  }
53
55
 
56
+ const CODEX_MCP_SECTION = [
57
+ "[mcp_servers.xfyun-ai]",
58
+ 'command = "npx"',
59
+ 'args = ["-y", "@fruitbars/xfyun-ai-mcp@latest"]',
60
+ 'env_vars = ["XFYUN_APP_ID", "XFYUN_API_KEY", "XFYUN_API_SECRET"]',
61
+ "startup_timeout_sec = 10",
62
+ "tool_timeout_sec = 30000",
63
+ 'default_tools_approval_mode = "writes"'
64
+ ].join("\n");
65
+
66
+ function replaceTomlSection(text, sectionName, replacement) {
67
+ const lines = text.replace(/\r\n/g, "\n").split("\n");
68
+ const sectionPattern = new RegExp(`^\\[${sectionName.replaceAll(".", "\\.")}\\]\\s*$`);
69
+ const start = lines.findIndex((line) => sectionPattern.test(line.trim()));
70
+ if (start < 0) {
71
+ const prefix = text.trimEnd();
72
+ return `${prefix}${prefix ? "\n\n" : ""}${replacement}\n`;
73
+ }
74
+ let end = start + 1;
75
+ while (end < lines.length) {
76
+ const match = /^\[([^\]]+)\]\s*$/.exec(lines[end].trim());
77
+ if (match && match[1] !== sectionName && !match[1].startsWith(`${sectionName}.`)) break;
78
+ end += 1;
79
+ }
80
+ lines.splice(start, end - start, ...replacement.split("\n"));
81
+ return `${lines.join("\n").replace(/\n+$/, "")}\n`;
82
+ }
83
+
84
+ function setupCodex(options = {}) {
85
+ const home = options.homeDir || os.homedir();
86
+ const configDir = path.join(home, ".codex");
87
+ const configPath = path.join(configDir, "config.toml");
88
+ fs.mkdirSync(configDir, { recursive: true });
89
+ const original = fs.existsSync(configPath) ? fs.readFileSync(configPath, "utf8") : "";
90
+ const updated = replaceTomlSection(original, "mcp_servers.xfyun-ai", CODEX_MCP_SECTION);
91
+ if (updated !== original && original) {
92
+ const backup = `${configPath}.bak-${new Date().toISOString().replaceAll(/[:.]/g, "-")}`;
93
+ fs.copyFileSync(configPath, backup);
94
+ }
95
+ if (updated !== original) {
96
+ const temporary = `${configPath}.tmp-${process.pid}`;
97
+ fs.writeFileSync(temporary, updated, { mode: 0o600 });
98
+ fs.renameSync(temporary, configPath);
99
+ }
100
+ process.stdout.write(`Configured Codex MCP at ${configPath}\n`);
101
+ process.stdout.write("Set XFYUN_APP_ID, XFYUN_API_KEY, and XFYUN_API_SECRET, then restart Codex.\n");
102
+ }
103
+
54
104
  function run() {
105
+ if (process.argv[2] === "setup") {
106
+ if (process.argv[3] !== "codex") {
107
+ process.stderr.write("xfyun-ai launcher: usage: setup codex\n");
108
+ process.exitCode = 2;
109
+ return;
110
+ }
111
+ try {
112
+ setupCodex();
113
+ } catch (error) {
114
+ process.stderr.write(`xfyun-ai launcher: unable to configure Codex: ${error.message}\n`);
115
+ process.exitCode = 1;
116
+ }
117
+ return;
118
+ }
55
119
  let binary;
56
120
  try {
57
121
  binary = resolveBinary();
@@ -87,4 +151,4 @@ if (require.main === module) {
87
151
  run();
88
152
  }
89
153
 
90
- module.exports = { TARGETS, targetFor, resolveBinary, resolveFFmpeg };
154
+ module.exports = { TARGETS, targetFor, resolveBinary, resolveFFmpeg, replaceTomlSection, setupCodex };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fruitbars/xfyun-ai-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Cross-platform stdio MCP launcher for XFYun AI capabilities",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,11 +21,11 @@
21
21
  },
22
22
  "optionalDependencies": {
23
23
  "@ffmpeg-installer/ffmpeg": "1.1.0",
24
- "@fruitbars/xfyun-ai-mcp-darwin-arm64": "0.4.0",
25
- "@fruitbars/xfyun-ai-mcp-darwin-x64": "0.4.0",
26
- "@fruitbars/xfyun-ai-mcp-linux-arm64": "0.4.0",
27
- "@fruitbars/xfyun-ai-mcp-linux-x64": "0.4.0",
28
- "@fruitbars/xfyun-ai-mcp-win32-arm64": "0.4.0",
29
- "@fruitbars/xfyun-ai-mcp-win32-x64": "0.4.0"
24
+ "@fruitbars/xfyun-ai-mcp-darwin-arm64": "0.4.2",
25
+ "@fruitbars/xfyun-ai-mcp-darwin-x64": "0.4.2",
26
+ "@fruitbars/xfyun-ai-mcp-linux-arm64": "0.4.2",
27
+ "@fruitbars/xfyun-ai-mcp-linux-x64": "0.4.2",
28
+ "@fruitbars/xfyun-ai-mcp-win32-arm64": "0.4.2",
29
+ "@fruitbars/xfyun-ai-mcp-win32-x64": "0.4.2"
30
30
  }
31
31
  }