@aicryptorisk/mcp-server 1.0.0 ā 1.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/MARKETING.md +231 -0
- package/README.md +134 -133
- package/index.js +370 -370
- package/package.json +43 -34
- package/schema.sql +89 -89
- package/setup.js +98 -98
package/package.json
CHANGED
|
@@ -1,34 +1,43 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@aicryptorisk/mcp-server",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "index.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"aicryptorisk-mcp": "./index.js"
|
|
9
|
-
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"start": "node index.js",
|
|
12
|
-
"setup": "node setup.js"
|
|
13
|
-
},
|
|
14
|
-
"dependencies": {
|
|
15
|
-
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
16
|
-
"@supabase/supabase-js": "^2.58.0"
|
|
17
|
-
},
|
|
18
|
-
"keywords": [
|
|
19
|
-
"mcp",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@aicryptorisk/mcp-server",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "The security layer for agentic crypto trading. Detect honeypots, rugpulls, and scam tokens before your AI agent trades.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"aicryptorisk-mcp": "./index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "node index.js",
|
|
12
|
+
"setup": "node setup.js"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
16
|
+
"@supabase/supabase-js": "^2.58.0"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"mcp",
|
|
20
|
+
"model-context-protocol",
|
|
21
|
+
"crypto",
|
|
22
|
+
"cryptocurrency",
|
|
23
|
+
"risk",
|
|
24
|
+
"scam",
|
|
25
|
+
"honeypot",
|
|
26
|
+
"rugpull",
|
|
27
|
+
"security",
|
|
28
|
+
"trading",
|
|
29
|
+
"defi",
|
|
30
|
+
"ai",
|
|
31
|
+
"claude",
|
|
32
|
+
"agent",
|
|
33
|
+
"ethereum",
|
|
34
|
+
"solana"
|
|
35
|
+
],
|
|
36
|
+
"author": "AICryptoRisk",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/djangamane/montecrypto"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://aicryptorisk.com"
|
|
43
|
+
}
|
package/schema.sql
CHANGED
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
-- API Keys table for MCP server authentication
|
|
2
|
-
-- Run this in your Supabase SQL editor
|
|
3
|
-
|
|
4
|
-
-- API Keys table
|
|
5
|
-
CREATE TABLE IF NOT EXISTS api_keys (
|
|
6
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
7
|
-
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
8
|
-
key_hash TEXT NOT NULL UNIQUE,
|
|
9
|
-
key_prefix TEXT NOT NULL, -- First 8 chars for display (e.g., "acr_1a2b...")
|
|
10
|
-
name TEXT NOT NULL DEFAULT 'Default',
|
|
11
|
-
tier TEXT NOT NULL DEFAULT 'free', -- free, pro, enterprise
|
|
12
|
-
daily_limit INTEGER DEFAULT 10, -- null = unlimited
|
|
13
|
-
calls_today INTEGER DEFAULT 0,
|
|
14
|
-
calls_total INTEGER DEFAULT 0,
|
|
15
|
-
is_active BOOLEAN DEFAULT true,
|
|
16
|
-
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
17
|
-
last_used_at TIMESTAMPTZ,
|
|
18
|
-
last_reset_at DATE DEFAULT CURRENT_DATE
|
|
19
|
-
);
|
|
20
|
-
|
|
21
|
-
-- Usage log for billing and analytics
|
|
22
|
-
CREATE TABLE IF NOT EXISTS api_usage_log (
|
|
23
|
-
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
24
|
-
api_key_id UUID REFERENCES api_keys(id) ON DELETE SET NULL,
|
|
25
|
-
tool_name TEXT NOT NULL,
|
|
26
|
-
success BOOLEAN NOT NULL,
|
|
27
|
-
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
28
|
-
metadata JSONB DEFAULT '{}'
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
-- Index for fast lookups
|
|
32
|
-
CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);
|
|
33
|
-
CREATE INDEX IF NOT EXISTS idx_api_keys_user ON api_keys(user_id);
|
|
34
|
-
CREATE INDEX IF NOT EXISTS idx_usage_log_key ON api_usage_log(api_key_id);
|
|
35
|
-
CREATE INDEX IF NOT EXISTS idx_usage_log_timestamp ON api_usage_log(timestamp);
|
|
36
|
-
|
|
37
|
-
-- Function to increment API calls (atomic)
|
|
38
|
-
CREATE OR REPLACE FUNCTION increment_api_calls(key_id UUID)
|
|
39
|
-
RETURNS void AS $$
|
|
40
|
-
BEGIN
|
|
41
|
-
UPDATE api_keys
|
|
42
|
-
SET
|
|
43
|
-
calls_today = CASE
|
|
44
|
-
WHEN last_reset_at < CURRENT_DATE THEN 1
|
|
45
|
-
ELSE calls_today + 1
|
|
46
|
-
END,
|
|
47
|
-
calls_total = calls_total + 1,
|
|
48
|
-
last_used_at = NOW(),
|
|
49
|
-
last_reset_at = CURRENT_DATE
|
|
50
|
-
WHERE id = key_id;
|
|
51
|
-
END;
|
|
52
|
-
$$ LANGUAGE plpgsql;
|
|
53
|
-
|
|
54
|
-
-- RLS Policies
|
|
55
|
-
ALTER TABLE api_keys ENABLE ROW LEVEL SECURITY;
|
|
56
|
-
ALTER TABLE api_usage_log ENABLE ROW LEVEL SECURITY;
|
|
57
|
-
|
|
58
|
-
-- Users can only see their own API keys
|
|
59
|
-
CREATE POLICY "Users can view own api_keys" ON api_keys
|
|
60
|
-
FOR SELECT USING (auth.uid() = user_id);
|
|
61
|
-
|
|
62
|
-
CREATE POLICY "Users can insert own api_keys" ON api_keys
|
|
63
|
-
FOR INSERT WITH CHECK (auth.uid() = user_id);
|
|
64
|
-
|
|
65
|
-
CREATE POLICY "Users can update own api_keys" ON api_keys
|
|
66
|
-
FOR UPDATE USING (auth.uid() = user_id);
|
|
67
|
-
|
|
68
|
-
CREATE POLICY "Users can delete own api_keys" ON api_keys
|
|
69
|
-
FOR DELETE USING (auth.uid() = user_id);
|
|
70
|
-
|
|
71
|
-
-- Users can view their own usage
|
|
72
|
-
CREATE POLICY "Users can view own usage" ON api_usage_log
|
|
73
|
-
FOR SELECT USING (
|
|
74
|
-
api_key_id IN (SELECT id FROM api_keys WHERE user_id = auth.uid())
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
-- Service role can do everything (for the MCP server)
|
|
78
|
-
CREATE POLICY "Service role full access api_keys" ON api_keys
|
|
79
|
-
FOR ALL USING (auth.role() = 'service_role');
|
|
80
|
-
|
|
81
|
-
CREATE POLICY "Service role full access usage" ON api_usage_log
|
|
82
|
-
FOR ALL USING (auth.role() = 'service_role');
|
|
83
|
-
|
|
84
|
-
-- Tier configurations (for reference)
|
|
85
|
-
COMMENT ON TABLE api_keys IS 'Tier limits:
|
|
86
|
-
- free: 10 calls/day
|
|
87
|
-
- pro: 100 calls/day
|
|
88
|
-
- enterprise: unlimited (null daily_limit)
|
|
89
|
-
';
|
|
1
|
+
-- API Keys table for MCP server authentication
|
|
2
|
+
-- Run this in your Supabase SQL editor
|
|
3
|
+
|
|
4
|
+
-- API Keys table
|
|
5
|
+
CREATE TABLE IF NOT EXISTS api_keys (
|
|
6
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
7
|
+
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
|
8
|
+
key_hash TEXT NOT NULL UNIQUE,
|
|
9
|
+
key_prefix TEXT NOT NULL, -- First 8 chars for display (e.g., "acr_1a2b...")
|
|
10
|
+
name TEXT NOT NULL DEFAULT 'Default',
|
|
11
|
+
tier TEXT NOT NULL DEFAULT 'free', -- free, pro, enterprise
|
|
12
|
+
daily_limit INTEGER DEFAULT 10, -- null = unlimited
|
|
13
|
+
calls_today INTEGER DEFAULT 0,
|
|
14
|
+
calls_total INTEGER DEFAULT 0,
|
|
15
|
+
is_active BOOLEAN DEFAULT true,
|
|
16
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
17
|
+
last_used_at TIMESTAMPTZ,
|
|
18
|
+
last_reset_at DATE DEFAULT CURRENT_DATE
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
-- Usage log for billing and analytics
|
|
22
|
+
CREATE TABLE IF NOT EXISTS api_usage_log (
|
|
23
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
24
|
+
api_key_id UUID REFERENCES api_keys(id) ON DELETE SET NULL,
|
|
25
|
+
tool_name TEXT NOT NULL,
|
|
26
|
+
success BOOLEAN NOT NULL,
|
|
27
|
+
timestamp TIMESTAMPTZ DEFAULT NOW(),
|
|
28
|
+
metadata JSONB DEFAULT '{}'
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
-- Index for fast lookups
|
|
32
|
+
CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);
|
|
33
|
+
CREATE INDEX IF NOT EXISTS idx_api_keys_user ON api_keys(user_id);
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_usage_log_key ON api_usage_log(api_key_id);
|
|
35
|
+
CREATE INDEX IF NOT EXISTS idx_usage_log_timestamp ON api_usage_log(timestamp);
|
|
36
|
+
|
|
37
|
+
-- Function to increment API calls (atomic)
|
|
38
|
+
CREATE OR REPLACE FUNCTION increment_api_calls(key_id UUID)
|
|
39
|
+
RETURNS void AS $$
|
|
40
|
+
BEGIN
|
|
41
|
+
UPDATE api_keys
|
|
42
|
+
SET
|
|
43
|
+
calls_today = CASE
|
|
44
|
+
WHEN last_reset_at < CURRENT_DATE THEN 1
|
|
45
|
+
ELSE calls_today + 1
|
|
46
|
+
END,
|
|
47
|
+
calls_total = calls_total + 1,
|
|
48
|
+
last_used_at = NOW(),
|
|
49
|
+
last_reset_at = CURRENT_DATE
|
|
50
|
+
WHERE id = key_id;
|
|
51
|
+
END;
|
|
52
|
+
$$ LANGUAGE plpgsql;
|
|
53
|
+
|
|
54
|
+
-- RLS Policies
|
|
55
|
+
ALTER TABLE api_keys ENABLE ROW LEVEL SECURITY;
|
|
56
|
+
ALTER TABLE api_usage_log ENABLE ROW LEVEL SECURITY;
|
|
57
|
+
|
|
58
|
+
-- Users can only see their own API keys
|
|
59
|
+
CREATE POLICY "Users can view own api_keys" ON api_keys
|
|
60
|
+
FOR SELECT USING (auth.uid() = user_id);
|
|
61
|
+
|
|
62
|
+
CREATE POLICY "Users can insert own api_keys" ON api_keys
|
|
63
|
+
FOR INSERT WITH CHECK (auth.uid() = user_id);
|
|
64
|
+
|
|
65
|
+
CREATE POLICY "Users can update own api_keys" ON api_keys
|
|
66
|
+
FOR UPDATE USING (auth.uid() = user_id);
|
|
67
|
+
|
|
68
|
+
CREATE POLICY "Users can delete own api_keys" ON api_keys
|
|
69
|
+
FOR DELETE USING (auth.uid() = user_id);
|
|
70
|
+
|
|
71
|
+
-- Users can view their own usage
|
|
72
|
+
CREATE POLICY "Users can view own usage" ON api_usage_log
|
|
73
|
+
FOR SELECT USING (
|
|
74
|
+
api_key_id IN (SELECT id FROM api_keys WHERE user_id = auth.uid())
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
-- Service role can do everything (for the MCP server)
|
|
78
|
+
CREATE POLICY "Service role full access api_keys" ON api_keys
|
|
79
|
+
FOR ALL USING (auth.role() = 'service_role');
|
|
80
|
+
|
|
81
|
+
CREATE POLICY "Service role full access usage" ON api_usage_log
|
|
82
|
+
FOR ALL USING (auth.role() = 'service_role');
|
|
83
|
+
|
|
84
|
+
-- Tier configurations (for reference)
|
|
85
|
+
COMMENT ON TABLE api_keys IS 'Tier limits:
|
|
86
|
+
- free: 10 calls/day
|
|
87
|
+
- pro: 100 calls/day
|
|
88
|
+
- enterprise: unlimited (null daily_limit)
|
|
89
|
+
';
|
package/setup.js
CHANGED
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* MCP Server Setup Helper
|
|
5
|
-
* Helps users configure Claude Desktop to use the AI Crypto Risk MCP server
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import fs from "fs";
|
|
9
|
-
import path from "path";
|
|
10
|
-
import { fileURLToPath } from "url";
|
|
11
|
-
import readline from "readline";
|
|
12
|
-
|
|
13
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
-
|
|
15
|
-
const rl = readline.createInterface({
|
|
16
|
-
input: process.stdin,
|
|
17
|
-
output: process.stdout,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
function prompt(question) {
|
|
21
|
-
return new Promise((resolve) => {
|
|
22
|
-
rl.question(question, resolve);
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Detect platform and config path
|
|
27
|
-
function getClaudeConfigPath() {
|
|
28
|
-
const platform = process.platform;
|
|
29
|
-
const home = process.env.HOME || process.env.USERPROFILE;
|
|
30
|
-
|
|
31
|
-
if (platform === "darwin") {
|
|
32
|
-
return path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
33
|
-
} else if (platform === "win32") {
|
|
34
|
-
return path.join(process.env.APPDATA, "Claude", "claude_desktop_config.json");
|
|
35
|
-
} else {
|
|
36
|
-
return path.join(home, ".config", "claude", "claude_desktop_config.json");
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function main() {
|
|
41
|
-
console.log("\nš AI Crypto Risk MCP Server Setup\n");
|
|
42
|
-
console.log("This will configure Claude Desktop to use the crypto risk analysis tools.\n");
|
|
43
|
-
|
|
44
|
-
// Get API key
|
|
45
|
-
const apiKey = await prompt("Enter your API key (get one at https://aicryptorisk.com/api-keys): ");
|
|
46
|
-
|
|
47
|
-
if (!apiKey || !apiKey.startsWith("acr_")) {
|
|
48
|
-
console.log("\nā Invalid API key. Keys should start with 'acr_'");
|
|
49
|
-
rl.close();
|
|
50
|
-
process.exit(1);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const configPath = getClaudeConfigPath();
|
|
54
|
-
const serverPath = path.resolve(__dirname, "index.js");
|
|
55
|
-
|
|
56
|
-
// Read existing config or create new
|
|
57
|
-
let config = { mcpServers: {} };
|
|
58
|
-
try {
|
|
59
|
-
if (fs.existsSync(configPath)) {
|
|
60
|
-
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
61
|
-
config.mcpServers = config.mcpServers || {};
|
|
62
|
-
}
|
|
63
|
-
} catch (err) {
|
|
64
|
-
console.log("Creating new Claude config...");
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Add our server
|
|
68
|
-
config.mcpServers.aicryptorisk = {
|
|
69
|
-
command: "node",
|
|
70
|
-
args: [serverPath],
|
|
71
|
-
env: {
|
|
72
|
-
AICRYPTORISK_API_KEY: apiKey,
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
// Ensure directory exists
|
|
77
|
-
const configDir = path.dirname(configPath);
|
|
78
|
-
if (!fs.existsSync(configDir)) {
|
|
79
|
-
fs.mkdirSync(configDir, { recursive: true });
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Write config
|
|
83
|
-
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
84
|
-
|
|
85
|
-
console.log(`\nā
Configuration saved to: ${configPath}`);
|
|
86
|
-
console.log("\nš Next steps:");
|
|
87
|
-
console.log(" 1. Restart Claude Desktop");
|
|
88
|
-
console.log(" 2. You can now ask Claude to analyze crypto tokens!");
|
|
89
|
-
console.log("\nš” Try: \"Analyze this token for scam risk: 0x...\"");
|
|
90
|
-
|
|
91
|
-
rl.close();
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
main().catch((err) => {
|
|
95
|
-
console.error("Setup failed:", err.message);
|
|
96
|
-
rl.close();
|
|
97
|
-
process.exit(1);
|
|
98
|
-
});
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* MCP Server Setup Helper
|
|
5
|
+
* Helps users configure Claude Desktop to use the AI Crypto Risk MCP server
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "fs";
|
|
9
|
+
import path from "path";
|
|
10
|
+
import { fileURLToPath } from "url";
|
|
11
|
+
import readline from "readline";
|
|
12
|
+
|
|
13
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
|
+
|
|
15
|
+
const rl = readline.createInterface({
|
|
16
|
+
input: process.stdin,
|
|
17
|
+
output: process.stdout,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
function prompt(question) {
|
|
21
|
+
return new Promise((resolve) => {
|
|
22
|
+
rl.question(question, resolve);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Detect platform and config path
|
|
27
|
+
function getClaudeConfigPath() {
|
|
28
|
+
const platform = process.platform;
|
|
29
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
30
|
+
|
|
31
|
+
if (platform === "darwin") {
|
|
32
|
+
return path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
33
|
+
} else if (platform === "win32") {
|
|
34
|
+
return path.join(process.env.APPDATA, "Claude", "claude_desktop_config.json");
|
|
35
|
+
} else {
|
|
36
|
+
return path.join(home, ".config", "claude", "claude_desktop_config.json");
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function main() {
|
|
41
|
+
console.log("\nš AI Crypto Risk MCP Server Setup\n");
|
|
42
|
+
console.log("This will configure Claude Desktop to use the crypto risk analysis tools.\n");
|
|
43
|
+
|
|
44
|
+
// Get API key
|
|
45
|
+
const apiKey = await prompt("Enter your API key (get one at https://aicryptorisk.com/api-keys): ");
|
|
46
|
+
|
|
47
|
+
if (!apiKey || !apiKey.startsWith("acr_")) {
|
|
48
|
+
console.log("\nā Invalid API key. Keys should start with 'acr_'");
|
|
49
|
+
rl.close();
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const configPath = getClaudeConfigPath();
|
|
54
|
+
const serverPath = path.resolve(__dirname, "index.js");
|
|
55
|
+
|
|
56
|
+
// Read existing config or create new
|
|
57
|
+
let config = { mcpServers: {} };
|
|
58
|
+
try {
|
|
59
|
+
if (fs.existsSync(configPath)) {
|
|
60
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
61
|
+
config.mcpServers = config.mcpServers || {};
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
console.log("Creating new Claude config...");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Add our server
|
|
68
|
+
config.mcpServers.aicryptorisk = {
|
|
69
|
+
command: "node",
|
|
70
|
+
args: [serverPath],
|
|
71
|
+
env: {
|
|
72
|
+
AICRYPTORISK_API_KEY: apiKey,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
// Ensure directory exists
|
|
77
|
+
const configDir = path.dirname(configPath);
|
|
78
|
+
if (!fs.existsSync(configDir)) {
|
|
79
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Write config
|
|
83
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
84
|
+
|
|
85
|
+
console.log(`\nā
Configuration saved to: ${configPath}`);
|
|
86
|
+
console.log("\nš Next steps:");
|
|
87
|
+
console.log(" 1. Restart Claude Desktop");
|
|
88
|
+
console.log(" 2. You can now ask Claude to analyze crypto tokens!");
|
|
89
|
+
console.log("\nš” Try: \"Analyze this token for scam risk: 0x...\"");
|
|
90
|
+
|
|
91
|
+
rl.close();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
main().catch((err) => {
|
|
95
|
+
console.error("Setup failed:", err.message);
|
|
96
|
+
rl.close();
|
|
97
|
+
process.exit(1);
|
|
98
|
+
});
|