@databytesolutionid/databyte-mcp 1.0.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/bin/cli.js ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * DataByte AI MCP Server CLI
4
+ *
5
+ * Connects to DataByte AI MCP endpoint at https://ai.databyte.co.id/mcp
6
+ * No external MCP package needed — user connects directly to DataByte.
7
+ */
8
+
9
+ const https = require('https');
10
+
11
+ const args = process.argv.slice(2);
12
+ let apiKey = null;
13
+ let baseUrl = 'https://ai.databyte.co.id/mcp';
14
+
15
+ for (let i = 0; i < args.length; i++) {
16
+ if (args[i] === '--api-key' && args[i + 1]) apiKey = args[++i];
17
+ else if (args[i] === '--url' && args[i + 1]) baseUrl = args[++i];
18
+ else if (args[i] === '--help') {
19
+ console.error(`DataByte AI MCP Server
20
+ Usage: databyte-mcp --api-key sk-db-xxxx
21
+
22
+ Options:
23
+ --api-key <key> DataByte AI API key (required)
24
+ --url <url> MCP endpoint URL (default: https://ai.databyte.co.id/mcp)
25
+ --help Show this help
26
+ `);
27
+ process.exit(0);
28
+ }
29
+ }
30
+
31
+ if (!apiKey) {
32
+ console.error('Error: --api-key is required');
33
+ process.exit(1);
34
+ }
35
+
36
+ const urlObj = new URL(baseUrl);
37
+
38
+ function sendJsonRequest(method, params) {
39
+ return new Promise((resolve, reject) => {
40
+ const payload = JSON.stringify({
41
+ jsonrpc: '2.0',
42
+ id: Date.now(),
43
+ method,
44
+ params
45
+ });
46
+
47
+ const options = {
48
+ hostname: urlObj.hostname,
49
+ port: urlObj.port || 443,
50
+ path: urlObj.pathname,
51
+ method: 'POST',
52
+ headers: {
53
+ 'Content-Type': 'application/json',
54
+ 'Authorization': `Bearer ${apiKey}`,
55
+ 'User-Agent': 'DataByte-MCP/1.0',
56
+ 'Content-Length': Buffer.byteLength(payload)
57
+ }
58
+ };
59
+
60
+ const req = https.request(options, (res) => {
61
+ let data = '';
62
+ res.on('data', chunk => data += chunk);
63
+ res.on('end', () => {
64
+ try { resolve(JSON.parse(data)); }
65
+ catch (e) { reject(new Error('Invalid JSON response')); }
66
+ });
67
+ });
68
+
69
+ req.on('error', reject);
70
+ req.setTimeout(30000, () => { req.destroy(); reject(new Error('Request timeout')); });
71
+ req.write(payload);
72
+ req.end();
73
+ });
74
+ }
75
+
76
+ let initialized = false;
77
+
78
+ async function handleRequest(request) {
79
+ const { method, params, id } = request;
80
+ const response = { jsonrpc: '2.0', id };
81
+
82
+ try {
83
+ if (method === 'initialize') {
84
+ response.result = {
85
+ protocolVersion: '2024-11-05',
86
+ capabilities: { tools: {} },
87
+ serverInfo: { name: 'databyte-mcp', version: '1.0.0' }
88
+ };
89
+ initialized = true;
90
+ send(response);
91
+ return;
92
+ }
93
+
94
+ if (method === 'ping') {
95
+ response.result = { status: 'ok' };
96
+ send(response);
97
+ return;
98
+ }
99
+
100
+ if (method === 'tools/list') {
101
+ response.result = {
102
+ tools: [
103
+ {
104
+ name: 'web_search',
105
+ description: 'Search the web for information.',
106
+ inputSchema: {
107
+ type: 'object',
108
+ properties: {
109
+ query: { type: 'string', description: 'The search query' }
110
+ },
111
+ required: ['query']
112
+ }
113
+ },
114
+ {
115
+ name: 'understand_image',
116
+ description: 'Analyze and understand images.',
117
+ inputSchema: {
118
+ type: 'object',
119
+ properties: {
120
+ image_url: { type: 'string', description: 'URL of the image' },
121
+ prompt: { type: 'string', description: 'Question about the image' }
122
+ },
123
+ required: ['image_url']
124
+ }
125
+ }
126
+ ]
127
+ };
128
+ send(response);
129
+ return;
130
+ }
131
+
132
+ if (method === 'tools/call') {
133
+ if (!initialized) {
134
+ await sendJsonRequest('initialize', {
135
+ protocolVersion: '2024-11-05',
136
+ capabilities: {},
137
+ clientInfo: { name: 'databyte-mcp-cli', version: '1.0.0' }
138
+ });
139
+ initialized = true;
140
+ }
141
+
142
+ const { name, arguments: args } = params || {};
143
+ const result = await sendJsonRequest('tools/call', { name, arguments: args });
144
+ response.result = result.result;
145
+ send(response);
146
+ return;
147
+ }
148
+
149
+ response.error = { code: -32601, message: `Unknown method: ${method}` };
150
+ send(response);
151
+ } catch (error) {
152
+ send({ ...response, error: { code: -32603, message: error.message } });
153
+ }
154
+ }
155
+
156
+ function send(obj) {
157
+ console.log(JSON.stringify(obj));
158
+ }
159
+
160
+ let buffer = '';
161
+ process.stdin.setEncoding('utf8');
162
+
163
+ process.stdin.on('data', (chunk) => {
164
+ buffer += chunk;
165
+ const lines = buffer.split('\n');
166
+ buffer = lines.pop();
167
+ for (const line of lines) {
168
+ if (line.trim()) {
169
+ try { handleRequest(JSON.parse(line)); }
170
+ catch (e) {}
171
+ }
172
+ }
173
+ });
174
+
175
+ process.stdin.on('end', () => {
176
+ if (buffer.trim()) {
177
+ try { handleRequest(JSON.parse(buffer)); }
178
+ catch (e) {}
179
+ }
180
+ });
package/build.js ADDED
@@ -0,0 +1,7 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const src = '/opt/databyte-ai/backend/src/mcp/databyte-mcp-server.js';
4
+ const dest = path.join(__dirname, 'dist/index.js');
5
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
6
+ fs.copyFileSync(src, dest);
7
+ console.log('Built @databyte/databyte-mcp!');
package/dist/index.js ADDED
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * DataByte AI MCP Server (Stdio Bridge)
4
+ *
5
+ * MCP server that bridges stdio protocol to DataByte AI's MCP endpoint.
6
+ * Provides web_search and understand_image tools.
7
+ *
8
+ * Usage in MCP config:
9
+ * {
10
+ * "mcpServers": {
11
+ * "databyte": {
12
+ * "command": "node",
13
+ * "args": ["/path/to/databyte-mcp-server.js", "--api-key", "sk-db-xxxx"]
14
+ * }
15
+ * }
16
+ * }
17
+ *
18
+ * Or for Claude Code (~/.claude/mcp.json):
19
+ * {
20
+ * "mcpServers": {
21
+ * "databyte": {
22
+ * "command": "node",
23
+ * "args": ["/path/to/databyte-mcp-server.js", "--api-key", "YOUR_API_KEY"]
24
+ * }
25
+ * }
26
+ * }
27
+ */
28
+
29
+ const https = require('https');
30
+
31
+ const args = process.argv.slice(2);
32
+ let apiKey = null;
33
+
34
+ for (let i = 0; i < args.length; i++) {
35
+ if (args[i] === '--api-key' && args[i + 1]) apiKey = args[++i];
36
+ else if (args[i] === '--help') {
37
+ console.error(`DataByte AI MCP Server
38
+ Usage: node databyte-mcp-server.js --api-key sk-db-xxxx
39
+
40
+ Options:
41
+ --api-key <key> DataByte AI API key (required)
42
+ --help Show this help
43
+ `);
44
+ process.exit(0);
45
+ }
46
+ }
47
+
48
+ if (!apiKey) {
49
+ console.error('Error: --api-key is required');
50
+ process.exit(1);
51
+ }
52
+
53
+ const BASE_URL = 'ai.databyte.co.id';
54
+ const MCP_PATH = '/mcp';
55
+
56
+ function httpRequest(path, payload) {
57
+ return new Promise((resolve, reject) => {
58
+ const data = JSON.stringify(payload);
59
+ const options = {
60
+ hostname: BASE_URL,
61
+ path,
62
+ method: 'POST',
63
+ headers: {
64
+ 'Content-Type': 'application/json',
65
+ 'Authorization': `Bearer ${apiKey}`,
66
+ 'User-Agent': 'DataByte-MCP/1.0',
67
+ 'Content-Length': Buffer.byteLength(data)
68
+ }
69
+ };
70
+
71
+ const req = https.request(options, (res) => {
72
+ let body = '';
73
+ res.on('data', chunk => body += chunk);
74
+ res.on('end', () => {
75
+ try {
76
+ resolve(JSON.parse(body));
77
+ } catch (e) {
78
+ reject(new Error('Invalid JSON: ' + body));
79
+ }
80
+ });
81
+ });
82
+
83
+ req.on('error', reject);
84
+ req.setTimeout(30000, () => { req.destroy(); reject(new Error('Timeout')); });
85
+ req.write(data);
86
+ req.end();
87
+ });
88
+ }
89
+
90
+ let initialized = false;
91
+
92
+ async function handleRequest(request) {
93
+ const { method, params, id } = request;
94
+ const response = { jsonrpc: '2.0', id };
95
+
96
+ try {
97
+ // Protocol methods - handle locally
98
+ if (method === 'initialize') {
99
+ response.result = {
100
+ protocolVersion: '2024-11-05',
101
+ capabilities: { tools: {} },
102
+ serverInfo: { name: 'databyte-mcp', version: '1.0.0' }
103
+ };
104
+ initialized = true;
105
+ send(response);
106
+ return;
107
+ }
108
+
109
+ if (method === 'ping') {
110
+ response.result = { status: 'ok' };
111
+ send(response);
112
+ return;
113
+ }
114
+
115
+ if (method === 'tools/list') {
116
+ response.result = {
117
+ tools: [
118
+ {
119
+ name: 'web_search',
120
+ description: 'Search the web for information. Use this when you need to find current or specific information from the internet.',
121
+ inputSchema: {
122
+ type: 'object',
123
+ properties: {
124
+ query: { type: 'string', description: 'The search query to look up on the web' }
125
+ },
126
+ required: ['query']
127
+ }
128
+ },
129
+ {
130
+ name: 'understand_image',
131
+ description: 'Analyze and understand the content of an image. Use this when you need to describe, explain, or extract information from an image.',
132
+ inputSchema: {
133
+ type: 'object',
134
+ properties: {
135
+ image_url: { type: 'string', description: 'URL of the image to analyze' },
136
+ prompt: { type: 'string', description: 'What to ask about the image (optional, default: "Describe this image")' }
137
+ },
138
+ required: ['image_url']
139
+ }
140
+ }
141
+ ]
142
+ };
143
+ send(response);
144
+ return;
145
+ }
146
+
147
+ // Forward tool calls to DataByte AI MCP endpoint
148
+ if (method === 'tools/call') {
149
+ if (!initialized) {
150
+ await httpRequest(MCP_PATH, {
151
+ jsonrpc: '2.0', id: Date.now(), method: 'initialize',
152
+ params: { protocolVersion: '2024-11-05', capabilities: {}, clientInfo: { name: 'databyte-mcp-stdio', version: '1.0.0' } }
153
+ });
154
+ initialized = true;
155
+ }
156
+
157
+ const { name, arguments: args } = params || {};
158
+ const result = await httpRequest(MCP_PATH, {
159
+ jsonrpc: '2.0', id: Date.now(), method: 'tools/call',
160
+ params: { name, arguments: args }
161
+ });
162
+
163
+ response.result = result.result;
164
+ send(response);
165
+ return;
166
+ }
167
+
168
+ // Unknown method
169
+ response.error = { code: -32601, message: `Method not found: ${method}` };
170
+ send(response);
171
+
172
+ } catch (error) {
173
+ send({ ...response, error: { code: -32603, message: error.message } });
174
+ }
175
+ }
176
+
177
+ function send(obj) {
178
+ console.log(JSON.stringify(obj));
179
+ }
180
+
181
+ // Read lines from stdin (JSON-RPC messages)
182
+ let buffer = '';
183
+ process.stdin.setEncoding('utf8');
184
+
185
+ process.stdin.on('data', (chunk) => {
186
+ buffer += chunk;
187
+ const lines = buffer.split('\n');
188
+ buffer = lines.pop();
189
+
190
+ for (const line of lines) {
191
+ if (line.trim()) {
192
+ try {
193
+ handleRequest(JSON.parse(line));
194
+ } catch (e) {
195
+ // Skip malformed lines
196
+ }
197
+ }
198
+ }
199
+ });
200
+
201
+ process.stdin.on('end', () => {
202
+ if (buffer.trim()) {
203
+ try {
204
+ handleRequest(JSON.parse(buffer));
205
+ } catch (e) {}
206
+ }
207
+ });
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@databytesolutionid/databyte-mcp",
3
+ "version": "1.0.0",
4
+ "description": "DataByte AI MCP Server - provides web_search and understand_image tools",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "databyte-mcp": "./bin/cli.js"
8
+ },
9
+ "scripts": {
10
+ "build": "node build.js",
11
+ "prepublishOnly": "node build.js"
12
+ },
13
+ "engines": {
14
+ "node": ">=18.0.0"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "databyte",
19
+ "ai",
20
+ "web-search",
21
+ "image-understanding"
22
+ ]
23
+ }