omnitrade-mcp 0.4.0 → 0.4.1

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.
Files changed (3) hide show
  1. package/dist/cli.js +130 -198
  2. package/dist/index.js +1 -1
  3. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -5,82 +5,71 @@ import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
5
5
  import { homedir } from "os";
6
6
  import { join } from "path";
7
7
  import * as readline from "readline";
8
- var VERSION = "0.4.0";
8
+ var VERSION = "0.4.1";
9
9
  var CONFIG_PATH = join(homedir(), ".omnitrade", "config.json");
10
10
  var c = {
11
11
  reset: "\x1B[0m",
12
12
  bold: "\x1B[1m",
13
13
  dim: "\x1B[2m",
14
- italic: "\x1B[3m",
15
- // Subtle colors
16
14
  white: "\x1B[97m",
17
15
  gray: "\x1B[90m",
18
- blue: "\x1B[38;5;75m",
19
- // Soft blue
20
- cyan: "\x1B[38;5;80m",
21
- // Soft cyan
22
- green: "\x1B[38;5;114m",
23
- // Soft green
24
- yellow: "\x1B[38;5;222m",
25
- // Soft yellow
26
- purple: "\x1B[38;5;141m",
27
- // Soft purple
28
- orange: "\x1B[38;5;215m",
29
- // Soft orange
30
- red: "\x1B[38;5;203m"
31
- // Soft red
16
+ blue: "\x1B[38;5;39m",
17
+ cyan: "\x1B[38;5;51m",
18
+ green: "\x1B[38;5;46m",
19
+ yellow: "\x1B[38;5;226m",
20
+ purple: "\x1B[38;5;165m",
21
+ orange: "\x1B[38;5;208m",
22
+ red: "\x1B[38;5;196m"
32
23
  };
33
24
  function printLogo() {
34
25
  console.log(`
35
- ${c.blue}${c.bold}
36
- \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E
37
- \u2502 \u2502
38
- \u2502 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2557${c.purple}\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557${c.blue}\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2502
39
- \u2502 \u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551${c.purple}\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D${c.blue}\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2502
40
- \u2502 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2551${c.purple} \u2588\u2588\u2551 ${c.blue}\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u2502
41
- \u2502 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2551${c.purple} \u2588\u2588\u2551 ${c.blue}\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2502
42
- \u2502 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2551${c.purple} \u2588\u2588\u2551 ${c.blue}\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2502
43
- \u2502 \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u255D${c.purple} \u255A\u2550\u255D ${c.blue}\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D \u2502
44
- \u2502 \u2502
45
- \u2502 ${c.gray}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.blue} \u2502
46
- \u2502 \u2502
47
- \u2502 ${c.white}One AI. 107 Exchanges. Natural Language Trading.${c.blue} \u2502
48
- \u2502 \u2502
49
- \u2502 ${c.gray}v${VERSION} by Connectry Labs${c.blue} \u2502
50
- \u2502 \u2502
51
- \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F
26
+ ${c.cyan}
27
+ \u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584\u2584
28
+ \u2588${c.reset} ${c.cyan}\u2588
29
+ \u2588${c.reset} ${c.white}${c.bold} \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588\u2588 \u2588\u2588 \u2588\u2588${c.purple}\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588${c.white}\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 ${c.reset}${c.cyan} \u2588
30
+ \u2588${c.reset} ${c.white}${c.bold}\u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588${c.purple} \u2588\u2588 ${c.white}\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ${c.reset}${c.cyan} \u2588
31
+ \u2588${c.reset} ${c.white}${c.bold}\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588${c.purple} \u2588\u2588 ${c.white}\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 ${c.reset}${c.cyan} \u2588
32
+ \u2588${c.reset} ${c.white}${c.bold}\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588${c.purple} \u2588\u2588 ${c.white}\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ${c.reset}${c.cyan} \u2588
33
+ \u2588${c.reset} ${c.white}${c.bold} \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588${c.purple} \u2588\u2588 ${c.white}\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588\u2588\u2588 ${c.reset}${c.cyan} \u2588
34
+ \u2588${c.reset} ${c.cyan}\u2588
35
+ \u2588${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.cyan}\u2588
36
+ \u2588${c.reset} ${c.cyan}\u2588
37
+ \u2588${c.reset} ${c.white}One AI. ${c.cyan}107 Exchanges. ${c.purple}Natural Language Trading.${c.reset} ${c.cyan}\u2588
38
+ \u2588${c.reset} ${c.cyan}\u2588
39
+ \u2588${c.reset} ${c.gray}v${VERSION}${c.reset} ${c.gray}by Connectry Labs${c.reset} ${c.cyan}\u2588
40
+ \u2588${c.reset} ${c.cyan}\u2588
41
+ \u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580\u2580
52
42
  ${c.reset}`);
53
43
  }
