@meldocio/mcp-stdio-proxy 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -6,17 +6,23 @@ MCP stdio proxy for meldoc - connects Claude Desktop to meldoc MCP API without r
6
6
 
7
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
8
 
9
+ The package follows MCP best practices:
10
+
11
+ - ✅ Pure stdio communication (no interactive prompts)
12
+ - ✅ All logs go to stderr (stdout is clean JSON-RPC only)
13
+ - ✅ No required arguments at startup
14
+ - ✅ Graceful error handling with proper JSON-RPC error codes
15
+ - ✅ Configurable logging levels
16
+
9
17
  ## Installation
10
18
 
11
- The package is designed to be used via `npx`, so no installation is required. However, if you want to install it globally:
19
+ ### Using Claude Desktop MCP Command
12
20
 
13
21
  ```bash
14
- npm install -g @meldocio/mcp-stdio-proxy
22
+ claude mcp add meldoc npx @meldocio/mcp-stdio-proxy@latest
15
23
  ```
16
24
 
17
- ## Usage
18
-
19
- ### Claude Desktop Configuration
25
+ ### Manual Configuration
20
26
 
21
27
  Add the following configuration to your `claude_desktop_config.json` file:
22
28
 
@@ -43,9 +49,9 @@ Add the following configuration to your `claude_desktop_config.json` file:
43
49
  "mcpServers": {
44
50
  "meldoc": {
45
51
  "command": "npx",
46
- "args": ["-y", "@meldocio/mcp-stdio-proxy"],
52
+ "args": ["-y", "@meldocio/mcp-stdio-proxy@latest"],
47
53
  "env": {
48
- "MELDOC_MCP_TOKEN": "your_token_here"
54
+ "MELDOC_TOKEN": "your_token_here"
49
55
  }
50
56
  }
51
57
  }
@@ -54,68 +60,119 @@ Add the following configuration to your `claude_desktop_config.json` file:
54
60
 
55
61
  After adding the configuration, restart Claude Desktop.
56
62
 
57
- ### Environment Variables
63
+ ## Authentication
64
+
65
+ Meldoc MCP requires an access token. The token is checked in this order:
66
+
67
+ 1. `MELDOC_TOKEN` environment variable (recommended)
68
+ 2. `MELDOC_MCP_TOKEN` environment variable (backward compatibility)
69
+ 3. `~/.meldoc/config.json` file
70
+ 4. If none found, tools will return an authentication error
71
+
72
+ ### Option 1: Environment variable (recommended)
73
+
74
+ Set the token as an environment variable:
75
+
76
+ ```bash
77
+ export MELDOC_TOKEN=your_token_here
78
+ ```
58
79
 
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`
80
+ For permanent setup (macOS/Linux):
61
81
 
62
- Example with custom API URL:
82
+ ```bash
83
+ echo 'export MELDOC_TOKEN=your_token_here' >> ~/.zshrc # or ~/.bashrc
84
+ source ~/.zshrc
85
+ ```
86
+
87
+ For Claude Desktop, add it to your configuration:
63
88
 
64
89
  ```json
65
90
  {
66
91
  "mcpServers": {
67
92
  "meldoc": {
68
93
  "command": "npx",
69
- "args": ["-y", "@meldocio/mcp-stdio-proxy"],
94
+ "args": ["-y", "@meldocio/mcp-stdio-proxy@latest"],
70
95
  "env": {
71
- "MELDOC_MCP_TOKEN": "your_token_here",
72
- "MELDOC_API_URL": "https://custom.api.example.com"
96
+ "MELDOC_TOKEN": "your_token_here"
73
97
  }
74
98
  }
75
99
  }
76
100
  }
77
101
  ```
78
102
 
79
- ### Command Line Testing
103
+ ### Option 2: Meldoc CLI
80
104
 
81
- You can test the proxy directly from the command line:
105
+ If you have the Meldoc CLI installed, run:
82
106
 
83
107
  ```bash
