@majkapp/majk-chat-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/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,287 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
38
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
39
+ const commander_1 = require("commander");
40
+ const fs = __importStar(require("fs"));
41
+ const child_process_1 = require("child_process");
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const program = new commander_1.Command();
45
+ program
46
+ .name('majk-mcp-server')
47
+ .description('Standalone MCP server for dynamic command execution')
48
+ .version('1.0.0');
49
+ program
50
+ .command('serve')
51
+ .description('Start MCP server in stdio mode')
52
+ .option('-c, --config <file>', 'Configuration file path')
53
+ .option('--config-json <json>', 'Configuration as JSON string')
54
+ .action(async (options) => {
55
+ try {
56
+ let config;
57
+ if (options.config) {
58
+ const configData = await fs.promises.readFile(options.config, 'utf-8');
59
+ config = JSON.parse(configData);
60
+ }
61
+ else if (options.configJson) {
62
+ config = JSON.parse(options.configJson);
63
+ }
64
+ else {
65
+ console.error('Error: Must provide either --config or --config-json');
66
+ process.exit(1);
67
+ }
68
+ await startMCPServer(config);
69
+ }
70
+ catch (error) {
71
+ console.error('Error:', error instanceof Error ? error.message : error);
72
+ process.exit(1);
73
+ }
74
+ });
75
+ program
76
+ .command('validate')
77
+ .description('Validate configuration file')
78
+ .option('-c, --config <file>', 'Configuration file path')
79
+ .option('--config-json <json>', 'Configuration as JSON string')
80
+ .action(async (options) => {
81
+ try {
82
+ let config;
83
+ if (options.config) {
84
+ const configData = await fs.promises.readFile(options.config, 'utf-8');
85
+ config = JSON.parse(configData);
86
+ }
87
+ else if (options.configJson) {
88
+ config = JSON.parse(options.configJson);
89
+ }
90
+ else {
91
+ console.error('Error: Must provide either --config or --config-json');
92
+ process.exit(1);
93
+ }
94
+ validateConfig(config);
95
+ console.log('✅ Configuration is valid');
96
+ // List discovered tools
97
+ console.log('\nDiscovered tools:');
98
+ for (const cmd of config.commands) {
99
+ console.log(` - ${cmd.name}: ${cmd.description}`);
100
+ }
101
+ }
102
+ catch (error) {
103
+ console.error('❌ Configuration error:', error instanceof Error ? error.message : error);
104
+ process.exit(1);
105
+ }
106
+ });
107
+ async function startMCPServer(config) {
108
+ validateConfig(config);
109
+ const server = new index_js_1.Server({
110
+ name: 'majk-dynamic-mcp-server',
111
+ version: '1.0.0'
112
+ }, {
113
+ capabilities: {
114
+ tools: {}
115
+ }
116
+ });
117
+ // Handle tools/list requests
118
+ server.setRequestHandler('tools/list', async () => {
119
+ return {
120
+ tools: config.commands.map(cmd => ({
121
+ name: cmd.name,
122
+ description: cmd.description,
123
+ inputSchema: cmd.parameters
124
+ }))
125
+ };
126
+ });
127
+ // Handle tools/call requests
128
+ server.setRequestHandler('tools/call', async (request) => {
129
+ const toolName = request.params?.name;
130
+ const toolArgs = request.params?.arguments || {};
131
+ const command = config.commands.find(cmd => cmd.name === toolName);
132
+ if (!command) {
133
+ throw new Error(`Unknown tool: ${toolName}`);
134
+ }
135
+ return await executeCommand(command, toolArgs);
136
+ });
137
+ const transport = new stdio_js_1.StdioServerTransport();
138
+ await server.connect(transport);
139
+ console.error(`MCP server started with ${config.commands.length} tools`);
140
+ }
141
+ async function executeCommand(command, args) {
142
+ // Resolve template variables
143
+ const resolvedPath = resolveTemplate(command.exec.path, args);
144
+ const resolvedArgs = command.exec.args
145
+ .map(arg => resolveTemplate(arg, args))
146
+ .filter(arg => arg.length > 0);
147
+ // Prepare environment
148
+ const env = {
149
+ ...process.env,
150
+ ...resolveEnv(command.exec.env || {}, args)
151
+ };
152
+ // Resolve working directory
153
+ const cwd = command.exec.cwd
154
+ ? resolvePath(command.exec.cwd)
155
+ : process.cwd();
156
+ const timeout = command.exec.timeoutMs || 30000;
157
+ const expectFormat = command.exec.expect || 'text';
158
+ try {
159
+ const result = await executeShellCommand(resolvedPath, resolvedArgs, { env, cwd, timeout });
160
+ if (result.code !== 0) {
161
+ throw new Error(`Command failed with exit code ${result.code}: ${result.stderr}`);
162
+ }
163
+ let output;
164
+ if (expectFormat === 'json') {
165
+ try {
166
+ output = JSON.parse(result.stdout);
167
+ }
168
+ catch (e) {
169
+ throw new Error(`Failed to parse JSON output: ${e}. Raw output: ${result.stdout}`);
170
+ }
171
+ }
172
+ else {
173
+ output = result.stdout;
174
+ }
175
+ return {
176
+ content: [{
177
+ type: 'text',
178
+ text: typeof output === 'string' ? output : JSON.stringify(output, null, 2)
179
+ }]
180
+ };
181
+ }
182
+ catch (error) {
183
+ throw new Error(error instanceof Error ? error.message : String(error));
184
+ }
185
+ }
186
+ function resolveTemplate(template, args) {
187
+ let result = template;
188
+ // Handle conditionals: {{#if variable}}text{{/if}}
189
+ result = result.replace(/\{\{#if\s+(\w+)\}\}([^{]*?)\{\{\/if\}\}/g, (match, variable, content) => {
190
+ return args[variable] ? content : '';
191
+ });
192
+ // Handle each loops: {{#each array}}{{this}}{{/each}}
193
+ result = result.replace(/\{\{#each\s+(\w+)\}\}([^{]*?)\{\{\/each\}\}/g, (match, variable, content) => {
194
+ const array = args[variable];
195
+ if (Array.isArray(array)) {
196
+ return array.map(item => content.replace(/\{\{this\}\}/g, String(item))).join(' ');
197
+ }
198
+ return '';
199
+ });
200
+ // Handle simple variables: {{variable}}
201
+ result = result.replace(/\{\{(\w+)\}\}/g, (match, variable) => {
202
+ return args[variable] !== undefined ? String(args[variable]) : '';
203
+ });
204
+ return result;
205
+ }
206
+ function resolveEnv(envConfig, args) {
207
+ const resolved = {};
208
+ for (const [key, value] of Object.entries(envConfig)) {
209
+ let resolvedValue = value;
210
+ // Replace $VAR with process.env.VAR
211
+ resolvedValue = resolvedValue.replace(/\$(\w+)/g, (match, varName) => {
212
+ return process.env[varName] || '';
213
+ });
214
+ // Replace template variables
215
+ resolvedValue = resolveTemplate(resolvedValue, args);
216
+ resolved[key] = resolvedValue;
217
+ }
218
+ return resolved;
219
+ }
220
+ function resolvePath(inputPath) {
221
+ if (inputPath.startsWith('~')) {
222
+ return path.join(os.homedir(), inputPath.slice(1));
223
+ }
224
+ return path.resolve(inputPath);
225
+ }
226
+ function executeShellCommand(command, args, options) {
227
+ return new Promise((resolve, reject) => {
228
+ const child = (0, child_process_1.spawn)(command, args, {
229
+ env: options.env,
230
+ cwd: options.cwd,
231
+ stdio: ['pipe', 'pipe', 'pipe']
232
+ });
233
+ let stdout = '';
234
+ let stderr = '';
235
+ child.stdout?.on('data', (data) => {
236
+ stdout += data.toString();
237
+ });
238
+ child.stderr?.on('data', (data) => {
239
+ stderr += data.toString();
240
+ });
241
+ const timeout = setTimeout(() => {
242
+ child.kill('SIGKILL');
243
+ reject(new Error(`Command timed out after ${options.timeout}ms`));
244
+ }, options.timeout);
245
+ child.on('close', (code) => {
246
+ clearTimeout(timeout);
247
+ resolve({
248
+ code: code || 0,
249
+ stdout: stdout.trim(),
250
+ stderr: stderr.trim()
251
+ });
252
+ });
253
+ child.on('error', (error) => {
254
+ clearTimeout(timeout);
255
+ reject(error);
256
+ });
257
+ });
258
+ }
259
+ function validateConfig(config) {
260
+ if (!Array.isArray(config.commands)) {
261
+ throw new Error('Config must have a "commands" array');
262
+ }
263
+ for (const cmd of config.commands) {
264
+ if (!cmd.name || typeof cmd.name !== 'string') {
265
+ throw new Error('Command missing required field: name');
266
+ }
267
+ if (!cmd.description || typeof cmd.description !== 'string') {
268
+ throw new Error(`Command "${cmd.name}" missing required field: description`);
269
+ }
270
+ if (!cmd.parameters || typeof cmd.parameters !== 'object') {
271
+ throw new Error(`Command "${cmd.name}" missing required field: parameters`);
272
+ }
273
+ if (!cmd.exec || typeof cmd.exec !== 'object') {
274
+ throw new Error(`Command "${cmd.name}" missing required field: exec`);
275
+ }
276
+ if (!cmd.exec.path || typeof cmd.exec.path !== 'string') {
277
+ throw new Error(`Command "${cmd.name}" exec missing required field: path`);
278
+ }
279
+ if (!Array.isArray(cmd.exec.args)) {
280
+ throw new Error(`Command "${cmd.name}" exec.args must be an array`);
281
+ }
282
+ }
283
+ }
284
+ // Parse and execute
285
+ if (require.main === module) {
286
+ program.parse(process.argv);
287
+ }
@@ -0,0 +1,22 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { MCPServerConfig } from '../types/config';
4
+ import { ChildProcess } from 'child_process';
5
+ export interface MCPConnection {
6
+ client: Client;
7
+ transport: StdioClientTransport;
8
+ process: ChildProcess;
9
+ serverName: string;
10
+ }
11
+ export declare class MCPClient {
12
+ private quiet;
13
+ private connections;
14
+ constructor(quiet?: boolean);
15
+ connect(serverName: string, config: MCPServerConfig): Promise<MCPConnection>;
16
+ disconnect(serverName: string): Promise<void>;
17
+ disconnectAll(): Promise<void>;
18
+ getConnection(serverName: string): MCPConnection | undefined;
19
+ getAllConnections(): MCPConnection[];
20
+ private resolveArgs;
21
+ }
22
+ //# sourceMappingURL=mcp-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client.d.ts","sourceRoot":"","sources":["../../src/client/mcp-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAS,YAAY,EAAE,MAAM,eAAe,CAAC;AAIpD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,oBAAoB,CAAC;IAChC,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,SAAS;IAGR,OAAO,CAAC,KAAK;IAFzB,OAAO,CAAC,WAAW,CAAyC;gBAExC,KAAK,GAAE,OAAe;IAEpC,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,aAAa,CAAC;IAiE5E,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7C,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAOpC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI5D,iBAAiB,IAAI,aAAa,EAAE;IAIpC,OAAO,CAAC,WAAW;CAQpB"}
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MCPClient = void 0;
37
+ const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
38
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
39
+ const child_process_1 = require("child_process");
40
+ const path = __importStar(require("path"));
41
+ const os = __importStar(require("os"));
42
+ class MCPClient {
43
+ constructor(quiet = false) {
44
+ this.quiet = quiet;
45
+ this.connections = new Map();
46
+ }
47
+ async connect(serverName, config) {
48
+ if (this.connections.has(serverName)) {
49
+ return this.connections.get(serverName);
50
+ }
51
+ const args = this.resolveArgs(config.args);
52
+ const processEnv = process.env;
53
+ const configEnv = config.env || {};
54
+ const env = {};
55
+ // Merge environment variables, filtering out undefined values
56
+ for (const [key, value] of Object.entries(processEnv)) {
57
+ if (value !== undefined) {
58
+ env[key] = value;
59
+ }
60
+ }
61
+ for (const [key, value] of Object.entries(configEnv)) {
62
+ if (value !== undefined) {
63
+ env[key] = value;
64
+ }
65
+ }
66
+ const childProcess = (0, child_process_1.spawn)(config.command, args, {
67
+ env,
68
+ stdio: ['pipe', 'pipe', 'pipe']
69
+ });
70
+ childProcess.on('error', (error) => {
71
+ if (!this.quiet) {
72
+ console.error(`MCP server "${serverName}" process error:`, error);
73
+ }
74
+ });
75
+ childProcess.stderr?.on('data', (data) => {
76
+ if (!this.quiet) {
77
+ console.error(`MCP server "${serverName}" stderr:`, data.toString());
78
+ }
79
+ });
80
+ const transport = new stdio_js_1.StdioClientTransport({
81
+ command: config.command,
82
+ args: args,
83
+ env: env
84
+ });
85
+ const client = new index_js_1.Client({
86
+ name: `majk-chat-mcp-${serverName}`,
87
+ version: '1.0.0'
88
+ }, {
89
+ capabilities: {}
90
+ });
91
+ await client.connect(transport);
92
+ const connection = {
93
+ client,
94
+ transport,
95
+ process: childProcess,
96
+ serverName
97
+ };
98
+ this.connections.set(serverName, connection);
99
+ return connection;
100
+ }
101
+ async disconnect(serverName) {
102
+ const connection = this.connections.get(serverName);
103
+ if (!connection) {
104
+ return;
105
+ }
106
+ try {
107
+ await connection.client.close();
108
+ }
109
+ catch (error) {
110
+ if (!this.quiet) {
111
+ console.error(`Error closing MCP client for "${serverName}":`, error);
112
+ }
113
+ }
114
+ connection.process.kill();
115
+ this.connections.delete(serverName);
116
+ }
117
+ async disconnectAll() {
118
+ const disconnectPromises = Array.from(this.connections.keys()).map(serverName => this.disconnect(serverName));
119
+ await Promise.all(disconnectPromises);
120
+ }
121
+ getConnection(serverName) {
122
+ return this.connections.get(serverName);
123
+ }
124
+ getAllConnections() {
125
+ return Array.from(this.connections.values());
126
+ }
127
+ resolveArgs(args) {
128
+ return args.map(arg => {
129
+ if (arg.startsWith('~')) {
130
+ return path.join(os.homedir(), arg.slice(1));
131
+ }
132
+ return arg;
133
+ });
134
+ }
135
+ }
136
+ exports.MCPClient = MCPClient;
@@ -0,0 +1,14 @@
1
+ import { MCPConfig, MCPServerConfig, MCPServerConfigType, DynamicServerConfig, MCPPluginOptions, ParsedPermissionTool } from '../types/config';
2
+ export { ParsedPermissionTool };
3
+ export declare class MCPConfigParser {
4
+ static parseConfig(options: MCPPluginOptions): MCPConfig;
5
+ static parsePermissionTool(toolName: string): ParsedPermissionTool | null;
6
+ static formatToolName(serverName: string, toolName: string): string;
7
+ private static resolvePath;
8
+ private static mergeConfigs;
9
+ static validateServerConfig(name: string, config: MCPServerConfigType): void;
10
+ static validateTraditionalServerConfig(name: string, config: MCPServerConfig): void;
11
+ static validateDynamicServerConfig(name: string, config: DynamicServerConfig): void;
12
+ static isDynamicServer(config: MCPServerConfigType): config is DynamicServerConfig;
13
+ }
14
+ //# sourceMappingURL=parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/config/parser.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EACT,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAEhC,qBAAa,eAAe;IAC1B,MAAM,CAAC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS;IAwBxD,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAezE,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAMnE,OAAO,CAAC,MAAM,CAAC,WAAW;IAO1B,OAAO,CAAC,MAAM,CAAC,YAAY;IAS3B,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAU5E,MAAM,CAAC,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI;IAYnF,MAAM,CAAC,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,GAAG,IAAI;IA2BnF,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,IAAI,mBAAmB;CAGnF"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MCPConfigParser = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ class MCPConfigParser {
41
+ static parseConfig(options) {
42
+ let config = { mcpServers: {} };
43
+ if (options.configPath) {
44
+ const resolvedPath = this.resolvePath(options.configPath);
45
+ if (fs.existsSync(resolvedPath)) {
46
+ const fileContent = fs.readFileSync(resolvedPath, 'utf-8');
47
+ const parsedConfig = JSON.parse(fileContent);
48
+ config = this.mergeConfigs(config, parsedConfig);
49
+ }
50
+ }
51
+ if (options.configString) {
52
+ const parsedConfig = JSON.parse(options.configString);
53
+ config = this.mergeConfigs(config, parsedConfig);
54
+ }
55
+ if (options.servers) {
56
+ config.mcpServers = { ...config.mcpServers, ...options.servers };
57
+ }
58
+ return config;
59
+ }
60
+ static parsePermissionTool(toolName) {
61
+ // Match pattern: mcp__<server>__<tool>
62
+ // Server name can contain underscores, so we need to be careful
63
+ const match = toolName.match(/^mcp__(.+?)__(.+)$/);
64
+ if (!match) {
65
+ return null;
66
+ }
67
+ return {
68
+ serverName: match[1],
69
+ toolName: match[2].replace(/_/g, ' '),
70
+ originalName: toolName
71
+ };
72
+ }
73
+ static formatToolName(serverName, toolName) {
74
+ const sanitizedServer = serverName.replace(/[^a-zA-Z0-9]/g, '_');
75
+ const sanitizedTool = toolName.replace(/[^a-zA-Z0-9]/g, '_');
76
+ return `mcp__${sanitizedServer}__${sanitizedTool}`;
77
+ }
78
+ static resolvePath(inputPath) {
79
+ if (inputPath.startsWith('~')) {
80
+ return path.join(os.homedir(), inputPath.slice(1));
81
+ }
82
+ return path.resolve(inputPath);
83
+ }
84
+ static mergeConfigs(base, override) {
85
+ return {
86
+ mcpServers: {
87
+ ...base.mcpServers,
88
+ ...override.mcpServers
89
+ }
90
+ };
91
+ }
92
+ static validateServerConfig(name, config) {
93
+ if ('commands' in config) {
94
+ // Dynamic server config
95
+ this.validateDynamicServerConfig(name, config);
96
+ }
97
+ else {
98
+ // Traditional MCP server config
99
+ this.validateTraditionalServerConfig(name, config);
100
+ }
101
+ }
102
+ static validateTraditionalServerConfig(name, config) {
103
+ if (!config.command) {
104
+ throw new Error(`MCP server "${name}" missing required field: command`);
105
+ }
106
+ if (!Array.isArray(config.args)) {
107
+ throw new Error(`MCP server "${name}" args must be an array`);
108
+ }
109
+ if (config.env && typeof config.env !== 'object') {
110
+ throw new Error(`MCP server "${name}" env must be an object`);
111
+ }
112
+ }
113
+ static validateDynamicServerConfig(name, config) {
114
+ if (!Array.isArray(config.commands)) {
115
+ throw new Error(`Dynamic MCP server "${name}" commands must be an array`);
116
+ }
117
+ for (const cmd of config.commands) {
118
+ if (!cmd.name || typeof cmd.name !== 'string') {
119
+ throw new Error(`Dynamic MCP server "${name}" command missing required field: name`);
120
+ }
121
+ if (!cmd.description || typeof cmd.description !== 'string') {
122
+ throw new Error(`Dynamic MCP server "${name}" command "${cmd.name}" missing required field: description`);
123
+ }
124
+ if (!cmd.parameters || typeof cmd.parameters !== 'object') {
125
+ throw new Error(`Dynamic MCP server "${name}" command "${cmd.name}" missing required field: parameters`);
126
+ }
127
+ if (!cmd.exec || typeof cmd.exec !== 'object') {
128
+ throw new Error(`Dynamic MCP server "${name}" command "${cmd.name}" missing required field: exec`);
129
+ }
130
+ if (!cmd.exec.path || typeof cmd.exec.path !== 'string') {
131
+ throw new Error(`Dynamic MCP server "${name}" command "${cmd.name}" exec missing required field: path`);
132
+ }
133
+ if (!Array.isArray(cmd.exec.args)) {
134
+ throw new Error(`Dynamic MCP server "${name}" command "${cmd.name}" exec.args must be an array`);
135
+ }
136
+ }
137
+ }
138
+ static isDynamicServer(config) {
139
+ return 'commands' in config;
140
+ }
141
+ }
142
+ exports.MCPConfigParser = MCPConfigParser;
@@ -0,0 +1,9 @@
1
+ export { MCPPlugin } from './plugin';
2
+ export { MCPClient, MCPConnection } from './client/mcp-client';
3
+ export { MCPConfigParser } from './config/parser';
4
+ export { MCPToolExecutor } from './tools/mcp-tool-executor';
5
+ export { DynamicCommandExecutor } from './tools/dynamic-executor';
6
+ export { ToolFilter } from './tools/tool-filter';
7
+ export { MCPPermissionHandler, PermissionResult } from './tools/permission-handler';
8
+ export * from './types/config';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACpF,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.MCPPermissionHandler = exports.ToolFilter = exports.DynamicCommandExecutor = exports.MCPToolExecutor = exports.MCPConfigParser = exports.MCPClient = exports.MCPPlugin = void 0;
18
+ var plugin_1 = require("./plugin");
19
+ Object.defineProperty(exports, "MCPPlugin", { enumerable: true, get: function () { return plugin_1.MCPPlugin; } });
20
+ var mcp_client_1 = require("./client/mcp-client");
21
+ Object.defineProperty(exports, "MCPClient", { enumerable: true, get: function () { return mcp_client_1.MCPClient; } });
22
+ var parser_1 = require("./config/parser");
23
+ Object.defineProperty(exports, "MCPConfigParser", { enumerable: true, get: function () { return parser_1.MCPConfigParser; } });
24
+ var mcp_tool_executor_1 = require("./tools/mcp-tool-executor");
25
+ Object.defineProperty(exports, "MCPToolExecutor", { enumerable: true, get: function () { return mcp_tool_executor_1.MCPToolExecutor; } });
26
+ var dynamic_executor_1 = require("./tools/dynamic-executor");
27
+ Object.defineProperty(exports, "DynamicCommandExecutor", { enumerable: true, get: function () { return dynamic_executor_1.DynamicCommandExecutor; } });
28
+ var tool_filter_1 = require("./tools/tool-filter");
29
+ Object.defineProperty(exports, "ToolFilter", { enumerable: true, get: function () { return tool_filter_1.ToolFilter; } });
30
+ var permission_handler_1 = require("./tools/permission-handler");
31
+ Object.defineProperty(exports, "MCPPermissionHandler", { enumerable: true, get: function () { return permission_handler_1.MCPPermissionHandler; } });
32
+ __exportStar(require("./types/config"), exports);