54
44
  function printCompactLogo() {
55
45
  console.log(`
56
- ${c.blue}${c.bold} \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E
57
- \u2502 ${c.white}OmniTrade${c.purple} MCP${c.blue} ${c.gray}\xB7 One AI. 107 Exchanges.${c.blue} \u2502
58
- \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F${c.reset}
46
+ ${c.cyan}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}
47
+ ${c.white}${c.bold}OMNITRADE${c.purple} MCP${c.reset} ${c.gray}\u2022 One AI. 107 Exchanges.${c.reset}
48
+ ${c.cyan}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${c.reset}
59
49
  `);
60
50
  }
61
51
  function printHelp() {
62
52
  printLogo();
63
53
  console.log(`
64
- ${c.white}${c.bold} COMMANDS${c.reset}
65
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
54
+ ${c.white}${c.bold}COMMANDS${c.reset}
55
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
66
56
 
67
- ${c.green}setup${c.reset} Guided setup wizard ${c.dim}(recommended for first use)${c.reset}
68
- ${c.blue}start${c.reset} Start the MCP server for Claude Desktop
69
- ${c.blue}test${c.reset} Test your exchange connections
70
- ${c.blue}config${c.reset} View current configuration
71
- ${c.blue}exchanges${c.reset} List all 107 supported exchanges
72
- ${c.blue}help${c.reset} Show this help message
57
+ ${c.green}${c.bold}setup${c.reset} Guided setup wizard ${c.dim}(start here!)${c.reset}
58
+ ${c.cyan}start${c.reset} Start MCP server for Claude Desktop
59
+ ${c.cyan}test${c.reset} Test your exchange connections
60
+ ${c.cyan}config${c.reset} View current configuration
61
+ ${c.cyan}exchanges${c.reset} List all 107 supported exchanges
62
+ ${c.cyan}help${c.reset} Show this help
73
63
 
74
- ${c.white}${c.bold} QUICK START${c.reset}
75
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
64
+ ${c.white}${c.bold}GET STARTED${c.reset}
65
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
76
66
 
77
- ${c.yellow}$${c.reset} ${c.cyan}omnitrade setup${c.reset} ${c.dim}Run the guided setup wizard${c.reset}
67
+ ${c.yellow}$${c.reset} ${c.green}omnitrade setup${c.reset}
78
68
 
79
- ${c.white}${c.bold} LINKS${c.reset}
80
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
69
+ ${c.white}${c.bold}DOCUMENTATION${c.reset}
70
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
81
71
 
82
- ${c.dim}Documentation${c.reset} ${c.blue}https://github.com/Connectry-io/omnitrade-mcp${c.reset}
83
- ${c.dim}Issues${c.reset} ${c.blue}https://github.com/Connectry-io/omnitrade-mcp/issues${c.reset}
72
+ ${c.blue}https://github.com/Connectry-io/omnitrade-mcp${c.reset}
84
73
 
85
74
  `);
86
75
  }
@@ -91,40 +80,35 @@ async function runSetupWizard() {
91
80
  output: process.stdout
92
81
  });
93
82
  const question = (q) => new Promise((resolve) => rl.question(q, resolve));
