@meldocio/mcp-stdio-proxy 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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Meldoc
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # @meldocio/mcp-stdio-proxy
2
+
3
+ MCP stdio proxy for meldoc - connects Claude Desktop to meldoc MCP API without requiring CLI installation.
4
+
5
+ ## Description
6
+
7
+ This npm package provides a lightweight proxy that bridges JSON-RPC communication between Claude Desktop and the meldoc MCP API. It reads JSON-RPC requests from stdin and forwards them to the meldoc API over HTTP, then returns the responses via stdout.
8
+
9
+ ## Installation
10
+
11
+ The package is designed to be used via `npx`, so no installation is required. However, if you want to install it globally:
12
+
13
+ ```bash
14
+ npm install -g @meldocio/mcp-stdio-proxy
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ### Claude Desktop Configuration
20
+
21
+ Add the following configuration to your `claude_desktop_config.json` file:
22
+
23
+ **macOS:**
24
+
25
+ ```
26
+ ~/Library/Application Support/Claude/claude_desktop_config.json
27
+ ```
28
+
29
+ **Windows:**
30
+
31
+ ```
32
+ %APPDATA%\Claude\claude_desktop_config.json
33
+ ```
34
+
35
+ **Linux:**
36
+
37
+ ```
38
+ ~/.config/Claude/claude_desktop_config.json
39
+ ```
40
+
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "meldoc": {
45
+ "command": "npx",
46
+ "args": ["-y", "@meldocio/mcp-stdio-proxy"],
47
+ "env": {
48
+ "MELDOC_MCP_TOKEN": "your_token_here"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ After adding the configuration, restart Claude Desktop.
56
+
57
+ ### Environment Variables
58
+
59
+ - **MELDOC_MCP_TOKEN** (required): Your meldoc MCP authentication token
60
+ - **MELDOC_API_URL** (optional): Base URL for the meldoc API. Defaults to `https://api.meldoc.io`
61
+
62
+ Example with custom API URL:
63
+
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "meldoc": {
68
+ "command": "npx",
69
+ "args": ["-y", "@meldocio/mcp-stdio-proxy"],
70
+ "env": {
71
+ "MELDOC_MCP_TOKEN": "your_token_here",
72
+ "MELDOC_API_URL": "https://custom.api.example.com"
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### Command Line Testing
80
+
81
+ You can test the proxy directly from the command line:
82
+
83
+ ```bash
84
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
85
+ MELDOC_MCP_TOKEN=your_token_here npx @meldocio/mcp-stdio-proxy
86
+ ```
87
+
88
+ Or with a custom API URL:
89
+
90
+ ```bash
91
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
92
+ MELDOC_MCP_TOKEN=your_token_here \
93
+ MELDOC_API_URL=https://custom.api.example.com \
94
+ npx @meldocio/mcp-stdio-proxy
95
+ ```
96
+
97
+ ## How It Works
98
+
99
+ 1. The proxy reads JSON-RPC requests from `stdin` (newline-delimited JSON)
100
+ 2. Each request is forwarded to `https://api.meldoc.io/mcp/v1/rpc` (or custom URL)
101
+ 3. The `Authorization: Bearer {token}` header is automatically added
102
+ 4. Responses are written to `stdout` in JSON-RPC format
103
+ 5. Errors are handled and returned as proper JSON-RPC error responses
104
+
105
+ ### Supported Features
106
+
107
+ - ✅ JSON-RPC 2.0 protocol
108
+ - ✅ Single and batch requests
109
+ - ✅ Proper error handling with JSON-RPC error codes
110
+ - ✅ Request timeout handling (30 seconds)
111
+ - ✅ Network error recovery
112
+ - ✅ Line-by-line processing for streaming
113
+
114
+ ## JSON-RPC Error Codes
115
+
116
+ The proxy uses standard JSON-RPC 2.0 error codes:
117
+
118
+ - `-32700`: Parse error (invalid JSON)
119
+ - `-32600`: Invalid Request (malformed JSON-RPC)
120
+ - `-32601`: Method not found
121
+ - `-32602`: Invalid params
122
+ - `-32603`: Internal error (network errors, timeouts, etc.)
123
+ - `-32000`: Server error (HTTP 4xx/5xx responses)
124
+
125
+ ## Troubleshooting
126
+
127
+ ### Error: MELDOC_MCP_TOKEN environment variable is required
128
+
129
+ **Solution:** Make sure you've set the `MELDOC_MCP_TOKEN` in the `env` section of your Claude Desktop configuration.
130
+
131
+ ### Connection timeout
132
+
133
+ **Solution:** Check your internet connection and verify that `https://api.meldoc.io` is accessible. You can test with:
134
+
135
+ ```bash
136
+ curl https://api.meldoc.io/mcp/v1/rpc \
137
+ -H "Authorization: Bearer your_token" \
138
+ -H "Content-Type: application/json" \
139
+ -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
140
+ ```
141
+
142
+ ### Invalid token error
143
+
144
+ **Solution:** Verify that your `MELDOC_MCP_TOKEN` is correct and hasn't expired. You can get a new token from the meldoc dashboard.
145
+
146
+ ### Claude Desktop not connecting
147
+
148
+ **Solution:**
149
+
150
+ 1. Verify the configuration JSON is valid (use a JSON validator)
151
+ 2. Check that the file path is correct for your operating system
152
+ 3. Restart Claude Desktop completely
153
+ 4. Check Claude Desktop logs for error messages
154
+
155
+ ### Testing the proxy manually
156
+
157
+ To debug issues, you can test the proxy directly:
158
+
159
+ ```bash
160
+ # Test with a simple request
161
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
162
+ MELDOC_MCP_TOKEN=your_token npx @meldocio/mcp-stdio-proxy
163
+
164
+ # Test with verbose output (if needed)
165
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
166
+ MELDOC_MCP_TOKEN=your_token \
167
+ DEBUG=1 \
168
+ npx @meldocio/mcp-stdio-proxy
169
+ ```
170
+
171
+ ## Development
172
+
173
+ ### Prerequisites
174
+
175
+ - Node.js >= 14.0.0
176
+ - npm
177
+
178
+ ### Setup
179
+
180
+ ```bash
181
+ git clone https://github.com/meldoc/mcp-stdio-proxy.git
182
+ cd mcp-stdio-proxy
183
+ npm install
184
+ ```
185
+
186
+ ### Running Tests
187
+
188
+ ```bash
189
+ npm test
190
+ ```
191
+
192
+ ### Building
193
+
194
+ No build step is required - the package uses plain JavaScript.
195
+
196
+ ### Publishing
197
+
198
+ ```bash
199
+ npm publish --access public
200
+ ```
201
+
202
+ ## Requirements
203
+
204
+ - Node.js >= 14.0.0
205
+ - Valid meldoc MCP token
206
+
207
+ ## License
208
+
209
+ MIT License - see [LICENSE](LICENSE) file for details.
210
+
211
+ ## Support
212
+
213
+ For issues, questions, or contributions, please visit:
214
+
215
+ - GitHub Issues: <https://github.com/meldoc/mcp-stdio-proxy/issues>
216
+ - Documentation: <https://docs.meldoc.io>
217
+
218
+ ## Related
219
+
220
+ - [meldoc MCP Documentation](https://docs.meldoc.io/integrations/mcp)
221
+ - [Claude Desktop MCP Guide](https://docs.anthropic.com/claude/docs/mcp)
@@ -0,0 +1,205 @@
1
+ #!/usr/bin/env node
2
+
3
+ const axios = require('axios');
4
+ const { URL } = require('url');
5
+
6
+ // JSON-RPC error codes
7
+ const JSON_RPC_ERROR_CODES = {
8
+ PARSE_ERROR: -32700,
9
+ INVALID_REQUEST: -32600,
10
+ METHOD_NOT_FOUND: -32601,
11
+ INVALID_PARAMS: -32602,
12
+ INTERNAL_ERROR: -32603,
13
+ SERVER_ERROR: -32000
14
+ };
15
+
16
+ // Configuration
17
+ const token = process.env.MELDOC_MCP_TOKEN;
18
+ const apiUrl = process.env.MELDOC_API_URL || 'https://api.meldoc.io';
19
+ const rpcEndpoint = `${apiUrl}/mcp/v1/rpc`;
20
+ const REQUEST_TIMEOUT = 30000; // 30 seconds
21
+
22
+ // Validate token
23
+ if (!token) {
24
+ console.error('Error: MELDOC_MCP_TOKEN environment variable is required');
25
+ process.exit(1);
26
+ }
27
+
28
+ // Buffer for incomplete lines
29
+ let buffer = '';
30
+
31
+ // Set stdin encoding
32
+ process.stdin.setEncoding('utf8');
33
+
34
+ // Handle stdin data
35
+ process.stdin.on('data', (chunk) => {
36
+ buffer += chunk;
37
+ const lines = buffer.split('\n');
38
+ // Keep the last incomplete line in buffer
39
+ buffer = lines.pop() || '';
40
+
41
+ // Process complete lines
42
+ for (const line of lines) {
43
+ if (line.trim()) {
44
+ handleLine(line.trim());
45
+ }
46
+ }
47
+ });
48
+
49
+ // Handle end of input
50
+ process.stdin.on('end', () => {
51
+ // Process any remaining buffer
52
+ if (buffer.trim()) {
53
+ handleLine(buffer.trim());
54
+ }
55
+ });
56
+
57
+ // Handle errors
58
+ process.stdin.on('error', (error) => {
59
+ sendError(null, JSON_RPC_ERROR_CODES.INTERNAL_ERROR, `Input error: ${error.message}`);
60
+ process.exit(1);
61
+ });
62
+
63
+ /**
64
+ * Handle a single line from stdin
65
+ */
66
+ function handleLine(line) {
67
+ try {
68
+ const request = JSON.parse(line);
69
+ handleRequest(request);
70
+ } catch (parseError) {
71
+ // Invalid JSON - send parse error
72
+ sendError(null, JSON_RPC_ERROR_CODES.PARSE_ERROR, `Parse error: ${parseError.message}`);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Validate JSON-RPC request
78
+ */
79
+ function validateRequest(request) {
80
+ if (!request || typeof request !== 'object') {
81
+ return { valid: false, error: 'Request must be an object' };
82
+ }
83
+
84
+ if (request.jsonrpc !== '2.0') {
85
+ return { valid: false, error: 'jsonrpc must be "2.0"' };
86
+ }
87
+
88
+ if (!request.method && !Array.isArray(request)) {
89
+ return { valid: false, error: 'Request must have a method or be a batch array' };
90
+ }
91
+
92
+ return { valid: true };
93
+ }
94
+
95
+ /**
96
+ * Handle a JSON-RPC request
97
+ */
98
+ async function handleRequest(request) {
99
+ // Handle batch requests (array of requests)
100
+ if (Array.isArray(request)) {
101
+ // Process batch requests sequentially
102
+ for (const req of request) {
103
+ if (req) {
104
+ await processSingleRequest(req);
105
+ }
106
+ }
107
+ return;
108
+ }
109
+
110
+ // Validate single request
111
+ const validation = validateRequest(request);
112
+ if (!validation.valid) {
113
+ sendError(request.id, JSON_RPC_ERROR_CODES.INVALID_REQUEST, validation.error);
114
+ return;
115
+ }
116
+
117
+ await processSingleRequest(request);
118
+ }
119
+
120
+ /**
121
+ * Process a single JSON-RPC request
122
+ */
123
+ async function processSingleRequest(request) {
124
+ try {
125
+ // Make HTTP request to MCP API
126
+ const response = await axios.post(rpcEndpoint, request, {
127
+ headers: {
128
+ 'Authorization': `Bearer ${token}`,
129
+ 'Content-Type': 'application/json'
130
+ },
131
+ timeout: REQUEST_TIMEOUT,
132
+ validateStatus: (status) => status < 500 // Don't throw on 4xx errors
133
+ });
134
+
135
+ // Handle successful response
136
+ if (response.status >= 200 && response.status < 300) {
137
+ const responseData = response.data;
138
+
139
+ // Ensure response has jsonrpc and id if original request had id
140
+ if (responseData && typeof responseData === 'object') {
141
+ if (!responseData.jsonrpc) {
142
+ responseData.jsonrpc = '2.0';
143
+ }
144
+ if (request.id !== undefined && responseData.id === undefined) {
145
+ responseData.id = request.id;
146
+ }
147
+ }
148
+
149
+ process.stdout.write(JSON.stringify(responseData) + '\n');
150
+ } else {
151
+ // HTTP error status
152
+ const errorMessage = response.data?.error?.message ||
153
+ response.data?.message ||
154
+ `HTTP ${response.status}: ${response.statusText}`;
155
+ sendError(request.id, JSON_RPC_ERROR_CODES.SERVER_ERROR, errorMessage);
156
+ }
157
+ } catch (error) {
158
+ // Handle different types of errors
159
+ if (error.response) {
160
+ // Server responded with error status
161
+ const status = error.response.status;
162
+ const errorData = error.response.data;
163
+ const errorMessage = errorData?.error?.message ||
164
+ errorData?.message ||
165
+ `HTTP ${status}: ${error.response.statusText}`;
166
+
167
+ let errorCode = JSON_RPC_ERROR_CODES.SERVER_ERROR;
168
+ if (status === 401) {
169
+ errorCode = JSON_RPC_ERROR_CODES.INTERNAL_ERROR;
170
+ } else if (status === 404) {
171
+ errorCode = JSON_RPC_ERROR_CODES.METHOD_NOT_FOUND;
172
+ }
173
+
174
+ sendError(request.id, errorCode, errorMessage);
175
+ } else if (error.request) {
176
+ // Request was made but no response received
177
+ sendError(request.id, JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
178
+ `Network error: ${error.message || 'No response from server'}`);
179
+ } else if (error.code === 'ECONNABORTED') {
180
+ // Timeout
181
+ sendError(request.id, JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
182
+ `Request timeout after ${REQUEST_TIMEOUT}ms`);
183
+ } else {
184
+ // Other errors
185
+ sendError(request.id, JSON_RPC_ERROR_CODES.INTERNAL_ERROR,
186
+ `Internal error: ${error.message || 'Unknown error'}`);
187
+ }
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Send JSON-RPC error response
193
+ */
194
+ function sendError(id, code, message) {
195
+ const errorResponse = {
196
+ jsonrpc: '2.0',
197
+ id: id !== undefined ? id : null,
198
+ error: {
199
+ code: code,
200
+ message: message
201
+ }
202
+ };
203
+
204
+ process.stdout.write(JSON.stringify(errorResponse) + '\n');
205
+ }
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "@meldocio/mcp-stdio-proxy",
3
+ "version": "1.0.0",
4
+ "description": "MCP stdio proxy for meldoc - connects Claude Desktop to meldoc MCP API",
5
+ "main": "bin/meldoc-mcp-proxy.js",
6
+ "bin": {
7
+ "meldoc-mcp-proxy": "bin/meldoc-mcp-proxy.js"
8
+ },
9
+ "scripts": {
10
+ "test": "jest",
11
+ "prepublishOnly": "npm test"
12
+ },
13
+ "engines": {
14
+ "node": ">=14.0.0"
15
+ },
16
+ "keywords": [
17
+ "mcp",
18
+ "meldoc",
19
+ "claude",
20
+ "stdio",
21
+ "proxy",
22
+ "json-rpc"
23
+ ],
24
+ "author": "Meldoc",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/meldoc/mcp-stdio-proxy.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/meldoc/mcp-stdio-proxy/issues"
32
+ },
33
+ "homepage": "https://github.com/meldoc/mcp-stdio-proxy#readme",
34
+ "dependencies": {
35
+ "axios": "^1.6.0"
36
+ },
37
+ "devDependencies": {
38
+ "jest": "^29.7.0"
39
+ },
40
+ "jest": {
41
+ "testEnvironment": "node",
42
+ "testMatch": [
43
+ "**/__tests__/**/*.test.js"
44
+ ],
45
+ "collectCoverageFrom": [
46
+ "bin/**/*.js"
47
+ ]
48
+ }
49
+ }