84
- echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
85
- MELDOC_MCP_TOKEN=your_token_here npx @meldocio/mcp-stdio-proxy
108
+ meldoc auth login
86
109
  ```
87
110
 
88
- Or with a custom API URL:
111
+ This will store the token in `~/.meldoc/config.json`, which the MCP proxy will automatically use.
112
+
113
+ ### Option 3: Manual config file
114
+
115
+ Create `~/.meldoc/config.json` manually:
116
+
117
+ ```json
118
+ {
119
+ "token": "your_token_here"
120
+ }
121
+ ```
122
+
123
+ ### Environment Variables
124
+
125
+ - **MELDOC_TOKEN** (recommended): Your meldoc authentication token
126
+ - **MELDOC_MCP_TOKEN** (optional): Alternative token variable (for backward compatibility)
127
+ - **LOG_LEVEL** (optional): Logging level - `ERROR`, `WARN`, `INFO`, or `DEBUG` (default: `ERROR`)
128
+
129
+ ### Command Line Testing
130
+
131
+ You can test the proxy directly from the command line:
89
132
 
90
133
  ```bash
134
+ # Test initialize (works without token)
135
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | \
136
+ npx @meldocio/mcp-stdio-proxy@latest
137
+
138
+ # Test tools/list (requires token)
91
139
  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
140
+ MELDOC_TOKEN=your_token_here npx @meldocio/mcp-stdio-proxy@latest
141
+
142
+ # Test with debug logging
143
+ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
144
+ MELDOC_TOKEN=your_token_here LOG_LEVEL=DEBUG npx @meldocio/mcp-stdio-proxy@latest
95
145
  ```
96
146
 
97
147
  ## How It Works
98
148
 
99
149
  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
150
+ 2. Protocol methods (`initialize`, `ping`, `resources/list`) are handled locally
151
+ 3. Tool requests are forwarded to `https://api.meldoc.io/mcp/v1/rpc`
152
+ 4. The `Authorization: Bearer {token}` header is automatically added
153
+ 5. Responses are written to `stdout` in JSON-RPC format (stdout is clean - only JSON-RPC)
154
+ 6. All logs and diagnostics go to `stderr`
155
+ 7. Errors are handled and returned as proper JSON-RPC error responses
104
156
 
105
157
  ### Supported Features
106
158
 
107
159
  - ✅ JSON-RPC 2.0 protocol
108
160
  - ✅ Single and batch requests
109
161
  - ✅ Proper error handling with JSON-RPC error codes
162
+ - ✅ Custom error codes: `AUTH_REQUIRED`, `NOT_FOUND`, `RATE_LIMIT`
110
163
  - ✅ Request timeout handling (25 seconds)
111
164
  - ✅ Network error recovery
112
165
  - ✅ Line-by-line processing for streaming
113
166
  - ✅ Automatic support for all MCP tools (including `server_info`)
114
- - ✅ Metadata (`_meta`) in responses for better context
167
+ - ✅ Configurable logging levels (ERROR, WARN, INFO, DEBUG)
168
+ - ✅ Graceful shutdown on SIGINT/SIGTERM
169
+ - ✅ No required arguments at startup
115
170
 
116
171
  ## JSON-RPC Error Codes
117
172
 
118
- The proxy uses standard JSON-RPC 2.0 error codes:
173
+ The proxy uses standard JSON-RPC 2.0 error codes plus custom codes:
174
+
175
+ ### Standard JSON-RPC 2.0 Codes
119
176
 
120
177
  - `-32700`: Parse error (invalid JSON)
121
178
  - `-32600`: Invalid Request (malformed JSON-RPC)
@@ -124,6 +181,18 @@ The proxy uses standard JSON-RPC 2.0 error codes:
124
181
  - `-32603`: Internal error (network errors, timeouts, etc.)
125
182
  - `-32000`: Server error (HTTP 4xx/5xx responses)
126
183
 