94
- const clear = () => console.log("\x1B[2J\x1B[H");
95
83
  console.log(`
96
- ${c.white}${c.bold} WELCOME TO OMNITRADE${c.reset}
97
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
84
+ ${c.white}${c.bold}WELCOME TO OMNITRADE${c.reset}
85
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
98
86
 
99
- This wizard will help you connect your first cryptocurrency exchange
100
- to Claude. It takes about ${c.green}2 minutes${c.reset}.
87
+ Let's connect your first crypto exchange to Claude.
88
+ This takes about ${c.green}2 minutes${c.reset}.
101
89
 
102
- ${c.white}${c.bold} WHAT YOU'LL NEED${c.reset}
103
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
90
+ ${c.white}${c.bold}WHAT YOU NEED${c.reset}
104
91
 
105
- ${c.cyan}1.${c.reset} An account on a cryptocurrency exchange ${c.dim}(Binance, Coinbase, etc.)${c.reset}
106
- ${c.cyan}2.${c.reset} API keys from that exchange ${c.dim}(we'll show you how)${c.reset}
107
- ${c.cyan}3.${c.reset} Claude Desktop installed ${c.dim}(download from claude.ai)${c.reset}
92
+ ${c.cyan}1.${c.reset} A crypto exchange account ${c.dim}(Binance, Coinbase, etc.)${c.reset}
93
+ ${c.cyan}2.${c.reset} API keys from that exchange
94
+ ${c.cyan}3.${c.reset} Claude Desktop installed
108
95
 
109
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
110
96
  `);
111
97
  await question(` ${c.dim}Press Enter to continue...${c.reset}`);
112
98
  console.log(`
113
- ${c.white}${c.bold} STEP 1 OF 4: CHOOSE YOUR EXCHANGE${c.reset}
114
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
99
+ ${c.white}${c.bold}STEP 1/4 \u2014 CHOOSE EXCHANGE${c.reset}
100
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
115
101
 
116
- ${c.dim}Popular exchanges:${c.reset}
117
-
118
- ${c.cyan}[1]${c.reset} Binance ${c.dim}Largest exchange, global${c.reset}
119
- ${c.cyan}[2]${c.reset} Coinbase ${c.dim}US-based, beginner friendly${c.reset}
120
- ${c.cyan}[3]${c.reset} Kraken ${c.dim}Security focused, EU/US${c.reset}
121
- ${c.cyan}[4]${c.reset} Bybit ${c.dim}Derivatives, Asia${c.reset}
122
- ${c.cyan}[5]${c.reset} OKX ${c.dim}Full-featured, global${c.reset}
123
- ${c.cyan}[6]${c.reset} KuCoin ${c.dim}Altcoin variety${c.reset}
124
- ${c.cyan}[7]${c.reset} Other ${c.dim}Enter exchange name manually${c.reset}
102
+ ${c.cyan}[1]${c.reset} Binance ${c.dim}Largest global exchange${c.reset}
103
+ ${c.cyan}[2]${c.reset} Coinbase ${c.dim}US-based, beginner friendly${c.reset}
104
+ ${c.cyan}[3]${c.reset} Kraken ${c.dim}Security focused${c.reset}
105
+ ${c.cyan}[4]${c.reset} Bybit ${c.dim}Derivatives trading${c.reset}
106
+ ${c.cyan}[5]${c.reset} OKX ${c.dim}Full-featured${c.reset}
107
+ ${c.cyan}[6]${c.reset} KuCoin ${c.dim}Altcoin variety${c.reset}
108
+ ${c.cyan}[7]${c.reset} Other ${c.dim}Enter name manually${c.reset}
125
109
 
126
110
  `);
127
- const exchangeChoice = await question(` ${c.yellow}?${c.reset} Select exchange ${c.dim}[1-7]${c.reset}: `);
111
+ const exchangeChoice = await question(` ${c.yellow}?${c.reset} Select [1-7]: `);
128
112
  const exchangeMap = {
129
113
  "1": "binance",
130
114
  "2": "coinbase",
@@ -135,65 +119,55 @@ ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2
135
119
  };
136
120
  let exchange = exchangeMap[exchangeChoice.trim()];
137
121
  if (!exchange) {
138
- exchange = await question(` ${c.yellow}?${c.reset} Enter exchange name: `);
122
+ exchange = await question(` ${c.yellow}?${c.reset} Exchange name: `);
139
123
  }
