@arkheia/mcp-server 0.1.4 → 0.1.5
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 +177 -89
- package/bin/arkheia-mcp.js +92 -59
- package/package.json +3 -2
- package/scripts/setup.js +35 -13
package/README.md
CHANGED
|
@@ -1,89 +1,177 @@
|
|
|
1
|
-
# Arkheia MCP Server — Fabrication Detection for AI Agents
|
|
2
|
-
|
|
3
|
-
Know when your AI is making things up.
|
|
4
|
-
|
|
5
|
-
Arkheia screens model responses for fabrication using behavioural fingerprinting. Works with Claude, GPT, Gemini, Grok, Llama, Mistral, and 30+ other models. One tool call. Real-time risk scoring.
|
|
6
|
-
|
|
7
|
-
Free tier: 1,500 detections/month. No credit card.
|
|
8
|
-
|
|
9
|
-
##
|
|
10
|
-
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
-
|
|
89
|
-
|
|
1
|
+
# Arkheia MCP Server — Fabrication Detection for AI Agents
|
|
2
|
+
|
|
3
|
+
Know when your AI is making things up.
|
|
4
|
+
|
|
5
|
+
Arkheia screens model responses for fabrication using behavioural fingerprinting. Works with Claude, GPT, Gemini, Grok, Llama, Mistral, and 30+ other models. One tool call. Real-time risk scoring.
|
|
6
|
+
|
|
7
|
+
Free tier: 1,500 detections/month. No credit card.
|
|
8
|
+
|
|
9
|
+
## Prerequisites
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Requires:
|
|
13
|
+
- Node 18+
|
|
14
|
+
- Python 3.10–3.13 with working pyexpat
|
|
15
|
+
|
|
16
|
+
macOS note: Homebrew's current `brew install python` installs 3.14,
|
|
17
|
+
which has a broken pyexpat link. Use `brew install python@3.12` until
|
|
18
|
+
Homebrew ships a fix. Verify with:
|
|
19
|
+
python3.12 -c "import pyexpat, ensurepip"
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install -g @arkheia/mcp-server
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Get a free API key at [arkheia.ai/mcp/account](https://arkheia.ai/mcp/account), or via the CLI:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
curl -X POST https://arkheia-proxy-production.up.railway.app/v1/provision \
|
|
32
|
+
-H "Content-Type: application/json" \
|
|
33
|
+
-d '{"email": "you@example.com"}'
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Set your key:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export ARKHEIA_API_KEY="ak_live_..."
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Register with your CLI
|
|
43
|
+
|
|
44
|
+
Each AI CLI has a slightly different `mcp add` command. Use the one that matches your tool. All assume you've installed globally with `npm install -g`.
|
|
45
|
+
|
|
46
|
+
### Claude Code
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
claude mcp add arkheia -s user \
|
|
50
|
+
-e ARKHEIA_API_KEY="$ARKHEIA_API_KEY" \
|
|
51
|
+
-- mcp-server
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Config lands in: `~/.claude.json` under `mcpServers.arkheia`
|
|
55
|
+
|
|
56
|
+
### Codex
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
codex mcp add arkheia \
|
|
60
|
+
--env ARKHEIA_API_KEY="$ARKHEIA_API_KEY" \
|
|
61
|
+
-- mcp-server
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Config lands in: `~/.codex/config.toml` under `[mcp_servers.arkheia.env]`
|
|
65
|
+
|
|
66
|
+
Note: `codex login --api-key` is deprecated. Use `printenv OPENAI_API_KEY | codex login --with-api-key` instead.
|
|
67
|
+
|
|
68
|
+
### Gemini
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
gemini mcp add -s user \
|
|
72
|
+
-e ARKHEIA_API_KEY="$ARKHEIA_API_KEY" \
|
|
73
|
+
arkheia mcp-server
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Config lands in: `~/.gemini/settings.json` under `mcpServers.arkheia`
|
|
77
|
+
|
|
78
|
+
**Gotcha:** `gemini mcp list` only shows project-scope servers. If you registered with `-s user`, verify by reading `~/.gemini/settings.json` directly.
|
|
79
|
+
|
|
80
|
+
**Gotcha:** Don't use `npx -y @arkheia/mcp-server` with Gemini — the `-y` flag gets eaten by Gemini's yargs parser as `--yolo`. Use the globally-installed `mcp-server` binary directly.
|
|
81
|
+
|
|
82
|
+
### Grok
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
grok mcp add arkheia \
|
|
86
|
+
-t stdio \
|
|
87
|
+
-c mcp-server \
|
|
88
|
+
-e ARKHEIA_API_KEY="$ARKHEIA_API_KEY"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Config lands in: `~/.grok/settings.json` under `mcpServers.arkheia` (note: env is nested under `transport`, unlike other CLIs)
|
|
92
|
+
|
|
93
|
+
## Verify it works
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Claude Code — live connection test
|
|
97
|
+
claude mcp list
|
|
98
|
+
|
|
99
|
+
# Codex — shows 'enabled' (not a live check)
|
|
100
|
+
codex mcp list
|
|
101
|
+
|
|
102
|
+
# Grok — best: spawns the server and lists all 9 tools
|
|
103
|
+
grok mcp test arkheia
|
|
104
|
+
|
|
105
|
+
# Gemini — no built-in test; start a session and try the tool
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Important:** MCP registrations are not hot-reloaded. Restart your CLI session after running `mcp add`.
|
|
109
|
+
|
|
110
|
+
## What You Get
|
|
111
|
+
|
|
112
|
+
| Tool | Description |
|
|
113
|
+
|------|-------------|
|
|
114
|
+
| `arkheia_verify` | Score any model response for fabrication risk (LOW/MEDIUM/HIGH) |
|
|
115
|
+
| `arkheia_audit_log` | Review your detection history |
|
|
116
|
+
| `run_grok` | Call Grok + screen for fabrication |
|
|
117
|
+
| `run_gemini` | Call Gemini + screen for fabrication |
|
|
118
|
+
| `run_ollama` | Call local Ollama model + screen |
|
|
119
|
+
| `run_together` | Call Together AI (Kimi, DeepSeek) + screen |
|
|
120
|
+
| `memory_store` | Persistent knowledge graph — upsert entity |
|
|
121
|
+
| `memory_retrieve` | Knowledge graph lookup |
|
|
122
|
+
| `memory_relate` | Create relationship between entities |
|
|
123
|
+
|
|
124
|
+
## 35+ Model Profiles
|
|
125
|
+
|
|
126
|
+
GPT-4o, GPT-5.4, Claude Opus/Sonnet/Haiku, Gemini 2.5/3.0, Grok 4, Llama, Mixtral, CodeLlama, Falcon, Phi4, Kimi K2.5, and more. If your model isn't listed, [let us know](mailto:dmurfet@arkheia.ai).
|
|
127
|
+
|
|
128
|
+
## Pricing
|
|
129
|
+
|
|
130
|
+
| Plan | Price | Detections |
|
|
131
|
+
|------|-------|------------|
|
|
132
|
+
| Free | $0 | 1,500/month |
|
|
133
|
+
| Single Contributor | $99/month | Unlimited |
|
|
134
|
+
| Professional | $499/month | Unlimited |
|
|
135
|
+
| Team | $1,999/month | Unlimited |
|
|
136
|
+
|
|
137
|
+
Manage your account at [arkheia.ai/mcp/account](https://arkheia.ai/mcp/account).
|
|
138
|
+
|
|
139
|
+
## Where API keys are stored
|
|
140
|
+
|
|
141
|
+
| CLI | Config file | Key location |
|
|
142
|
+
|-----|-------------|-------------|
|
|
143
|
+
| Claude Code | `~/.claude.json` | `mcpServers.arkheia.env.ARKHEIA_API_KEY` |
|
|
144
|
+
| Codex | `~/.codex/config.toml` | `[mcp_servers.arkheia.env]` section |
|
|
145
|
+
| Gemini | `~/.gemini/settings.json` | `mcpServers.arkheia.env.ARKHEIA_API_KEY` |
|
|
146
|
+
| Grok | `~/.grok/settings.json` | `mcpServers.arkheia.transport.env.ARKHEIA_API_KEY` |
|
|
147
|
+
|
|
148
|
+
## Troubleshooting
|
|
149
|
+
|
|
150
|
+
**"Python 3.10+ is required but not found"** — Install Python 3.12: `brew install python@3.12` (macOS) or download from [python.org](https://python.org).
|
|
151
|
+
|
|
152
|
+
**"No module named pip"** — Your Python installation has broken pip (common with Python 3.14 on macOS). Delete `~/.arkheia/venv` and switch to Python 3.12: `brew install python@3.12`.
|
|
153
|
+
|
|
154
|
+
**Server registered but tools not showing** — Restart your CLI session. MCP registrations are not hot-reloaded.
|
|
155
|
+
|
|
156
|
+
**API key rejected** — Check for trailing whitespace or `\r` characters. If your env file was created on Windows, run `dos2unix` on it. The server will warn about this on startup.
|
|
157
|
+
|
|
158
|
+
## Full Documentation
|
|
159
|
+
|
|
160
|
+
See the [GitHub repo](https://github.com/arkheiaai/arkheia-mcp) for:
|
|
161
|
+
- Complete setup guide for all agents
|
|
162
|
+
- CLAUDE.md template for automatic detection across projects
|
|
163
|
+
- Multi-agent quorum pattern
|
|
164
|
+
- Test prompts and examples
|
|
165
|
+
|
|
166
|
+
## Feedback
|
|
167
|
+
|
|
168
|
+
- **GitHub Issues:** https://github.com/arkheiaai/arkheia-mcp/issues
|
|
169
|
+
- **Email:** dmurfet@arkheia.ai
|
|
170
|
+
|
|
171
|
+
Every message is read by the founder.
|
|
172
|
+
|
|
173
|
+
## Links
|
|
174
|
+
|
|
175
|
+
- Website: https://arkheia.ai
|
|
176
|
+
- MCP Account: https://arkheia.ai/mcp/account
|
|
177
|
+
- GitHub: https://github.com/arkheiaai/arkheia-mcp
|
package/bin/arkheia-mcp.js
CHANGED
|
@@ -22,59 +22,35 @@ const { spawn, execSync } = require("child_process");
|
|
|
22
22
|
const path = require("path");
|
|
23
23
|
const fs = require("fs");
|
|
24
24
|
|
|
25
|
-
const
|
|
25
|
+
const PYTHON_DIR = path.join(__dirname, "..", "python");
|
|
26
|
+
const REQUIREMENTS = path.join(PYTHON_DIR, "requirements.txt");
|
|
27
|
+
const VENV_DIR = path.join(
|
|
26
28
|
process.env.HOME || process.env.USERPROFILE || "/tmp",
|
|
27
|
-
".arkheia"
|
|
29
|
+
".arkheia",
|
|
30
|
+
"venv"
|
|
28
31
|
);
|
|
29
|
-
const REPO_DIR = path.join(ARKHEIA_HOME, "mcp");
|
|
30
|
-
const BUNDLED_PYTHON_DIR = path.join(__dirname, "..", "python");
|
|
31
|
-
const VENV_DIR = path.join(ARKHEIA_HOME, "venv");
|
|
32
|
-
|
|
33
|
-
// Determine the real Python source: cloned repo > bundled package
|
|
34
|
-
function getServerDir() {
|
|
35
|
-
// If repo already cloned, use it
|
|
36
|
-
if (fs.existsSync(path.join(REPO_DIR, "mcp_server", "server.py"))) {
|
|
37
|
-
return REPO_DIR;
|
|
38
|
-
}
|
|
39
|
-
// If bundled package has the server code, use it
|
|
40
|
-
if (fs.existsSync(path.join(BUNDLED_PYTHON_DIR, "mcp_server", "server.py"))) {
|
|
41
|
-
return BUNDLED_PYTHON_DIR;
|
|
42
|
-
}
|
|
43
|
-
// Neither exists — clone the repo
|
|
44
|
-
process.stderr.write("[arkheia] Server code not found. Cloning from GitHub...\n");
|
|
45
|
-
try {
|
|
46
|
-
if (!fs.existsSync(ARKHEIA_HOME)) fs.mkdirSync(ARKHEIA_HOME, { recursive: true });
|
|
47
|
-
execSync(`git clone --depth 1 https://github.com/arkheiaai/arkheia-mcp.git "${REPO_DIR}"`, {
|
|
48
|
-
stdio: "inherit",
|
|
49
|
-
timeout: 60000,
|
|
50
|
-
});
|
|
51
|
-
process.stderr.write("[arkheia] Repository cloned successfully.\n");
|
|
52
|
-
return REPO_DIR;
|
|
53
|
-
} catch (err) {
|
|
54
|
-
process.stderr.write(
|
|
55
|
-
`[arkheia] Error: Could not clone repository: ${err.message}\n` +
|
|
56
|
-
"Manual install: git clone https://github.com/arkheiaai/arkheia-mcp.git ~/.arkheia/mcp\n"
|
|
57
|
-
);
|
|
58
|
-
process.exit(1);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const PYTHON_DIR = getServerDir();
|
|
63
|
-
const REQUIREMENTS = fs.existsSync(path.join(PYTHON_DIR, "mcp_server", "requirements.txt"))
|
|
64
|
-
? path.join(PYTHON_DIR, "mcp_server", "requirements.txt")
|
|
65
|
-
: path.join(PYTHON_DIR, "requirements.txt");
|
|
66
32
|
|
|
67
33
|
function findPython() {
|
|
68
|
-
|
|
34
|
+
// Try versioned interpreters first — on Homebrew, keg-only formulae like
|
|
35
|
+
// python@3.12 only expose the versioned binary (python3.12), not python3.
|
|
36
|
+
// Exclude 3.14: Homebrew's build has broken pyexpat on macOS as of Apr 2026.
|
|
37
|
+
const candidates = ["python3.13", "python3.12", "python3.11", "python3", "python"];
|
|
69
38
|
for (const cmd of candidates) {
|
|
70
39
|
try {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
40
|
+
// Check version AND that pyexpat + ensurepip actually work.
|
|
41
|
+
// Python 3.14 on macOS crashes on `import pyexpat` due to a missing
|
|
42
|
+
// libexpat symbol — this import check catches it at discovery time.
|
|
43
|
+
const output = execSync(
|
|
44
|
+
`${cmd} -c "import sys,pyexpat,ensurepip; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
45
|
+
{ encoding: "utf-8", timeout: 10000, stdio: ["pipe", "pipe", "pipe"] }
|
|
46
|
+
).trim();
|
|
47
|
+
const match = output.match(/^(\d+)\.(\d+)$/);
|
|
48
|
+
if (match) {
|
|
49
|
+
const major = parseInt(match[1]);
|
|
50
|
+
const minor = parseInt(match[2]);
|
|
51
|
+
if (major === 3 && minor >= 10 && minor <= 13) {
|
|
52
|
+
return cmd;
|
|
53
|
+
}
|
|
78
54
|
}
|
|
79
55
|
} catch {
|
|
80
56
|
// Try next candidate
|
|
@@ -83,15 +59,34 @@ function findPython() {
|
|
|
83
59
|
return null;
|
|
84
60
|
}
|
|
85
61
|
|
|
62
|
+
function venvIsHealthy(venvPython) {
|
|
63
|
+
if (!fs.existsSync(venvPython)) return false;
|
|
64
|
+
try {
|
|
65
|
+
execSync(`"${venvPython}" -m pip --version`, {
|
|
66
|
+
encoding: "utf-8", timeout: 10000, stdio: ["pipe", "pipe", "pipe"],
|
|
67
|
+
});
|
|
68
|
+
return true;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
86
74
|
function ensureVenv(python) {
|
|
87
75
|
const venvPython =
|
|
88
76
|
process.platform === "win32"
|
|
89
77
|
? path.join(VENV_DIR, "Scripts", "python.exe")
|
|
90
78
|
: path.join(VENV_DIR, "bin", "python");
|
|
91
79
|
|
|
92
|
-
if (!
|
|
80
|
+
if (!venvIsHealthy(venvPython)) {
|
|
81
|
+
if (fs.existsSync(VENV_DIR)) {
|
|
82
|
+
process.stderr.write("[arkheia] Existing venv is unhealthy (pip broken or missing). Recreating...\n");
|
|
83
|
+
fs.rmSync(VENV_DIR, { recursive: true, force: true });
|
|
84
|
+
}
|
|
93
85
|
process.stderr.write("[arkheia] Creating virtual environment...\n");
|
|
94
86
|
execSync(`${python} -m venv "${VENV_DIR}"`, { stdio: "inherit" });
|
|
87
|
+
// Force-reinstall deps after venv recreation
|
|
88
|
+
const marker = path.join(VENV_DIR, ".arkheia-deps-installed");
|
|
89
|
+
if (fs.existsSync(marker)) fs.unlinkSync(marker);
|
|
95
90
|
}
|
|
96
91
|
|
|
97
92
|
return venvPython;
|
|
@@ -103,21 +98,58 @@ function installDeps(venvPython) {
|
|
|
103
98
|
return; // Already installed
|
|
104
99
|
}
|
|
105
100
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
101
|
+
const logFile = path.join(ARKHEIA_HOME, "install.log");
|
|
102
|
+
process.stderr.write("[arkheia] Installing Python dependencies (first run)...\n");
|
|
103
|
+
const start = Date.now();
|
|
104
|
+
try {
|
|
105
|
+
const output = execSync(`"${venvPython}" -m pip install -r "${REQUIREMENTS}" 2>&1`, {
|
|
106
|
+
encoding: "utf-8",
|
|
107
|
+
timeout: 300000, // 5 min — slow networks exist
|
|
108
|
+
});
|
|
109
|
+
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
110
|
+
// Count installed packages from pip output
|
|
111
|
+
const installed = (output.match(/Successfully installed/g) || []).length;
|
|
112
|
+
process.stderr.write(`[arkheia] Dependencies installed in ${elapsed}s\n`);
|
|
113
|
+
fs.writeFileSync(marker, new Date().toISOString());
|
|
114
|
+
} catch (err) {
|
|
115
|
+
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
|
|
116
|
+
// Save full pip output for debugging
|
|
117
|
+
const pipOutput = err.stdout || err.stderr || err.message || "unknown error";
|
|
118
|
+
fs.writeFileSync(logFile, pipOutput);
|
|
119
|
+
process.stderr.write(
|
|
120
|
+
`[arkheia] Dependency install failed after ${elapsed}s.\n` +
|
|
121
|
+
`[arkheia] Full output saved to: ${logFile}\n` +
|
|
122
|
+
`[arkheia] Try: "${venvPython}" -m pip install -r "${REQUIREMENTS}"\n`
|
|
123
|
+
);
|
|
124
|
+
throw err;
|
|
125
|
+
}
|
|
113
126
|
}
|
|
114
127
|
|
|
115
128
|
function main() {
|
|
129
|
+
// ── CRLF warning — env files with Windows line endings silently break API keys
|
|
130
|
+
for (const k of ["ARKHEIA_API_KEY", "ARKHEIA_PROXY_URL", "ARKHEIA_HOSTED_URL"]) {
|
|
131
|
+
const v = process.env[k];
|
|
132
|
+
if (v && /[\r\n]/.test(v)) {
|
|
133
|
+
process.stderr.write(
|
|
134
|
+
`[arkheia] WARNING: ${k} contains whitespace/newline characters.\n` +
|
|
135
|
+
`[arkheia] Your env file may have Windows (CRLF) line endings. Run 'dos2unix' on it.\n`
|
|
136
|
+
);
|
|
137
|
+
process.env[k] = v.trim(); // auto-fix for this run
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
116
141
|
const python = findPython();
|
|
117
142
|
if (!python) {
|
|
118
143
|
process.stderr.write(
|
|
119
|
-
"[arkheia] Error: Python 3.10
|
|
120
|
-
|
|
144
|
+
"[arkheia] Error: Python 3.10–3.13 is required but not found.\n\n" +
|
|
145
|
+
" macOS (Homebrew):\n" +
|
|
146
|
+
" brew install python@3.12\n\n" +
|
|
147
|
+
" NOTE: Homebrew's current default 'brew install python' installs 3.14,\n" +
|
|
148
|
+
" which has a broken pyexpat link on macOS as of April 2026.\n" +
|
|
149
|
+
" Use python@3.12 until Homebrew ships a fix.\n\n" +
|
|
150
|
+
" After installing, verify with:\n" +
|
|
151
|
+
" python3.12 -c \"import pyexpat, ensurepip\"\n\n" +
|
|
152
|
+
" Other platforms: https://python.org\n"
|
|
121
153
|
);
|
|
122
154
|
process.exit(1);
|
|
123
155
|
}
|
|
@@ -173,15 +205,16 @@ function main() {
|
|
|
173
205
|
}
|
|
174
206
|
|
|
175
207
|
// Spawn the MCP server with stdio transport
|
|
208
|
+
const serverDir = PYTHON_DIR;
|
|
176
209
|
const child = spawn(
|
|
177
210
|
venvPython,
|
|
178
211
|
["-m", "mcp_server.server"],
|
|
179
212
|
{
|
|
180
|
-
cwd:
|
|
213
|
+
cwd: serverDir,
|
|
181
214
|
stdio: ["pipe", "pipe", "inherit"], // stdin/stdout piped, stderr inherited
|
|
182
215
|
env: {
|
|
183
216
|
...process.env,
|
|
184
|
-
PYTHONPATH:
|
|
217
|
+
PYTHONPATH: serverDir,
|
|
185
218
|
},
|
|
186
219
|
}
|
|
187
220
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arkheia/mcp-server",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"mcpName": "io.github.arkheiaai/mcp-server",
|
|
5
5
|
"description": "Arkheia MCP Server — Fabrication detection for LLM outputs. Detect hallucination in any model's output with a single tool call.",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node bin/arkheia-mcp.js",
|
|
11
|
-
"postinstall": "node scripts/setup.js"
|
|
11
|
+
"postinstall": "node scripts/setup.js",
|
|
12
|
+
"release": "npm version patch --no-git-tag-version && npm publish --access public && node -e \"const{execSync}=require('child_process');const p=require('./package.json');const s=JSON.parse(require('fs').readFileSync('server.json','utf8'));s.version=p.version;s.packages[0].version=p.version;require('fs').writeFileSync('server.json',JSON.stringify(s,null,2));execSync('mcp-publisher publish',{stdio:'inherit'})\" && echo 'Published to npm + MCP registry'"
|
|
12
13
|
},
|
|
13
14
|
"keywords": [
|
|
14
15
|
"mcp",
|
package/scripts/setup.js
CHANGED
|
@@ -54,16 +54,27 @@ function saveConfig(apiKey) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function checkPython() {
|
|
57
|
-
|
|
57
|
+
// Try versioned interpreters first — on Homebrew, keg-only formulae like
|
|
58
|
+
// python@3.12 only expose python3.12, not python3.
|
|
59
|
+
const candidates = ["python3.13", "python3.12", "python3.11", "python3", "python"];
|
|
58
60
|
for (const cmd of candidates) {
|
|
59
61
|
try {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
// Verify version AND that pyexpat + ensurepip work.
|
|
63
|
+
// Python 3.14 on macOS has broken pyexpat (missing libexpat symbol).
|
|
64
|
+
const output = execSync(
|
|
65
|
+
`${cmd} -c "import sys,pyexpat,ensurepip; print(f'{sys.version_info.major}.{sys.version_info.minor}')"`,
|
|
66
|
+
{ encoding: "utf-8", timeout: 10000, stdio: ["pipe", "pipe", "pipe"] }
|
|
67
|
+
).trim();
|
|
68
|
+
const match = output.match(/^(\d+)\.(\d+)$/);
|
|
69
|
+
if (match) {
|
|
70
|
+
const major = parseInt(match[1]);
|
|
71
|
+
const minor = parseInt(match[2]);
|
|
72
|
+
if (major === 3 && minor >= 10 && minor <= 13) {
|
|
73
|
+
const version = execSync(`${cmd} --version 2>&1`, {
|
|
74
|
+
encoding: "utf-8", timeout: 5000,
|
|
75
|
+
}).trim();
|
|
76
|
+
return { cmd, version };
|
|
77
|
+
}
|
|
67
78
|
}
|
|
68
79
|
} catch {
|
|
69
80
|
// Try next
|
|
@@ -75,19 +86,30 @@ function checkPython() {
|
|
|
75
86
|
const python = checkPython();
|
|
76
87
|
|
|
77
88
|
if (!python) {
|
|
78
|
-
console.
|
|
89
|
+
console.error(`
|
|
79
90
|
============================================================
|
|
80
|
-
Arkheia MCP Server requires Python 3.10
|
|
91
|
+
ERROR: Arkheia MCP Server requires Python 3.10–3.13
|
|
92
|
+
with working pyexpat and ensurepip.
|
|
93
|
+
|
|
94
|
+
macOS (Homebrew):
|
|
95
|
+
brew install python@3.12
|
|
96
|
+
|
|
97
|
+
NOTE: Homebrew's current default 'brew install python'
|
|
98
|
+
installs 3.14, which has a broken pyexpat link on macOS
|
|
99
|
+
as of April 2026. Use python@3.12 until Homebrew ships a fix.
|
|
100
|
+
|
|
101
|
+
After installing, verify with:
|
|
102
|
+
python3.12 -c "import pyexpat, ensurepip"
|
|
81
103
|
|
|
82
|
-
|
|
83
|
-
Then run: npx @arkheia/mcp-server
|
|
104
|
+
Other platforms: https://python.org
|
|
84
105
|
============================================================
|
|
85
106
|
`);
|
|
107
|
+
process.exit(1);
|
|
86
108
|
} else {
|
|
87
109
|
console.log(`
|
|
88
110
|
============================================================
|
|
89
111
|
Arkheia MCP Server installed successfully.
|
|
90
|
-
Python: ${python.version}
|
|
112
|
+
Python: ${python.version} (${python.cmd})
|
|
91
113
|
============================================================
|
|
92
114
|
`);
|
|
93
115
|
}
|