@arkheia/mcp-server 0.1.0

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 ADDED
@@ -0,0 +1,84 @@
1
+ # Arkheia MCP Server — Fabrication Detection for LLMs
2
+
3
+ Detect fabrication (hallucination) in any LLM output.
4
+ Free tier included (1,500 detections/month).
5
+
6
+ ## Quick Start
7
+
8
+ ### 1. Clone and install
9
+
10
+ ```bash
11
+ git clone https://github.com/arkheiaai/arkheia-mcp.git ~/.arkheia-mcp
12
+ cd ~/.arkheia-mcp
13
+ pip install -r requirements.txt
14
+ ```
15
+
16
+ ### 2. Get an API key (free)
17
+
18
+ ```bash
19
+ curl -X POST https://arkheia-proxy-production.up.railway.app/v1/provision \
20
+ -H "Content-Type: application/json" \
21
+ -d '{"email": "you@example.com"}'
22
+ ```
23
+
24
+ ### 3. Add to Claude Desktop
25
+
26
+ Edit your config file:
27
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
28
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
29
+
30
+ ```json
31
+ {
32
+ "mcpServers": {
33
+ "arkheia": {
34
+ "command": "python",
35
+ "args": ["-m", "mcp_server.server"],
36
+ "cwd": "~/.arkheia-mcp",
37
+ "env": {
38
+ "PYTHONPATH": "~/.arkheia-mcp",
39
+ "ARKHEIA_API_KEY": "ak_live_YOUR_KEY_HERE"
40
+ }
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ On Windows, replace `~/.arkheia-mcp` with the full path (e.g. `C:/Users/YourName/.arkheia-mcp`).
47
+
48
+ ### 4. Restart Claude
49
+
50
+ The `arkheia_verify` and `arkheia_audit_log` tools will appear automatically.
51
+
52
+ ## Tools
53
+
54
+ | Tool | Description |
55
+ |------|-------------|
56
+ | `arkheia_verify` | Score any model output for fabrication risk (LOW/MEDIUM/HIGH) |
57
+ | `arkheia_audit_log` | Review detection history |
58
+ | `run_grok` | Call xAI Grok + screen for fabrication |
59
+ | `run_gemini` | Call Google Gemini + screen for fabrication |
60
+ | `run_together` | Call Together AI (Kimi, DeepSeek) + screen |
61
+ | `run_ollama` | Call local Ollama model + screen |
62
+ | `memory_store` / `memory_retrieve` / `memory_relate` | Persistent knowledge graph |
63
+
64
+ ## Pricing
65
+
66
+ - **Free:** 1,500 detections/month (no credit card)
67
+ - **Single Contributor:** $99/month (unlimited)
68
+ - **Professional:** $499/month (20 concurrent)
69
+ - **Team:** $1,999/month (50 concurrent)
70
+
71
+ ## Requirements
72
+
73
+ - Python 3.10+
74
+ - Git
75
+
76
+ ## Full Setup Guide
77
+
78
+ See [AGENTS.md](https://github.com/arkheiaai/arkheia-mcp/blob/master/AGENTS.md) for detailed instructions, troubleshooting, and environment variables.
79
+
80
+ ## Links
81
+
82
+ - Website: https://arkheia.ai
83
+ - GitHub: https://github.com/arkheiaai/arkheia-mcp
84
+ - Support: support@arkheia.ai
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Arkheia MCP Server — thin Node wrapper that spawns the Python MCP server.
4
+ *
5
+ * This wrapper exists so that MCP clients can install via:
6
+ * npx @arkheia/mcp-server
7
+ * npm install -g @arkheia/mcp-server
8
+ *
9
+ * It:
10
+ * 1. Locates a Python 3.10+ interpreter
11
+ * 2. Ensures mcp_server dependencies are installed (pip install)
12
+ * 3. Spawns `python -m mcp_server.server` with stdio transport
13
+ * 4. Forwards stdin/stdout/stderr (MCP uses stdio)
14
+ *
15
+ * Environment variables:
16
+ * ARKHEIA_API_KEY — API key for hosted detection (required)
17
+ * ARKHEIA_PROXY_URL — Local proxy URL (optional, for enterprise)
18
+ * ARKHEIA_HOSTED_URL — Hosted API URL (default: https://arkheia-proxy-production.up.railway.app)
19
+ */
20
+
21
+ const { spawn, execSync } = require("child_process");
22
+ const path = require("path");
23
+ const fs = require("fs");
24
+
25
+ const PYTHON_DIR = path.join(__dirname, "..", "python");
26
+ const REQUIREMENTS = path.join(PYTHON_DIR, "requirements.txt");
27
+ const VENV_DIR = path.join(
28
+ process.env.HOME || process.env.USERPROFILE || "/tmp",
29
+ ".arkheia",
30
+ "venv"
31
+ );
32
+
33
+ function findPython() {
34
+ const candidates = ["python3", "python"];
35
+ for (const cmd of candidates) {
36
+ try {
37
+ const version = execSync(`${cmd} --version 2>&1`, {
38
+ encoding: "utf-8",
39
+ timeout: 5000,
40
+ }).trim();
41
+ const match = version.match(/Python (\d+)\.(\d+)/);
42
+ if (match && parseInt(match[1]) >= 3 && parseInt(match[2]) >= 10) {
43
+ return cmd;
44
+ }
45
+ } catch {
46
+ // Try next candidate
47
+ }
48
+ }
49
+ return null;
50
+ }
51
+
52
+ function ensureVenv(python) {
53
+ const venvPython =
54
+ process.platform === "win32"
55
+ ? path.join(VENV_DIR, "Scripts", "python.exe")
56
+ : path.join(VENV_DIR, "bin", "python");
57
+
58
+ if (!fs.existsSync(venvPython)) {
59
+ process.stderr.write("[arkheia] Creating virtual environment...\n");
60
+ execSync(`${python} -m venv "${VENV_DIR}"`, { stdio: "inherit" });
61
+ }
62
+
63
+ return venvPython;
64
+ }
65
+
66
+ function installDeps(venvPython) {
67
+ const marker = path.join(VENV_DIR, ".arkheia-deps-installed");
68
+ if (fs.existsSync(marker)) {
69
+ return; // Already installed
70
+ }
71
+
72
+ process.stderr.write("[arkheia] Installing dependencies...\n");
73
+ execSync(`"${venvPython}" -m pip install --quiet -r "${REQUIREMENTS}"`, {
74
+ stdio: "inherit",
75
+ timeout: 120000,
76
+ });
77
+
78
+ fs.writeFileSync(marker, new Date().toISOString());
79
+ }
80
+
81
+ function main() {
82
+ const python = findPython();
83
+ if (!python) {
84
+ process.stderr.write(
85
+ "[arkheia] Error: Python 3.10+ is required but not found.\n" +
86
+ "Install Python from https://python.org and try again.\n"
87
+ );
88
+ process.exit(1);
89
+ }
90
+
91
+ // ── Load config from ~/.arkheia/config.json ──────────────────
92
+ const configPath = path.join(
93
+ process.env.HOME || process.env.USERPROFILE || "/tmp",
94
+ ".arkheia",
95
+ "config.json"
96
+ );
97
+ let arkheiaConfig = {};
98
+ try {
99
+ if (fs.existsSync(configPath)) {
100
+ arkheiaConfig = JSON.parse(fs.readFileSync(configPath, "utf-8"));
101
+ process.stderr.write(`[arkheia] Loaded config from ${configPath}\n`);
102
+ }
103
+ } catch (err) {
104
+ process.stderr.write(
105
+ `[arkheia] Warning: Could not read ${configPath}: ${err.message}\n`
106
+ );
107
+ }
108
+
109
+ // Inject API key from config if not already in env
110
+ if (!process.env.ARKHEIA_API_KEY && arkheiaConfig.api_key) {
111
+ process.env.ARKHEIA_API_KEY = arkheiaConfig.api_key;
112
+ process.stderr.write("[arkheia] API key loaded from config.json\n");
113
+ }
114
+
115
+ // Inject hosted URL from config if not already in env
116
+ if (!process.env.ARKHEIA_HOSTED_URL && arkheiaConfig.proxy_url) {
117
+ process.env.ARKHEIA_HOSTED_URL = arkheiaConfig.proxy_url;
118
+ process.stderr.write(`[arkheia] Hosted URL: ${arkheiaConfig.proxy_url}\n`);
119
+ }
120
+
121
+ // Check for API key
122
+ if (!process.env.ARKHEIA_API_KEY) {
123
+ process.stderr.write(
124
+ "[arkheia] Warning: ARKHEIA_API_KEY not set.\n" +
125
+ "Get a free API key at https://arkheia.ai/mcp\n" +
126
+ "Then set: export ARKHEIA_API_KEY=ak_live_...\n\n"
127
+ );
128
+ }
129
+
130
+ let venvPython;
131
+ try {
132
+ venvPython = ensureVenv(python);
133
+ installDeps(venvPython);
134
+ } catch (err) {
135
+ process.stderr.write(
136
+ `[arkheia] Error setting up Python environment: ${err.message}\n`
137
+ );
138
+ process.exit(1);
139
+ }
140
+
141
+ // Spawn the MCP server with stdio transport
142
+ const serverDir = PYTHON_DIR;
143
+ const child = spawn(
144
+ venvPython,
145
+ ["-m", "mcp_server.server"],
146
+ {
147
+ cwd: serverDir,
148
+ stdio: ["pipe", "pipe", "inherit"], // stdin/stdout piped, stderr inherited
149
+ env: {
150
+ ...process.env,
151
+ PYTHONPATH: serverDir,
152
+ },
153
+ }
154
+ );
155
+
156
+ // Forward stdio for MCP protocol
157
+ process.stdin.pipe(child.stdin);
158
+ child.stdout.pipe(process.stdout);
159
+
160
+ child.on("error", (err) => {
161
+ process.stderr.write(`[arkheia] Failed to start MCP server: ${err.message}\n`);
162
+ process.exit(1);
163
+ });
164
+
165
+ child.on("exit", (code) => {
166
+ process.exit(code || 0);
167
+ });
168
+
169
+ // Forward signals
170
+ process.on("SIGINT", () => child.kill("SIGINT"));
171
+ process.on("SIGTERM", () => child.kill("SIGTERM"));
172
+ }
173
+
174
+ main();
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@arkheia/mcp-server",
3
+ "version": "0.1.0",
4
+ "description": "Arkheia MCP Server — Fabrication detection for LLM outputs. Detect hallucination in any model's output with a single tool call.",
5
+ "bin": {
6
+ "mcp-server": "bin/arkheia-mcp.js"
7
+ },
8
+ "scripts": {
9
+ "start": "node bin/arkheia-mcp.js",
10
+ "postinstall": "node scripts/setup.js"
11
+ },
12
+ "keywords": [
13
+ "mcp",
14
+ "ai",
15
+ "fabrication",
16
+ "hallucination",
17
+ "detection",
18
+ "llm",
19
+ "claude",
20
+ "gpt",
21
+ "gemini",
22
+ "governance",
23
+ "audit",
24
+ "grounding",
25
+ "verification"
26
+ ],
27
+ "author": "Arkheia AI <support@arkheia.ai>",
28
+ "license": "MIT",
29
+ "homepage": "https://arkheia.ai/mcp",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/arkheiaai/arkheia-mcp.git"
33
+ },
34
+ "engines": {
35
+ "node": ">=18.0.0"
36
+ },
37
+ "files": [
38
+ "bin/",
39
+ "scripts/",
40
+ "python/",
41
+ "README.md"
42
+ ]
43
+ }
File without changes
@@ -0,0 +1,4 @@
1
+ mcp>=1.26.0
2
+ httpx>=0.27.1
3
+ pydantic>=2.10.0
4
+ pyyaml>=6.0
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Build script — copies Python MCP server source into npm package.
4
+ * Run before `npm publish`.
5
+ *
6
+ * Usage: node scripts/build.js
7
+ */
8
+
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+
12
+ const SRC = path.resolve(__dirname, "..", "..", "mcp_server");
13
+ const DEST = path.resolve(__dirname, "..", "python", "mcp_server");
14
+
15
+ function copyDir(src, dest) {
16
+ if (!fs.existsSync(dest)) {
17
+ fs.mkdirSync(dest, { recursive: true });
18
+ }
19
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
20
+ const srcPath = path.join(src, entry.name);
21
+ const destPath = path.join(dest, entry.name);
22
+ if (entry.name === "__pycache__" || entry.name === "tests") continue;
23
+ if (entry.isDirectory()) {
24
+ copyDir(srcPath, destPath);
25
+ } else if (entry.name.endsWith(".py")) {
26
+ fs.copyFileSync(srcPath, destPath);
27
+ }
28
+ }
29
+ }
30
+
31
+ console.log(`Copying ${SRC} -> ${DEST}`);
32
+ copyDir(SRC, DEST);
33
+ console.log("Build complete. Run `npm publish` from npm-wrapper/.");
@@ -0,0 +1,129 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Post-install script — verifies Python is available and prints setup instructions.
4
+ * Does NOT auto-install Python dependencies (that happens on first run).
5
+ */
6
+
7
+ const { execSync } = require("child_process");
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+
11
+ const ARKHEIA_DIR = path.join(
12
+ process.env.HOME || process.env.USERPROFILE || "/tmp",
13
+ ".arkheia"
14
+ );
15
+ const CONFIG_FILE = path.join(ARKHEIA_DIR, "config.json");
16
+
17
+ function checkApiKey() {
18
+ // Check if config.json exists and has api_key
19
+ try {
20
+ if (fs.existsSync(CONFIG_FILE)) {
21
+ const config = JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
22
+ if (config.api_key && config.api_key.length > 0) {
23
+ return config.api_key;
24
+ }
25
+ }
26
+ } catch {
27
+ // Corrupt config — treat as missing
28
+ }
29
+
30
+ // Check environment variable
31
+ if (process.env.ARKHEIA_API_KEY) {
32
+ // Save env-provided key to config for future runs
33
+ saveConfig(process.env.ARKHEIA_API_KEY);
34
+ return process.env.ARKHEIA_API_KEY;
35
+ }
36
+
37
+ return null;
38
+ }
39
+
40
+ function saveConfig(apiKey) {
41
+ try {
42
+ if (!fs.existsSync(ARKHEIA_DIR)) {
43
+ fs.mkdirSync(ARKHEIA_DIR, { recursive: true });
44
+ }
45
+ const config = {
46
+ api_key: apiKey,
47
+ proxy_url: "https://arkheia-proxy-production.up.railway.app",
48
+ provisioned_at: new Date().toISOString(),
49
+ };
50
+ fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
51
+ } catch (err) {
52
+ console.error(` [arkheia] Warning: Could not save config: ${err.message}`);
53
+ }
54
+ }
55
+
56
+ function checkPython() {
57
+ const candidates = ["python3", "python"];
58
+ for (const cmd of candidates) {
59
+ try {
60
+ const version = execSync(`${cmd} --version 2>&1`, {
61
+ encoding: "utf-8",
62
+ timeout: 5000,
63
+ }).trim();
64
+ const match = version.match(/Python (\d+)\.(\d+)/);
65
+ if (match && parseInt(match[1]) >= 3 && parseInt(match[2]) >= 10) {
66
+ return { cmd, version };
67
+ }
68
+ } catch {
69
+ // Try next
70
+ }
71
+ }
72
+ return null;
73
+ }
74
+
75
+ const python = checkPython();
76
+
77
+ if (!python) {
78
+ console.log(`
79
+ ============================================================
80
+ Arkheia MCP Server requires Python 3.10+
81
+
82
+ Install Python from: https://python.org
83
+ Then run: npx @arkheia/mcp-server
84
+ ============================================================
85
+ `);
86
+ } else {
87
+ console.log(`
88
+ ============================================================
89
+ Arkheia MCP Server installed successfully.
90
+ Python: ${python.version}
91
+ ============================================================
92
+ `);
93
+ }
94
+
95
+ // ── API key provisioning check ──────────────────────────────────
96
+ const existingKey = checkApiKey();
97
+
98
+ if (existingKey) {
99
+ const maskedKey =
100
+ existingKey.substring(0, 8) + "..." + existingKey.substring(existingKey.length - 4);
101
+ console.log(`
102
+ ============================================================
103
+ API key found: ${maskedKey}
104
+ Config: ${CONFIG_FILE}
105
+ ============================================================
106
+ `);
107
+ } else {
108
+ console.log(`
109
+ ============================================================
110
+ No Arkheia API key configured.
111
+
112
+ To enable hosted detection and encrypted profiles:
113
+
114
+ 1. Get a free API key at: https://arkheia.ai/mcp
115
+ 2. Set it in your environment:
116
+ export ARKHEIA_API_KEY=ak_live_...
117
+
118
+ Or save it directly to ${CONFIG_FILE}:
119
+ {
120
+ "api_key": "ak_live_...",
121
+ "proxy_url": "https://arkheia-proxy-production.up.railway.app",
122
+ "provisioned_at": "..."
123
+ }
124
+
125
+ The server will work without a key, but encrypted profiles
126
+ and hosted detection will be unavailable.
127
+ ============================================================
128
+ `);
129
+ }