140
124
  exchange = exchange.toLowerCase().trim();
141
125
  console.log(`
142
- ${c.white}${c.bold} STEP 2 OF 4: GET YOUR API KEYS${c.reset}
143
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
126
+ ${c.white}${c.bold}STEP 2/4 \u2014 GET API KEYS${c.reset}
127
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
144
128
 
145
- ${c.dim}You need to create API keys on ${c.white}${exchange}${c.dim}. Here's how:${c.reset}
129
+ Create API keys on ${c.white}${c.bold}${exchange.toUpperCase()}${c.reset}:
146
130
  `);
147
131
  if (exchange === "binance") {
148
132
  console.log(`
149
- ${c.cyan}1.${c.reset} Go to ${c.blue}https://testnet.binance.vision/${c.reset} ${c.dim}(for testnet)${c.reset}
150
- Or ${c.blue}https://www.binance.com/en/my/settings/api-management${c.reset} ${c.dim}(real)${c.reset}
151
- ${c.cyan}2.${c.reset} Click "${c.white}Generate HMAC_SHA256 Key${c.reset}"
152
- ${c.cyan}3.${c.reset} Enable permissions: ${c.green}\u2713 Read${c.reset} ${c.green}\u2713 Trade${c.reset} ${c.red}\u2717 Withdraw${c.reset}
153
- ${c.cyan}4.${c.reset} Copy the ${c.white}API Key${c.reset} and ${c.white}Secret Key${c.reset}
133
+ ${c.cyan}1.${c.reset} Go to ${c.blue}https://testnet.binance.vision${c.reset} ${c.dim}(testnet)${c.reset}
134
+ ${c.cyan}2.${c.reset} Click ${c.white}"Generate HMAC_SHA256 Key"${c.reset}
135
+ ${c.cyan}3.${c.reset} Permissions: ${c.green}\u2713 Read${c.reset} ${c.green}\u2713 Trade${c.reset} ${c.red}\u2717 Withdraw${c.reset}
136
+ ${c.cyan}4.${c.reset} Copy ${c.white}API Key${c.reset} and ${c.white}Secret Key${c.reset}
154
137
  `);
155
138
  } else if (exchange === "coinbase") {
156
139
  console.log(`
157
- ${c.cyan}1.${c.reset} Go to ${c.blue}https://portal.cdp.coinbase.com/${c.reset}
158
- ${c.cyan}2.${c.reset} Create a new project
159
- ${c.cyan}3.${c.reset} Generate API credentials
160
- ${c.cyan}4.${c.reset} Copy ${c.white}API Key${c.reset}, ${c.white}Secret${c.reset}, and ${c.white}Passphrase${c.reset}
161
- `);
162
- } else if (exchange === "kraken") {
163
- console.log(`
164
- ${c.cyan}1.${c.reset} Go to ${c.blue}https://www.kraken.com/u/security/api${c.reset}
165
- ${c.cyan}2.${c.reset} Click "Generate new key"
166
- ${c.cyan}3.${c.reset} Enable: ${c.green}\u2713 Query${c.reset} ${c.green}\u2713 Trade${c.reset} ${c.red}\u2717 Withdraw${c.reset}
167
- ${c.cyan}4.${c.reset} Copy the ${c.white}API Key${c.reset} and ${c.white}Private Key${c.reset}
140
+ ${c.cyan}1.${c.reset} Go to ${c.blue}https://portal.cdp.coinbase.com${c.reset}
141
+ ${c.cyan}2.${c.reset} Create a new project
142
+ ${c.cyan}3.${c.reset} Generate API credentials
143
+ ${c.cyan}4.${c.reset} Copy ${c.white}API Key${c.reset}, ${c.white}Secret${c.reset}, and ${c.white}Passphrase${c.reset}
168
144
  `);
169
145
  } else {
170
146
  console.log(`
171
- ${c.cyan}1.${c.reset} Log in to ${c.white}${exchange}${c.reset}
172
- ${c.cyan}2.${c.reset} Go to API settings ${c.dim}(usually in Settings or Security)${c.reset}
173
- ${c.cyan}3.${c.reset} Create a new API key
174
- ${c.cyan}4.${c.reset} Enable: ${c.green}\u2713 Read${c.reset} ${c.green}\u2713 Trade${c.reset} ${c.red}\u2717 Withdraw${c.reset} ${c.dim}(never enable withdraw!)${c.reset}
175
- ${c.cyan}5.${c.reset} Copy the ${c.white}API Key${c.reset} and ${c.white}Secret${c.reset}
147
+ ${c.cyan}1.${c.reset} Log into ${c.white}${exchange}${c.reset}
148
+ ${c.cyan}2.${c.reset} Go to API settings
149
+ ${c.cyan}3.${c.reset} Create new API key
150
+ ${c.cyan}4.${c.reset} Enable: ${c.green}\u2713 Read${c.reset} ${c.green}\u2713 Trade${c.reset} ${c.red}\u2717 Withdraw${c.reset}
176
151
  `);
177
152
  }
