@meldocio/mcp-stdio-proxy 1.0.28 → 1.1.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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +3 -3
- package/bin/cli.js +2 -1
- package/bin/meldoc-mcp-proxy.js +178 -134
- package/lib/cli/commands.js +19 -8
- package/lib/core/auth.js +35 -16
- package/lib/core/oauth-pkce.js +279 -0
- package/lib/http/proxy.js +230 -0
- package/lib/mcp/handlers.js +16 -165
- package/lib/mcp/tools-call.js +16 -18
- package/lib/protocol/tools-schema.js +15 -169
- package/package.json +1 -1
package/lib/mcp/tools-call.js
CHANGED
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
* Local tools: set_workspace, get_workspace, auth_status, auth_login_instructions
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
const { sendResponse
|
|
9
|
-
const { JSON_RPC_ERROR_CODES } = require('../protocol/error-codes');
|
|
8
|
+
const { sendResponse } = require('../protocol/json-rpc');
|
|
10
9
|
const { getAuthStatus } = require('../core/auth');
|
|
11
10
|
const { setWorkspaceAlias, getWorkspaceAlias } = require('../core/config');
|
|
12
11
|
const { LOG_LEVELS } = require('../core/constants');
|
|
@@ -37,14 +36,16 @@ function log(level, message) {
|
|
|
37
36
|
* @returns {Object} MCP result object
|
|
38
37
|
*/
|
|
39
38
|
function createToolResponse(text) {
|
|
40
|
-
return {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
39
|
+
return { content: [{ type: 'text', text }] };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Create MCP tool error response (isError: true per MCP spec)
|
|
44
|
+
* @param {string} message - Error message
|
|
45
|
+
* @returns {Object} MCP result object
|
|
46
|
+
*/
|
|
47
|
+
function createToolError(message) {
|
|
48
|
+
return { isError: true, content: [{ type: 'text', text: message }] };
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/**
|
|
@@ -55,7 +56,7 @@ function createToolResponse(text) {
|
|
|
55
56
|
function handleSetWorkspace(request, arguments_) {
|
|
56
57
|
const alias = arguments_.alias;
|
|
57
58
|
if (!alias || typeof alias !== 'string') {
|
|
58
|
-
|
|
59
|
+
sendResponse(request.id, createToolError('alias parameter is required and must be a string'));
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
61
62
|
|
|
@@ -63,7 +64,7 @@ function handleSetWorkspace(request, arguments_) {
|
|
|
63
64
|
setWorkspaceAlias(alias);
|
|
64
65
|
sendResponse(request.id, createToolResponse(`Workspace alias set to: ${alias}`));
|
|
65
66
|
} catch (error) {
|
|
66
|
-
|
|
67
|
+
sendResponse(request.id, createToolError(`Failed to set workspace alias: ${error.message}`));
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
@@ -81,7 +82,7 @@ function handleGetWorkspace(request) {
|
|
|
81
82
|
};
|
|
82
83
|
sendResponse(request.id, createToolResponse(JSON.stringify(result, null, 2)));
|
|
83
84
|
} catch (error) {
|
|
84
|
-
|
|
85
|
+
sendResponse(request.id, createToolError(`Failed to get workspace: ${error.message}`));
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
@@ -103,7 +104,7 @@ async function handleAuthStatus(request) {
|
|
|
103
104
|
|
|
104
105
|
sendResponse(request.id, createToolResponse(JSON.stringify(authStatus, null, 2)));
|
|
105
106
|
} catch (error) {
|
|
106
|
-
|
|
107
|
+
sendResponse(request.id, createToolError(`Failed to get auth status: ${error.message}`));
|
|
107
108
|
}
|
|
108
109
|
}
|
|
109
110
|
|
|
@@ -165,10 +166,7 @@ async function handleToolsCall(request) {
|
|
|
165
166
|
return true; // Handled
|
|
166
167
|
} catch (error) {
|
|
167
168
|
log(LOG_LEVELS.ERROR, `Unexpected error in handleToolsCall: ${error.message || 'Unknown error'}`);
|
|
168
|
-
|
|
169
|
-
`Error executing tool: ${error.message || 'Unknown error'}`, {
|
|
170
|
-
code: 'INTERNAL_ERROR'
|
|
171
|
-
});
|
|
169
|
+
sendResponse(request.id, createToolError(`Error executing tool: ${error.message || 'Unknown error'}`));
|
|
172
170
|
return true; // Error handled
|
|
173
171
|
}
|
|
174
172
|
}
|
|
@@ -1,179 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tools Schema Definitions
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Contains only the local tools handled by this proxy.
|
|
5
|
+
* All other tools are provided by the server-side MCP via tools/list forwarding.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
10
|
-
* @returns {Array<Object>} Array of tool definitions
|
|
9
|
+
* Local tools handled directly by this proxy (not forwarded to the server).
|
|
10
|
+
* @returns {Array<Object>} Array of local tool definitions
|
|
11
11
|
*/
|
|
12
|
-
function
|
|
12
|
+
function getLocalToolsList() {
|
|
13
13
|
return [
|
|
14
|
-
{
|
|
15
|
-
name: 'docs_list',
|
|
16
|
-
description: 'List documents in workspace/project. For public tokens, only shows published public documents.',
|
|
17
|
-
inputSchema: {
|
|
18
|
-
type: 'object',
|
|
19
|
-
properties: {
|
|
20
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
21
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
22
|
-
projectId: { type: 'string', description: 'UUID of the project to list documents from' },
|
|
23
|
-
cursor: { type: 'string', description: 'Pagination cursor' },
|
|
24
|
-
limit: { type: 'integer', description: 'Maximum number of documents to return (default: 50, max: 100)' }
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
name: 'docs_get',
|
|
30
|
-
description: 'Get a specific document by ID or path. For public tokens, allows access to public and unlisted documents.',
|
|
31
|
-
inputSchema: {
|
|
32
|
-
type: 'object',
|
|
33
|
-
required: ['docId'],
|
|
34
|
-
properties: {
|
|
35
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
36
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
37
|
-
docId: { type: 'string', description: 'UUID of the document (alias: id)' },
|
|
38
|
-
id: { type: 'string', description: 'UUID of the document (alias for docId)' },
|
|
39
|
-
path: { type: 'string', description: 'Path of the document (not yet implemented)' }
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: 'docs_tree',
|
|
45
|
-
description: 'Get the document tree structure for a project. For public tokens, only includes published public documents.',
|
|
46
|
-
inputSchema: {
|
|
47
|
-
type: 'object',
|
|
48
|
-
required: ['projectId'],
|
|
49
|
-
properties: {
|
|
50
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
51
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
52
|
-
projectId: { type: 'string', description: 'UUID of the project' },
|
|
53
|
-
project_alias: { type: 'string', description: 'Alias of the project (alternative to projectId)' }
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: 'docs_search',
|
|
59
|
-
description: 'Search documents by text query. For public tokens, only searches published public documents.',
|
|
60
|
-
inputSchema: {
|
|
61
|
-
type: 'object',
|
|
62
|
-
required: ['query'],
|
|
63
|
-
properties: {
|
|
64
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
65
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
66
|
-
query: { type: 'string', description: 'Search query text' },
|
|
67
|
-
projectId: { type: 'string', description: 'UUID of the project to search in' },
|
|
68
|
-
limit: { type: 'integer', description: 'Maximum number of results (default: 20, max: 50)' }
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
name: 'docs_update',
|
|
74
|
-
description: 'Update a document\'s content and/or metadata. Requires update permission (internal tokens only).',
|
|
75
|
-
inputSchema: {
|
|
76
|
-
type: 'object',
|
|
77
|
-
required: ['docId'],
|
|
78
|
-
properties: {
|
|
79
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
80
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
81
|
-
docId: { type: 'string', description: 'UUID of the document to update' },
|
|
82
|
-
contentMd: { type: 'string', description: 'New markdown content for the document (optional, can update individual fields without content)' },
|
|
83
|
-
title: { type: 'string', description: 'New title for the document' },
|
|
84
|
-
alias: { type: 'string', description: 'New alias for the document' },
|
|
85
|
-
parentAlias: { type: 'string', description: 'Alias of the parent document (set to empty string to remove parent)' },
|
|
86
|
-
workflow: { type: 'string', enum: ['published', 'draft'], description: 'Workflow status: \'published\' or \'draft\'' },
|
|
87
|
-
visibility: { type: 'string', enum: ['visible', 'hidden'], description: 'Visibility: \'visible\' or \'hidden\'' },
|
|
88
|
-
exposure: { type: 'string', enum: ['private', 'unlisted', 'public', 'inherit'], description: 'Exposure level: \'private\', \'unlisted\', \'public\', or \'inherit\'' },
|
|
89
|
-
expectedUpdatedAt: { type: 'string', description: 'Expected updatedAt timestamp for optimistic locking (RFC3339 format)' }
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'docs_create',
|
|
95
|
-
description: 'Create a new document. Requires create permission (internal tokens only).',
|
|
96
|
-
inputSchema: {
|
|
97
|
-
type: 'object',
|
|
98
|
-
required: ['projectId', 'title', 'contentMd'],
|
|
99
|
-
properties: {
|
|
100
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
101
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
102
|
-
projectId: { type: 'string', description: 'UUID of the project to create the document in' },
|
|
103
|
-
title: { type: 'string', description: 'Title of the document' },
|
|
104
|
-
contentMd: { type: 'string', description: 'Markdown content for the document' },
|
|
105
|
-
alias: { type: 'string', description: 'Alias for the document (will be auto-generated from title if not provided)' },
|
|
106
|
-
parentAlias: { type: 'string', description: 'Alias of the parent document' }
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
name: 'docs_delete',
|
|
112
|
-
description: 'Delete a document. Requires delete permission (internal tokens only).',
|
|
113
|
-
inputSchema: {
|
|
114
|
-
type: 'object',
|
|
115
|
-
required: ['docId'],
|
|
116
|
-
properties: {
|
|
117
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
118
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
119
|
-
docId: { type: 'string', description: 'UUID of the document to delete' }
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
name: 'docs_links',
|
|
125
|
-
description: 'Get all outgoing links from a document (links that point from this document to other documents).',
|
|
126
|
-
inputSchema: {
|
|
127
|
-
type: 'object',
|
|
128
|
-
required: ['docId'],
|
|
129
|
-
properties: {
|
|
130
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
131
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' },
|
|
132
|
-
docId: { type: 'string', description: 'UUID of the document' }
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
name: 'docs_backlinks',
|
|
138
|
-
description: 'Get all backlinks to a document (links from other documents that point to this document).',
|
|
139
|
-
inputSchema: {
|
|
140
|
-
type: 'object',
|
|
141
|
-
required: ['docId'],
|
|
142
|
-
properties: {
|
|
143
|
-
docId: { type: 'string', description: 'UUID of the document' }
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
name: 'projects_list',
|
|
149
|
-
description: 'List projects accessible by this token. For public tokens, only shows public projects.',
|
|
150
|
-
inputSchema: {
|
|
151
|
-
type: 'object',
|
|
152
|
-
properties: {
|
|
153
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
154
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' }
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
{
|
|
159
|
-
name: 'server_info',
|
|
160
|
-
description: 'Get information about this MCP server\'s configuration, capabilities, and accessible projects.',
|
|
161
|
-
inputSchema: {
|
|
162
|
-
type: 'object',
|
|
163
|
-
properties: {
|
|
164
|
-
workspaceAlias: { type: 'string', description: 'Workspace alias (auto-selected if user has only one workspace)' },
|
|
165
|
-
workspaceId: { type: 'string', description: 'Workspace UUID (auto-selected if user has only one workspace)' }
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
name: 'list_workspaces',
|
|
171
|
-
description: 'List all workspaces accessible by the current user or integration token. For integration tokens, returns the workspace from token scope. Works without workspace header via /mcp/v1/rpc endpoint.',
|
|
172
|
-
inputSchema: {
|
|
173
|
-
type: 'object',
|
|
174
|
-
properties: {}
|
|
175
|
-
}
|
|
176
|
-
},
|
|
177
14
|
{
|
|
178
15
|
name: 'get_workspace',
|
|
179
16
|
description: 'Get the current workspace alias from repo config or global config. Reads workspaceAlias from configuration files.',
|
|
@@ -212,6 +49,14 @@ function getToolsList() {
|
|
|
212
49
|
];
|
|
213
50
|
}
|
|
214
51
|
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Use getLocalToolsList() instead.
|
|
54
|
+
* Kept for backward compatibility with any code that imports getToolsList.
|
|
55
|
+
*/
|
|
56
|
+
function getToolsList() {
|
|
57
|
+
return getLocalToolsList();
|
|
58
|
+
}
|
|
59
|
+
|
|
215
60
|
/**
|
|
216
61
|
* Check if a tool name exists in the schema
|
|
217
62
|
* @param {string} toolName - The name of the tool to check
|
|
@@ -233,7 +78,8 @@ function getToolByName(toolName) {
|
|
|
233
78
|
}
|
|
234
79
|
|
|
235
80
|
module.exports = {
|
|
236
|
-
|
|
81
|
+
getLocalToolsList,
|
|
82
|
+
getToolsList, // backward compat alias for getLocalToolsList
|
|
237
83
|
isValidToolName,
|
|
238
84
|
getToolByName
|
|
239
85
|
};
|
package/package.json
CHANGED