icebox-interview-mcp 1.0.0 → 1.0.3

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 (2) hide show
  1. package/index.js +48 -55
  2. package/package.json +19 -5
package/index.js CHANGED
@@ -1,65 +1,47 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import EventSource from 'eventsource';
4
3
  import { createInterface } from 'readline';
5
4
 
6
5
  const token = process.env.ICEBOX_CANDIDATE_TOKEN;
7
6
  const apiUrl = process.env.ICEBOX_API_URL || 'https://api.iceboxiq.com';
8
7
 
9
8
  if (!token) {
10
- console.error(JSON.stringify({
9
+ const error = {
11
10
  jsonrpc: '2.0',
12
11
  error: { code: -32600, message: 'ICEBOX_CANDIDATE_TOKEN environment variable required' },
13
12
  id: null
14
- }));
13
+ };
14
+ console.log(JSON.stringify(error));
15
15
  process.exit(1);
16
16
  }
17
17
 
18
- const sseUrl = `${apiUrl}/api/mcp/candidate/sse`;
19
- const messagesUrl = `${apiUrl}/api/mcp/candidate/messages`;
18
+ const messagesUrl = `${apiUrl}/api/mcp/candidate/message`;
20
19
 
21
- // Connect to SSE endpoint
22
- const es = new EventSource(sseUrl, {
23
- headers: {
24
- 'Authorization': `Bearer ${token}`
25
- }
26
- });
27
-
28
- es.onopen = () => {
29
- // Connection established
30
- };
31
-
32
- es.onmessage = (event) => {
33
- // Forward SSE messages to stdout for Claude Desktop
34
- try {
35
- const data = JSON.parse(event.data);
36
- console.log(JSON.stringify(data));
37
- } catch (e) {
38
- // Raw message
39
- console.log(event.data);
40
- }
41
- };
42
-
43
- es.onerror = (err) => {
44
- console.error(JSON.stringify({
45
- jsonrpc: '2.0',
46
- error: { code: -32603, message: 'SSE connection error' },
47
- id: null
48
- }));
49
- };
50
-
51
- // Read from stdin (messages from Claude Desktop)
20
+ // Read JSON-RPC messages from stdin
52
21
  const rl = createInterface({
53
22
  input: process.stdin,
54
- output: process.stdout,
55
23
  terminal: false
56
24
  });
57
25
 
26
+ // Process each line as a JSON-RPC message
58
27
  rl.on('line', async (line) => {
28
+ if (!line.trim()) return;
29
+
30
+ let message;
59
31
  try {
60
- const message = JSON.parse(line);
32
+ message = JSON.parse(line);
33
+ } catch (e) {
34
+ const error = {
35
+ jsonrpc: '2.0',
36
+ error: { code: -32700, message: 'Parse error: invalid JSON' },
37
+ id: null
38
+ };
39
+ console.log(JSON.stringify(error));
40
+ return;
41
+ }
61
42
 
62
- // Forward to messages endpoint
43
+ try {
44
+ // Forward message to the API
63
45
  const response = await fetch(messagesUrl, {
64
46
  method: 'POST',
65
47
  headers: {
@@ -70,30 +52,41 @@ rl.on('line', async (line) => {
70
52
  });
71
53
 
72
54
  if (!response.ok) {
73
- const error = await response.text();
74
- console.error(JSON.stringify({
55
+ let errorText;
56
+ try {
57
+ const errorJson = await response.json();
58
+ errorText = errorJson.error || JSON.stringify(errorJson);
59
+ } catch {
60
+ errorText = await response.text();
61
+ }
62
+
63
+ const error = {
75
64
  jsonrpc: '2.0',
76
- error: { code: -32603, message: error },
65
+ error: { code: -32603, message: `API error: ${errorText}` },
77
66
  id: message.id || null
78
- }));
67
+ };
68
+ console.log(JSON.stringify(error));
69
+ return;
79
70
  }
80
- // Response comes via SSE
71
+
72
+ // Return the response
73
+ const result = await response.json();
74
+ console.log(JSON.stringify(result));
81
75
  } catch (e) {
82
- console.error(JSON.stringify({
76
+ const error = {
83
77
  jsonrpc: '2.0',
84
- error: { code: -32700, message: 'Parse error' },
85
- id: null
86
- }));
78
+ error: { code: -32603, message: `Request failed: ${e.message}` },
79
+ id: message.id || null
80
+ };
81
+ console.log(JSON.stringify(error));
87
82
  }
88
83
  });
89
84
 
90
- // Handle process termination
91
- process.on('SIGINT', () => {
92
- es.close();
85
+ // Handle stdin close
86
+ rl.on('close', () => {
93
87
  process.exit(0);
94
88
  });
95
89
 
96
- process.on('SIGTERM', () => {
97
- es.close();
98
- process.exit(0);
99
- });
90
+ // Handle termination signals
91
+ process.on('SIGINT', () => process.exit(0));
92
+ process.on('SIGTERM', () => process.exit(0));
package/package.json CHANGED
@@ -1,18 +1,32 @@
1
1
  {
2
2
  "name": "icebox-interview-mcp",
3
- "version": "1.0.0",
4
- "description": "MCP client for Icebox ATS interviews",
3
+ "version": "1.0.3",
4
+ "description": "MCP server for Icebox ATS candidate interviews",
5
5
  "main": "index.js",
6
6
  "bin": {
7
- "icebox-interview": "./index.js"
7
+ "icebox-interview-mcp": "./index.js"
8
8
  },
9
9
  "type": "module",
10
+ "engines": {
11
+ "node": ">=18"
12
+ },
10
13
  "dependencies": {
11
14
  "eventsource": "^2.0.2"
12
15
  },
13
16
  "files": [
14
17
  "index.js"
15
18
  ],
16
- "keywords": ["mcp", "icebox", "interview"],
17
- "license": "MIT"
19
+ "keywords": [
20
+ "mcp",
21
+ "icebox",
22
+ "interview",
23
+ "ats",
24
+ "hiring"
25
+ ],
26
+ "author": "Icebox",
27
+ "license": "MIT",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/iceboxiq/icebox"
31
+ }
18
32
  }