178
- console.log(`
179
- ${c.orange} \u26A0 SECURITY TIP: Never enable withdrawal permissions!${c.reset}
153
+ console.log(` ${c.orange}\u26A0 Never enable withdrawal permissions!${c.reset}
180
154
  `);
181
- await question(` ${c.dim}Press Enter when you have your API keys ready...${c.reset}`);
155
+ await question(` ${c.dim}Press Enter when you have your keys...${c.reset}`);
182
156
  console.log(`
183
- ${c.white}${c.bold} STEP 3 OF 4: ENTER YOUR API KEYS${c.reset}
184
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
157
+ ${c.white}${c.bold}STEP 3/4 \u2014 ENTER API KEYS${c.reset}
158
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
185
159
 
186
- ${c.dim}Your keys are stored locally at ~/.omnitrade/config.json${c.reset}
160
+ ${c.dim}Keys are stored locally at ~/.omnitrade/config.json${c.reset}
187
161
  ${c.dim}They never leave your machine.${c.reset}
188
162
 
189
163
  `);
190
164
  const apiKey = await question(` ${c.yellow}?${c.reset} API Key: `);
191
- const secret = await question(` ${c.yellow}?${c.reset} Secret Key: `);
165
+ const secret = await question(` ${c.yellow}?${c.reset} Secret: `);
192
166
  let password = "";
193
167
  if (["coinbase", "kucoin", "okx"].includes(exchange)) {
194
- password = await question(` ${c.yellow}?${c.reset} Passphrase ${c.dim}(required for ${exchange})${c.reset}: `);
168
+ password = await question(` ${c.yellow}?${c.reset} Passphrase: `);
195
169
  }
196
- const testnetAnswer = await question(` ${c.yellow}?${c.reset} Use testnet/sandbox mode? ${c.dim}(recommended)${c.reset} [Y/n]: `);
170
+ const testnetAnswer = await question(` ${c.yellow}?${c.reset} Use testnet? ${c.dim}(Y/n)${c.reset}: `);
197
171
  const testnet = testnetAnswer.toLowerCase() !== "n";
198
172
  rl.close();
199
173
  const config = {
@@ -221,44 +195,41 @@ ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2
221
195
  } catch {
222
196
  }
223
197
  console.log(`
224
- ${c.green}${c.bold} \u2713 CONFIGURATION SAVED${c.reset}
198
+ ${c.green}${c.bold}\u2713 SAVED${c.reset}
225
199
 
226
- ${c.white}${c.bold} STEP 4 OF 4: CONNECT TO CLAUDE DESKTOP${c.reset}
227
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
200
+ ${c.white}${c.bold}STEP 4/4 \u2014 CONNECT TO CLAUDE${c.reset}
201
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
228
202
 
229
- ${c.dim}Add OmniTrade to Claude Desktop:${c.reset}
203
+ ${c.cyan}1.${c.reset} Open Claude Desktop config:
230
204
 
231
- ${c.cyan}1.${c.reset} Open this file in a text editor:
232
- ${c.blue}~/Library/Application Support/Claude/claude_desktop_config.json${c.reset}
205
+ ${c.dim}macOS:${c.reset} ${c.blue}~/Library/Application Support/Claude/claude_desktop_config.json${c.reset}
206
+ ${c.dim}Windows:${c.reset} ${c.blue}%APPDATA%\\Claude\\claude_desktop_config.json${c.reset}
233
207
 
234
- ${c.cyan}2.${c.reset} Add this configuration:
208
+ ${c.cyan}2.${c.reset} Add this:
235
209
 
236
- ${c.gray}{
237
- "mcpServers": {
238
- "omnitrade": {
239
- "command": "omnitrade",
240
- "args": ["start"]
241
- }
210
+ ${c.gray}{
211
+ "mcpServers": {
212
+ "omnitrade": {
213
+ "command": "omnitrade",
214
+ "args": ["start"]
242
215
  }
243
- }${c.reset}
216
+ }
217
+ }${c.reset}
244
218
 
245
- ${c.cyan}3.${c.reset} Save the file and ${c.white}restart Claude Desktop${c.reset}
219
+ ${c.cyan}3.${c.reset} ${c.white}Restart Claude Desktop${c.reset}
246
220
 
247
- ${c.cyan}4.${c.reset} Start chatting! Try asking:
248
- ${c.dim}"What's my balance on ${exchange}?"${c.reset}
249
- ${c.dim}"Show me the price of Bitcoin"${c.reset}
250
- ${c.dim}"Buy $10 of ETH"${c.reset}
221
+ ${c.cyan}4.${c.reset} Try asking Claude:
222
+ ${c.dim}"What's my balance on ${exchange}?"${c.reset}
251
223
 
252
- ${c.gray} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
224
+ ${c.gray}\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500${c.reset}
253
225
 
254
- ${c.white}${c.bold} NEXT STEPS${c.reset}
226
+ ${c.white}${c.bold}USEFUL COMMANDS${c.reset}
255
227
 
256
- ${c.cyan}\u2022${c.reset} Test your connection: ${c.yellow}omnitrade test${c.reset}
257
- ${c.cyan}\u2022${c.reset} View your config: ${c.yellow}omnitrade config${c.reset}
258
- ${c.cyan}\u2022${c.reset} Add more exchanges: ${c.yellow}omnitrade setup${c.reset} ${c.dim}(run again)${c.reset}
259
- ${c.cyan}\u2022${c.reset} Get help: ${c.yellow}omnitrade help${c.reset}
228
+ ${c.cyan}omnitrade test${c.reset} Test your connection
229
+ ${c.cyan}omnitrade config${c.reset} View configuration
230
+ ${c.cyan}omnitrade setup${c.reset} Add another exchange
260
231
 
261
- ${c.green}${c.bold} \u2713 Setup complete! You're ready to trade with AI.${c.reset}
232
+ ${c.green}${c.bold}\u2713 Setup complete!${c.reset}
262
233
 
263
234
  `);
264
235
  }
@@ -266,55 +237,31 @@ async function showExchanges() {
266
237
  printCompactLogo();
267
238
  const ccxt = await import("ccxt");
268
239
  const exchanges = ccxt.default.exchanges;
269
- console.log(`${c.white}${c.bold} SUPPORTED EXCHANGES${c.reset} ${c.dim}(${exchanges.length} total)${c.reset}
240
+ console.log(` ${c.white}${c.bold}SUPPORTED EXCHANGES${c.reset} ${c.dim}(${exchanges.length})${c.reset}
270
241
  `);
271
- const tier1 = ["binance", "bybit", "okx", "gate", "kucoin", "bitget", "htx", "mexc", "cryptocom", "bitmex", "woo", "coinex", "bitmart", "bingx"];
272
- const tier2 = ["coinbase", "kraken", "bitstamp", "gemini", "bitfinex", "poloniex", "deribit", "upbit", "bithumb", "bitvavo", "phemex", "ascendex", "lbank"];
273
- console.log(` ${c.green}\u2605 TIER 1 - CERTIFIED${c.reset}`);
274
- console.log(` ${c.dim}${tier1.filter((e) => exchanges.includes(e)).join(", ")}${c.reset}`);
275
- console.log(`
276
- ${c.yellow}\u2605 TIER 2 - MAJOR${c.reset}`);
277
- console.log(` ${c.dim}${tier2.filter((e) => exchanges.includes(e)).join(", ")}${c.reset}`);
242
+ const tier1 = ["binance", "bybit", "okx", "gate", "kucoin", "bitget", "htx", "mexc", "cryptocom", "bitmex"];
243
+ const tier2 = ["coinbase", "kraken", "bitstamp", "gemini", "bitfinex", "poloniex", "deribit", "upbit", "bithumb", "bitvavo"];
244
+ console.log(` ${c.green}\u2605 TIER 1${c.reset} ${c.dim}${tier1.join(", ")}${c.reset}`);
245
+ console.log(` ${c.yellow}\u2605 TIER 2${c.reset} ${c.dim}${tier2.join(", ")}${c.reset}`);
278
246
  const others = exchanges.filter((e) => !tier1.includes(e) && !tier2.includes(e));
279
- console.log(`
280
- ${c.gray}\u2605 ALL OTHERS (${others.length})${c.reset}`);
281
- const cols = 8;
282
- for (let i = 0; i < others.length; i += cols) {
283
- const row = others.slice(i, i + cols);
284
- console.log(` ${c.dim}${row.map((e) => e.padEnd(12)).join("")}${c.reset}`);
285
- }
286
- console.log("");
247
+ console.log(` ${c.gray}+ ${others.length} more...${c.reset}
248
+ `);
287
249
  }
288
250
  async function showConfig() {
289
251
  printCompactLogo();
290
- console.log(`${c.white}${c.bold} CONFIGURATION${c.reset}
291
- `);
292
- console.log(` ${c.dim}Location:${c.reset} ${c.blue}${CONFIG_PATH}${c.reset}
293
- `);
294
252
  if (!existsSync(CONFIG_PATH)) {
295
- console.log(` ${c.red}\u2717 No configuration found${c.reset}`);
296
- console.log(`
297
- Run ${c.cyan}omnitrade setup${c.reset} to get started.
253
+ console.log(` ${c.red}\u2717 No configuration${c.reset}
254
+ Run ${c.cyan}omnitrade setup${c.reset}
298
255
  `);
299
256
  return;
300
257
  }
301
258
  try {
302
259
  const config = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
303
- const exchanges = Object.keys(config.exchanges || {});
304
- console.log(` ${c.green}\u2713 Config loaded${c.reset}
260
+ console.log(` ${c.green}\u2713 Config loaded${c.reset} ${c.dim}${CONFIG_PATH}${c.reset}
305
261
  `);
306
- console.log(` ${c.white}${c.bold}Exchanges:${c.reset}`);
307
- for (const ex of exchanges) {
308
- const cfg = config.exchanges[ex];
262
+ for (const [ex, cfg] of Object.entries(config.exchanges || {})) {
309
263
  const mode = cfg.testnet ? `${c.yellow}testnet${c.reset}` : `${c.green}live${c.reset}`;
310
- console.log(` ${c.cyan}\u2022${c.reset} ${ex} (${mode})`);
311
- }
312
- if (config.security) {
313
- console.log(`
314
- ${c.white}${c.bold}Security:${c.reset}`);
315
- if (config.security.maxOrderSize) {
316
- console.log(` ${c.cyan}\u2022${c.reset} Max order: $${config.security.maxOrderSize}`);
317
- }
264
+ console.log(` ${c.cyan}\u2022${c.reset} ${ex} (${mode})`);
318
265
  }
319
266
  console.log("");
320
267
  } catch (error) {
@@ -324,44 +271,32 @@ async function showConfig() {
324
271
  }
325
272
  async function testConnections() {
326
273
  printCompactLogo();
327
- console.log(`${c.white}${c.bold} TESTING CONNECTIONS${c.reset}
328
- `);
329
274
  if (!existsSync(CONFIG_PATH)) {
330
- console.log(` ${c.red}\u2717 No configuration found${c.reset}`);
331
- console.log(`
332
- Run ${c.cyan}omnitrade setup${c.reset} to get started.
275
+ console.log(` ${c.red}\u2717 No configuration${c.reset}
276
+ Run ${c.cyan}omnitrade setup${c.reset}
333
277
  `);
334
278
  return;
335
279
  }
280
+ console.log(` ${c.white}${c.bold}TESTING${c.reset}
281
+ `);
336
282
  const ccxt = await import("ccxt");
337
283
  const config = JSON.parse(readFileSync(CONFIG_PATH, "utf-8"));
338
- const exchanges = Object.entries(config.exchanges || {});
339
- for (const [name, cfg] of exchanges) {
340
- process.stdout.write(` Testing ${c.cyan}${name}${c.reset}... `);
284
+ for (const [name, cfg] of Object.entries(config.exchanges || {})) {
285
+ process.stdout.write(` ${c.cyan}${name}${c.reset} ... `);
341
286
  try {
342
287
  const ExchangeClass = ccxt.default[name];
343
- if (!ExchangeClass) {
344
- console.log(`${c.red}\u2717 Unknown exchange${c.reset}`);
345
- continue;
346
- }
347
288
  const ex = new ExchangeClass({
348
289
  apiKey: cfg.apiKey,
349
290
  secret: cfg.secret,
350
291
  password: cfg.password,
351
292
  enableRateLimit: true
352
293
  });
353
- if (cfg.testnet) {
354
- ex.setSandboxMode(true);
355
- }
294
+ if (cfg.testnet) ex.setSandboxMode(true);
356
295
  const balance = await ex.fetchBalance();
357
- const assets = Object.entries(balance.total).filter(([_, v]) => v > 0).slice(0, 3).map(([k, v]) => `${k}: ${v}`).join(", ");
358
- const mode = cfg.testnet ? `${c.yellow}testnet${c.reset}` : `${c.green}live${c.reset}`;
359
- console.log(`${c.green}\u2713${c.reset} Connected (${mode})`);
360
- if (assets) {
361
- console.log(` ${c.dim}Balances: ${assets}${c.reset}`);
362
- }
296
+ const assets = Object.entries(balance.total).filter(([_, v]) => v > 0).slice(0, 3).map(([k, v]) => `${k}:${v}`).join(" ");
297
+ console.log(`${c.green}\u2713${c.reset} ${c.dim}${assets || "connected"}${c.reset}`);
363
298
  } catch (error) {
364
- console.log(`${c.red}\u2717 ${error.message.substring(0, 50)}${c.reset}`);
299
+ console.log(`${c.red}\u2717${c.reset} ${c.dim}${error.message.slice(0, 40)}${c.reset}`);
365
300
  }
366
301
  }
367
302
  console.log("");
@@ -372,7 +307,6 @@ async function main() {
372
307
  switch (command) {
373
308
  case "setup":
374
309
  case "init":
375
- case "configure":
376
310
  await runSetupWizard();
377
311
  break;
378
312
  case "help":
@@ -390,7 +324,6 @@ async function main() {
390
324
  await showExchanges();
391
325
  break;
392
326
  case "config":
393
- case "status":
394
327
  await showConfig();
395
328
  break;
396
329
  case "test":
@@ -398,12 +331,11 @@ async function main() {
398
331
  break;
399
332
  case "start":
400
333
  case "serve":
401
- case "run":
402
334
  await import("./index.js");
403
335
  break;
404
336
  default:
405
- console.log(`${c.red}Unknown command: ${command}${c.reset}`);
406
- console.log(`Run ${c.cyan}omnitrade help${c.reset} for usage.
337
+ console.log(`${c.red}Unknown: ${command}${c.reset}
338
+ Run ${c.cyan}omnitrade help${c.reset}
407
339
  `);
408
340
  process.exit(1);
409
341
  }
package/dist/index.js CHANGED
@@ -911,7 +911,7 @@ function registerArbitrageTools(server, exchangeManager) {
911
911
  }
912
912
 
913
913
  // src/index.ts
914
- var VERSION = "0.4.0";
914
+ var VERSION = "0.4.1";
915
915
  function showBanner() {
916
916
  console.error(`
917
917
  \u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnitrade-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Multi-exchange AI trading via MCP. 107 exchanges. One AI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",