184
+ ### Custom Error Codes
185
+
186
+ - `-32001`: Authentication required (`AUTH_REQUIRED`) - Token missing or invalid
187
+ - `-32002`: Not found (`NOT_FOUND`) - Resource not found
188
+ - `-32003`: Rate limit exceeded (`RATE_LIMIT`) - Too many requests
189
+
190
+ Error responses include:
191
+
192
+ - `code`: Error code
193
+ - `message`: Human-readable error message
194
+ - `data` (optional, DEBUG level only): Additional error details
195
+
127
196
  ## Available Tools
128
197
 
129
198
  The proxy automatically supports all tools provided by the meldoc MCP API, including:
@@ -143,6 +212,7 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"server_inf
143
212
  ```
144
213
 
145
214
  The response includes:
215
+
146
216
  - Server name (from token)
147
217
  - Token description (if provided)
148
218
  - Available projects with IDs, names, and aliases
@@ -169,9 +239,9 @@ This metadata helps AI assistants understand the context and limitations of the
169
239
 
170
240
  ## Troubleshooting
171
241
 
172
- ### Error: MELDOC_MCP_TOKEN environment variable is required
242
+ ### Error: AUTH_REQUIRED - Meldoc token not found
173
243
 
174
- **Solution:** Make sure you've set the `MELDOC_MCP_TOKEN` in the `env` section of your Claude Desktop configuration.
244
+ **Solution:** Set the `MELDOC_TOKEN` environment variable or run `meldoc auth login` to store the token in `~/.meldoc/config.json`. The token is checked when tools are called, not at startup.
175
245
 
176
246
  ### Connection timeout
177
247
 
@@ -202,15 +272,19 @@ curl https://api.meldoc.io/mcp/v1/rpc \
202
272
  To debug issues, you can test the proxy directly:
203
273
 
204
274
  ```bash
275
+ # Test initialize (works without token)
276
+ echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"1.0.0"}}}' | \
277
+ npx @meldocio/mcp-stdio-proxy@latest
278
+
205
279
  # Test with a simple request
206
280
  echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
207
- MELDOC_MCP_TOKEN=your_token npx @meldocio/mcp-stdio-proxy
281
+ MELDOC_TOKEN=your_token npx @meldocio/mcp-stdio-proxy@latest
208
282
 
209
- # Test with verbose output (if needed)
283
+ # Test with debug logging
210
284
  echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \
211
- MELDOC_MCP_TOKEN=your_token \
212
- DEBUG=1 \
213
- npx @meldocio/mcp-stdio-proxy
285
+ MELDOC_TOKEN=your_token \
286
+ LOG_LEVEL=DEBUG \
287
+ npx @meldocio/mcp-stdio-proxy@latest
214
288
  ```
215
289
 
216
290
  ## Development
@@ -246,8 +320,8 @@ npm publish --access public
246
320
 
247
321
  ## Requirements
248
322
 
249
- - Node.js >= 14.0.0
250
- - Valid meldoc MCP token
323
+ - Node.js >= 18.0.0
324
+ - Valid meldoc MCP token (required for tool calls, not for startup)
251
325
 
252
326
  ## License
253
327
 
package/bin/cli.js ADDED
@@ -0,0 +1,327 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { deviceFlowLogin } = require('../lib/device-flow');
4
+ const { readCredentials, deleteCredentials } = require('../lib/credentials');
5
+ const { getAuthStatus } = require('../lib/auth');
6
+ const { setWorkspaceAlias, getWorkspaceAlias } = require('../lib/config');
7
+ const { getAccessToken } = require('../lib/auth');
8
+ const { getApiUrl, getAppUrl } = require('../lib/constants');
9
+ const axios = require('axios');
10
+ const https = require('https');
11
+ const chalk = require('chalk');
12
+ const logger = require('../lib/logger');
13
+
14
+ const API_URL = getApiUrl();
15
+ const APP_URL = getAppUrl();
16
+
17
+ // Support localhost testing
18
+ if (process.env.MELDOC_API_URL) {
19
+ logger.debug(`Using API URL: ${process.env.MELDOC_API_URL}`);
20
+ }
21
+ if (process.env.MELDOC_APP_URL) {
22
+ logger.debug(`Using App URL: ${process.env.MELDOC_APP_URL}`);
23
+ }
24
+
25
+ /**
26
+ * Handle auth login command
27
+ */
28
+ async function handleAuthLogin() {
29
+ try {
30
+ logger.section('🔐 Authentication');
31
+ await deviceFlowLogin(
32
+ (url, code) => {
33
+ console.log('\n' + logger.label('Visit this URL:'));
34
+ console.log(' ' + logger.url(url));
35
+ console.log('\n' + logger.label('Enter this code:'));
36
+ console.log(' ' + logger.code(code) + '\n');
37
+ logger.info('Waiting for authentication...');
38
+ },
39
+ (status) => {
40
+ if (status === 'denied') {
41
+ logger.error('Login denied by user');
42
+ process.exit(1);
43
+ } else if (status === 'expired') {
44
+ logger.error('Authentication code expired');
45
+ process.exit(1);
46
+ }
47
+ },
48
+ API_URL,
49
+ APP_URL
50
+ );
51
+ logger.success('Login successful!');
52
+ process.exit(0);
53
+ } catch (error) {
54
+ logger.error(`Login failed: ${error.message}`);
55
+ process.exit(1);
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Handle auth status command
61
+ */
62
+ async function handleAuthStatus() {
63
+ const status = await getAuthStatus();
64
+ if (!status || !status.authenticated) {
65
+ logger.error('Not authenticated');
66
+ console.log('\n' + logger.label('To authenticate, run:'));
67
+ console.log(' ' + logger.highlight('npx @meldoc/mcp auth login') + '\n');
68
+ process.exit(1);
69
+ }
70
+
71
+ logger.section('🔑 Authentication Status');
72
+
73
+ if (status.type === 'user_session' && status.user) {
74
+ logger.item('Email', logger.value(status.user.email));
75
+ if (status.expiresAt) {
76
+ logger.item('Token expires', logger.value(new Date(status.expiresAt).toLocaleString()));
77
+ }
78
+ } else {
79
+ logger.item('Type', logger.value(status.type));
80
+ }
81
+
82
+ console.log();
83
+ process.exit(0);
84
+ }
85
+
86
+ /**
87
+ * Handle auth logout command
88
+ */
89
+ async function handleAuthLogout() {
90
+ deleteCredentials();
91
+ logger.success('Logged out successfully');
92
+ process.exit(0);
93
+ }
94
+
95
+ /**
96
+ * Handle config set-workspace command
97
+ */
98
+ function handleConfigSetWorkspace(alias) {
99
+ if (!alias) {
100
+ logger.error('Workspace alias is required');
101
+ console.log('\n' + logger.label('Usage:'));
102
+ console.log(' ' + logger.highlight('npx @meldoc/mcp config set-workspace <alias>') + '\n');
103
+ process.exit(1);
104
+ }
105
+
106
+ try {
107
+ setWorkspaceAlias(alias);
108
+ logger.success(`Workspace set to: ${logger.highlight(alias)}`);
109
+ process.exit(0);
110
+ } catch (error) {
111
+ logger.error(`Failed to set workspace: ${error.message}`);
112
+ process.exit(1);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Handle config get-workspace command
118
+ */
119
+ function handleConfigGetWorkspace() {
120
+ const alias = getWorkspaceAlias();
121
+ if (alias) {
122
+ console.log(logger.highlight(alias));
123
+ }
124
+ process.exit(0);
125
+ }
126
+
127
+ /**
128
+ * Handle config list-workspaces command
129
+ */
130
+ async function handleConfigListWorkspaces() {
131
+ try {
132
+ const tokenInfo = await getAccessToken();
133
+ if (!tokenInfo) {
134
+ logger.error('Not authenticated');
135
+ console.log('\n' + logger.label('To authenticate, run:'));
136
+ console.log(' ' + logger.highlight('npx @meldoc/mcp auth login') + '\n');
137
+ process.exit(1);
138
+ }
139
+
140
+ // Call MCP tool meldoc.list_workspaces via POST /mcp/v1/rpc
141
+ const response = await axios.post(`${API_URL}/mcp/v1/rpc`, {
142
+ jsonrpc: '2.0',
143
+ id: 1,
144
+ method: 'tools/call',
145
+ params: {
146
+ name: 'meldoc.list_workspaces',
147
+ arguments: {}
148
+ }
149
+ }, {
150
+ headers: {
151
+ 'Authorization': `Bearer ${tokenInfo.token}`,
152
+ 'Content-Type': 'application/json'
153
+ },
154
+ timeout: 10000,
155
+ httpsAgent: new https.Agent({ keepAlive: true })
156
+ });
157
+
158
+ if (response.data.error) {
159
+ logger.error(`Error: ${response.data.error.message}`);
160
+ process.exit(1);
161
+ }
162
+
163
+ const workspaces = response.data.result?.workspaces || [];
164
+ if (workspaces.length === 0) {
165
+ logger.info('No workspaces available');
166
+ process.exit(0);
167
+ }
168
+
169
+ logger.section('📁 Available Workspaces');
170
+ for (const ws of workspaces) {
171
+ const role = ws.role || 'member';
172
+ const roleColor = role === 'owner' ? chalk.red : role === 'admin' ? chalk.yellow : chalk.gray;
173
+ logger.item(
174
+ `${logger.highlight(ws.alias)} ${chalk.gray('(' + ws.name + ')')}`,
175
+ roleColor(`[${role}]`)
176
+ );
177
+ }
178
+ console.log();
179
+
180
+ process.exit(0);
181
+ } catch (error) {
182
+ if (error.response?.data?.error) {
183
+ const errorData = error.response.data.error;
184
+ if (errorData.code === 'AUTH_REQUIRED' || errorData.data?.code === 'AUTH_REQUIRED') {
185
+ logger.error('Not authenticated');
186
+ console.log('\n' + logger.label('To authenticate, run:'));
187
+ console.log(' ' + logger.highlight('npx @meldoc/mcp auth login') + '\n');
188
+ process.exit(1);
189
+ }
190
+ logger.error(`Error: ${errorData.message || error.message}`);
191
+ } else {
192
+ logger.error(`Error: ${error.message}`);
193
+ }
194
+ process.exit(1);
195
+ }
196
+ }
197
+
198
+ /**
199
+ * Handle help command
200
+ */
201
+ function handleHelp() {
202
+ console.log('\n' + logger.section('📖 Meldoc MCP CLI Help'));
203
+ console.log();
204
+
205
+ console.log(logger.label('Available Commands:'));
206
+ console.log();
207
+
208
+ console.log(' ' + logger.highlight('auth login'));
209
+ console.log(' Authenticate with Meldoc using device flow');
210
+ console.log();
211
+
212
+ console.log(' ' + logger.highlight('auth status'));
213
+ console.log(' Check authentication status');
214
+ console.log();
215
+
216
+ console.log(' ' + logger.highlight('auth logout'));
217
+ console.log(' Log out and clear credentials');
218
+ console.log();
219
+
220
+ console.log(' ' + logger.highlight('config set-workspace <alias>'));
221
+ console.log(' Set the active workspace alias');
222
+ console.log();
223
+
224
+ console.log(' ' + logger.highlight('config get-workspace'));
225
+ console.log(' Get the current workspace alias');
226
+ console.log();
227
+
228
+ console.log(' ' + logger.highlight('config list-workspaces'));
229
+ console.log(' List all available workspaces');
230
+ console.log();
231
+
232
+ console.log(' ' + logger.highlight('help'));
233
+ console.log(' Show this help message');
234
+ console.log();
235
+
236
+ console.log(logger.label('Examples:'));
237
+ console.log(' ' + logger.highlight('npx @meldoc/mcp auth login'));
238
+ console.log(' ' + logger.highlight('npx @meldoc/mcp config set-workspace my-workspace'));
239
+ console.log(' ' + logger.highlight('npx @meldoc/mcp config list-workspaces'));
240
+ console.log();
241
+
242
+ process.exit(0);
243
+ }
244
+
245
+ /**
246
+ * Show usage hints when no arguments provided
247
+ */
248
+ function showUsageHints() {
249
+ console.log('\n' + logger.section('🔧 Meldoc MCP CLI'));
250
+ console.log();
251
+ console.log(logger.label('Available commands:'));
252
+ console.log(' ' + logger.highlight('auth login') + ' - Authenticate with Meldoc');
253
+ console.log(' ' + logger.highlight('auth status') + ' - Check authentication status');
254
+ console.log(' ' + logger.highlight('auth logout') + ' - Log out');
255
+ console.log(' ' + logger.highlight('config set-workspace') + ' - Set workspace alias');
256
+ console.log(' ' + logger.highlight('config get-workspace') + ' - Get current workspace');
257
+ console.log(' ' + logger.highlight('config list-workspaces') + ' - List workspaces');
258
+ console.log(' ' + logger.highlight('help') + ' - Show detailed help');
259
+ console.log();
260
+ console.log(logger.label('For more information, run:'));
261
+ console.log(' ' + logger.highlight('npx @meldoc/mcp help') + '\n');
262
+ process.exit(0);
263
+ }
264
+
265
+ /**
266
+ * Main CLI handler
267
+ */
268
+ function main() {
269
+ const args = process.argv.slice(2);
270
+
271
+ if (args.length === 0) {
272
+ // No arguments - show usage hints
273
+ showUsageHints();
274
+ return;
275
+ }
276
+
277
+ const command = args[0];
278
+ const subcommand = args[1];
279
+ const value = args[2];
280
+
281
+ if (command === 'help' || command === '--help' || command === '-h') {
282
+ handleHelp();
283
+ } else if (command === 'auth') {
284
+ if (subcommand === 'login') {
285
+ handleAuthLogin();
286
+ } else if (subcommand === 'status') {
287
+ handleAuthStatus();
288
+ } else if (subcommand === 'logout') {
289
+ handleAuthLogout();
290
+ } else {
291
+ logger.error(`Unknown auth command: ${subcommand}`);
292
+ console.log('\n' + logger.label('Usage:'));
293
+ console.log(' ' + logger.highlight('npx @meldoc/mcp auth <login|status|logout>') + '\n');
294
+ process.exit(1);
295
+ }
296
+ } else if (command === 'config') {
297
+ if (subcommand === 'set-workspace') {
298
+ handleConfigSetWorkspace(value);
299
+ } else if (subcommand === 'get-workspace') {
300
+ handleConfigGetWorkspace();
301
+ } else if (subcommand === 'list-workspaces') {
302
+ handleConfigListWorkspaces();
303
+ } else {
304
+ logger.error(`Unknown config command: ${subcommand}`);
305
+ console.log('\n' + logger.label('Usage:'));
306
+ console.log(' ' + logger.highlight('npx @meldoc/mcp config <set-workspace|get-workspace|list-workspaces>') + '\n');
307
+ process.exit(1);
308
+ }
309
+ } else {
310
+ // Unknown command - might be for main proxy
311
+ // Return control to main proxy handler
312
+ return;
313
+ }
314
+ }
315
+
316
+ // Run main when this file is required (called from main proxy)
317
+ // main() will handle commands and exit, so this is safe to call
318
+ main();
319
+
320
+ module.exports = {
321
+ handleAuthLogin,
322
+ handleAuthStatus,
323
+ handleAuthLogout,
324
+ handleConfigSetWorkspace,
325
+ handleConfigGetWorkspace,
326
+ handleConfigListWorkspaces
327
+ };