├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── index.ts ├── package-lock.json ├── package.json └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | build -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # ビルドステージ 2 | FROM node:20-slim AS builder 3 | 4 | WORKDIR /app 5 | COPY package*.json ./ 6 | RUN npm install 7 | COPY . . 8 | RUN npm run build 9 | 10 | # 実行ステージ 11 | FROM node:20-slim 12 | 13 | RUN apt-get update && \ 14 | apt-get install -y --no-install-recommends \ 15 | python3-minimal \ 16 | python3-pip \ 17 | curl \ 18 | which && \ 19 | apt-get clean && \ 20 | rm -rf /var/lib/apt/lists/* && \ 21 | ln -sf /usr/bin/python3 /usr/bin/python && \ 22 | npm install -g ts-node typescript 23 | 24 | ENV PATH="/usr/local/bin:/usr/bin:/bin:${PATH}" 25 | ENV NODE_PATH="/app/node_modules" 26 | ENV PYTHONUNBUFFERED=1 27 | 28 | WORKDIR /app 29 | COPY --from=builder /app/build ./build 30 | COPY --from=builder /app/node_modules ./node_modules 31 | # package.jsonをコピーして"type": "module"設定を確実に継承 32 | COPY --from=builder /app/package*.json ./ 33 | 34 | RUN chmod +x build/index.js && \ 35 | mkdir -p /tmp/mcp-create-servers && \ 36 | chmod 777 /tmp/mcp-create-servers 37 | 38 | CMD ["node", "build/index.js"] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 tesla0225 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MCP Create Server 2 | 3 | A dynamic MCP server management service that creates, runs, and manages Model Context Protocol (MCP) servers dynamically. This service itself functions as an MCP server and launches/manages other MCP servers as child processes, enabling a flexible MCP ecosystem. 4 | 5 | 6 | Create Server MCP server 7 | 8 | 9 | ## Key Features 10 | 11 | - Dynamic creation and execution of MCP server code 12 | - Support for TypeScript only (JavaScript and Python support planned for future releases) 13 | - Tool execution on child MCP servers 14 | - Server code updates and restarts 15 | - Removal of unnecessary servers 16 | 17 | ## Installation 18 | 19 | **Note: Docker is the recommended way to run this service** 20 | 21 | ### Docker Installation (Recommended) 22 | 23 | ```bash 24 | # Build Docker image 25 | docker build -t mcp-create . 26 | 27 | # Run Docker container 28 | docker run -it --rm mcp-create 29 | ``` 30 | 31 | ### Manual Installation (TypeScript Only) 32 | 33 | ```bash 34 | # Clone repository 35 | git clone https://github.com/tesla0225/mcp-create.git 36 | cd mcp-create 37 | 38 | # Install dependencies 39 | npm install 40 | 41 | # Build 42 | npm run build 43 | 44 | # Run 45 | npm start 46 | ``` 47 | 48 | ## Integration with Claude Desktop 49 | 50 | Add the following to your Claude Desktop configuration file (`claude_desktop_config.json`): 51 | 52 | ```json 53 | { 54 | "mcpServers": { 55 | "mcp-create": { 56 | "command": "docker", 57 | "args": ["run", "-i", "--rm", "mcp-create"] 58 | } 59 | } 60 | } 61 | ``` 62 | 63 | ## Available Tools 64 | 65 | | Tool Name | Description | Input Parameters | Output | 66 | |-----------|-------------|-----------------|--------| 67 | | create-server-from-template | Create MCP server from template | language: string | { serverId: string, message: string } | 68 | | execute-tool | Execute tool on server | serverId: string
toolName: string
args: object | Tool execution result | 69 | | get-server-tools | Get list of server tools | serverId: string | { tools: ToolDefinition[] } | 70 | | delete-server | Delete server | serverId: string | { success: boolean, message: string } | 71 | | list-servers | Get list of running servers | none | { servers: string[] } | 72 | 73 | ## Usage Examples 74 | 75 | ### Creating a New Server 76 | 77 | ```json 78 | { 79 | "name": "create-server-from-template", 80 | "arguments": { 81 | "language": "typescript" 82 | } 83 | } 84 | ``` 85 | 86 | ### Executing a Tool 87 | 88 | ```json 89 | { 90 | "name": "execute-tool", 91 | "arguments": { 92 | "serverId": "ba7c9a4f-6ba8-4cad-8ec8-a41a08c19fac", 93 | "toolName": "echo", 94 | "args": { 95 | "message": "Hello, dynamic MCP server!" 96 | } 97 | } 98 | } 99 | ``` 100 | 101 | ## Technical Specifications 102 | 103 | - Node.js 18 or higher 104 | - TypeScript (required) 105 | - Dependencies: 106 | - @modelcontextprotocol/sdk: MCP client/server implementation 107 | - child_process (Node.js built-in): Child process management 108 | - fs/promises (Node.js built-in): File operations 109 | - uuid: Unique server ID generation 110 | 111 | ## Security Considerations 112 | 113 | - **Code Execution Restrictions:** Consider sandboxing as the service executes arbitrary code 114 | - **Resource Limitations:** Set limits on memory, CPU usage, number of files, etc. 115 | - **Process Monitoring:** Monitor and forcibly terminate zombie or runaway processes 116 | - **Path Validation:** Properly validate file paths to prevent directory traversal attacks 117 | 118 | ## License 119 | 120 | MIT -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 2 | import { Client } from "@modelcontextprotocol/sdk/client/index.js"; 3 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 4 | import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"; 5 | import { fileURLToPath } from "url"; 6 | import { dirname } from "path"; 7 | import { 8 | CallToolRequest, 9 | CallToolRequestSchema, 10 | ListToolsRequestSchema, 11 | Tool, 12 | } from "@modelcontextprotocol/sdk/types.js"; 13 | import { spawn, ChildProcess } from "child_process"; 14 | import * as fs from "fs/promises"; 15 | import * as path from "path"; 16 | import { v4 as uuidv4 } from "uuid"; 17 | import * as os from "os"; 18 | 19 | // Type definitions for tool arguments 20 | interface CreateServerArgs { 21 | code: string; 22 | language: "typescript" | "javascript" | "python"; 23 | } 24 | 25 | interface CreateServerFromTemplateArgs { 26 | language: "typescript" | "python"; 27 | code?: string; 28 | dependencies?: Record; // 例: { "axios": "^1.0.0" } 29 | } 30 | 31 | interface ExecuteToolArgs { 32 | serverId: string; 33 | toolName: string; 34 | args: Record; 35 | } 36 | 37 | interface GetServerToolsArgs { 38 | serverId: string; 39 | } 40 | 41 | interface UpdateServerArgs { 42 | serverId: string; 43 | code: string; 44 | } 45 | 46 | interface DeleteServerArgs { 47 | serverId: string; 48 | } 49 | 50 | interface ConnectedServer { 51 | process: ChildProcess; 52 | client: Client; 53 | transport: StdioClientTransport; 54 | language: string; 55 | filePath: string; 56 | } 57 | 58 | // Get current file path and directory in ES modules 59 | const __filename = fileURLToPath(import.meta.url); 60 | const __dirname = dirname(__filename); 61 | 62 | // コマンドの絶対パスを取得する関数を追加 63 | async function getCommandPath(command: string): Promise { 64 | try { 65 | // whichコマンドの代わりにJavaScriptで絶対パスを探す 66 | const possiblePaths = [ 67 | "/usr/local/bin", 68 | "/usr/bin", 69 | "/bin", 70 | "/usr/local/sbin", 71 | "/usr/sbin", 72 | "/sbin", 73 | ]; 74 | 75 | for (const dir of possiblePaths) { 76 | const fullPath = path.join(dir, command); 77 | try { 78 | await fs.access(fullPath, fs.constants.X_OK); 79 | console.error(`Found command ${command} at ${fullPath}`); 80 | return fullPath; 81 | } catch { 82 | // このパスにコマンドが存在しない場合は次を試す 83 | } 84 | } 85 | 86 | // コマンドが見つからない場合は元のコマンド名を返す 87 | console.error( 88 | `Command ${command} not found in standard paths, returning as is` 89 | ); 90 | return command; 91 | } catch (error) { 92 | console.error(`Error resolving path for ${command}:`, error); 93 | return command; 94 | } 95 | } 96 | 97 | // Server manager class 98 | class ServerManager { 99 | private servers: Map = new Map(); 100 | 101 | private templatesDir: string = path.join(__dirname, "templates"); 102 | private serversDir: string = path.join(os.tmpdir(), "mcp-create-servers"); 103 | 104 | constructor() { 105 | // Ensure servers directory exists 106 | this.initDirectories(); 107 | } 108 | 109 | private async initDirectories() { 110 | try { 111 | await fs.mkdir(this.serversDir, { recursive: true }); 112 | // 権限を明示的に設定(Docker内でも動作するように) 113 | await fs.chmod(this.serversDir, 0o777); 114 | console.error(`Created servers directory: ${this.serversDir}`); 115 | } catch (error) { 116 | console.error(`Error creating servers directory: ${error}`); 117 | } 118 | } 119 | 120 | // Create a new server from code 121 | async createServer( 122 | code: string, 123 | language: string, 124 | dependencies?: Record 125 | ): Promise { 126 | const serverId = uuidv4(); 127 | const serverDir = path.join(this.serversDir, serverId); 128 | 129 | try { 130 | // Create server directory 131 | await fs.mkdir(serverDir, { recursive: true }); 132 | await fs.chmod(serverDir, 0o777); // 権限を追加 133 | 134 | // 依存関係がある場合はインストール(シンボリックリンクは作成しない) 135 | if (dependencies && Object.keys(dependencies).length > 0) { 136 | await this.installDependencies(serverDir, dependencies, language); 137 | } else { 138 | // 依存関係がない場合のみシンボリックリンクを作成 139 | try { 140 | await fs.symlink( 141 | "/app/node_modules", 142 | path.join(serverDir, "node_modules") 143 | ); 144 | console.error(`Created symlink to node_modules in ${serverDir}`); 145 | } catch (error) { 146 | console.error(`Error creating symlink: ${error}`); 147 | // エラーがあっても続行する 148 | } 149 | } 150 | 151 | // Write server code to file 152 | let filePath: string; 153 | let command: string; 154 | let args: string[] = []; 155 | 156 | // 共通の環境変数設定 157 | const appNodeModules = path.resolve("/app/node_modules"); 158 | const commonEnv = { 159 | ...process.env, 160 | PATH: process.env.PATH || "/usr/local/bin:/usr/bin:/bin", 161 | NODE_PATH: appNodeModules, 162 | }; 163 | 164 | console.error(`Current PATH: ${process.env.PATH}`); 165 | console.error(`Current NODE_PATH: ${process.env.NODE_PATH}`); 166 | 167 | switch (language) { 168 | case "typescript": 169 | filePath = path.join(serverDir, "index.ts"); 170 | const jsFilePath = path.join(serverDir, "index.js"); 171 | const tsConfigPath = path.join(__dirname, "tsconfig.json"); 172 | 173 | await fs.writeFile(filePath, code); 174 | 175 | // 絶対パスを取得して出力 176 | command = await getCommandPath("npx"); 177 | console.error(`Using command path for npx: ${command}`); 178 | 179 | // TypeScriptをコンパイルする方法に変更 180 | await new Promise((resolve, reject) => { 181 | const tscCommand = "npx"; 182 | const tscArgs = [ 183 | "tsc", 184 | "--allowJs", 185 | filePath, 186 | "--outDir", 187 | serverDir, 188 | "--target", 189 | "ES2020", 190 | "--module", 191 | "NodeNext", 192 | "--moduleResolution", 193 | "NodeNext", 194 | "--esModuleInterop", 195 | "--skipLibCheck", 196 | "--resolveJsonModule", 197 | ]; 198 | 199 | 200 | console.error( 201 | `Compiling TypeScript: ${tscCommand} ${tscArgs.join(" ")}` 202 | ); 203 | 204 | const compileProcess = spawn(tscCommand, tscArgs, { 205 | stdio: ["ignore", "pipe", "pipe"], 206 | shell: true, 207 | env: commonEnv, 208 | cwd: "/app", // アプリケーションのルートディレクトリを指定 209 | }); 210 | 211 | compileProcess.stdout.on("data", (data) => { 212 | console.error(`TSC stdout: ${data}`); 213 | }); 214 | 215 | compileProcess.stderr.on("data", (data) => { 216 | console.error(`TSC stderr: ${data}`); 217 | }); 218 | 219 | compileProcess.on("exit", (code) => { 220 | if (code === 0) { 221 | console.error(`TypeScript compilation successful`); 222 | resolve(); 223 | } else { 224 | console.error( 225 | `TypeScript compilation failed with code ${code}` 226 | ); 227 | reject( 228 | new Error(`TypeScript compilation failed with code ${code}`) 229 | ); 230 | } 231 | }); 232 | }); 233 | 234 | // コンパイルされたJavaScriptを実行 235 | command = await getCommandPath("node"); 236 | args = [jsFilePath]; 237 | break; 238 | 239 | case "javascript": 240 | filePath = path.join(serverDir, "index.js"); 241 | await fs.writeFile(filePath, code); 242 | command = await getCommandPath("node"); 243 | args = [filePath]; 244 | break; 245 | 246 | case "python": 247 | filePath = path.join(serverDir, "server.py"); 248 | await fs.writeFile(filePath, code); 249 | command = await getCommandPath("python"); 250 | args = [filePath]; 251 | break; 252 | 253 | default: 254 | throw new Error(`Unsupported language: ${language}`); 255 | } 256 | 257 | console.error(`Spawning process: ${command} ${args.join(" ")}`); 258 | 259 | // サーバープロセスを起動(パイプに変更) 260 | const childProcess = spawn(command, args, { 261 | stdio: ["pipe", "pipe", "pipe"], // inheritではなくpipeを使用 262 | shell: true, 263 | env: commonEnv, 264 | cwd: process.cwd(), 265 | }); 266 | 267 | // 標準エラー出力のログ取得 268 | childProcess.stderr.on("data", (data) => { 269 | console.error(`Child process stderr: ${data}`); 270 | }); 271 | 272 | // 標準出力のログ取得 273 | childProcess.stdout.on("data", (data) => { 274 | console.error(`Child process stdout: ${data}`); 275 | }); 276 | 277 | // Create MCP client to communicate with the server 278 | const transport = new StdioClientTransport({ 279 | command, 280 | args, 281 | env: commonEnv, // 同じ環境変数を使用 282 | }); 283 | 284 | const client = new Client( 285 | { 286 | name: "mcp-create-client", 287 | version: "1.0.0", 288 | }, 289 | { 290 | capabilities: { 291 | tools: {}, 292 | }, 293 | } 294 | ); 295 | 296 | try { 297 | await client.connect(transport); 298 | console.error(`Connected to server ${serverId}`); 299 | } catch (error) { 300 | console.error(`Error connecting to server ${serverId}:`, error); 301 | childProcess.kill(); 302 | throw error; 303 | } 304 | 305 | // Store server info 306 | this.servers.set(serverId, { 307 | process: childProcess, 308 | client, 309 | transport, 310 | language, 311 | filePath, 312 | }); 313 | 314 | // Handle process exit 315 | childProcess.on("exit", (code) => { 316 | console.error(`Server ${serverId} exited with code ${code}`); 317 | this.servers.delete(serverId); 318 | }); 319 | 320 | return serverId; 321 | } catch (error) { 322 | // Clean up on error 323 | console.error(`Error creating server:`, error); 324 | try { 325 | await fs.rm(serverDir, { recursive: true, force: true }); 326 | } catch (cleanupError) { 327 | console.error(`Error cleaning up server directory: ${cleanupError}`); 328 | } 329 | 330 | throw error; 331 | } 332 | } 333 | 334 | // Create a server from template 335 | // async createServerFromTemplate( 336 | // language: string 337 | // ): Promise<{ serverId: string; message: string }> { 338 | // // Template code for different languages 339 | // let templateCode: string; 340 | 341 | // switch (language) { 342 | // case "typescript": 343 | // templateCode = ` 344 | // import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 345 | // import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 346 | // import { 347 | // CallToolRequestSchema, 348 | // ListToolsRequestSchema 349 | // } from "@modelcontextprotocol/sdk/types.js"; 350 | 351 | // const server = new Server({ 352 | // name: "dynamic-test-server", 353 | // version: "1.0.0" 354 | // }, { 355 | // capabilities: { 356 | // tools: {} 357 | // } 358 | // }); 359 | 360 | // // Server implementation - 正しいスキーマ型を使用 361 | // server.setRequestHandler(ListToolsRequestSchema, async () => { 362 | // return { 363 | // tools: [{ 364 | // name: "echo", 365 | // description: "Echo back a message", 366 | // inputSchema: { 367 | // type: "object", 368 | // properties: { 369 | // message: { type: "string" } 370 | // }, 371 | // required: ["message"] 372 | // } 373 | // }] 374 | // }; 375 | // }); 376 | 377 | // server.setRequestHandler(CallToolRequestSchema, async (request) => { 378 | // if (request.params.name === "echo") { 379 | // return { 380 | // content: [ 381 | // { 382 | // type: "text", 383 | // text: \`Echo: \${request.params.arguments.message}\` 384 | // } 385 | // ] 386 | // }; 387 | // } 388 | // throw new Error("Tool not found"); 389 | // }); 390 | 391 | // // Server startup 392 | // const transport = new StdioServerTransport(); 393 | // server.connect(transport); 394 | // `; 395 | // break; 396 | 397 | // case "python": 398 | // templateCode = ` 399 | // import asyncio 400 | // from mcp.server import Server 401 | // from mcp.server.stdio import stdio_server 402 | 403 | // app = Server("dynamic-test-server") 404 | 405 | // @app.list_tools() 406 | // async def list_tools(): 407 | // return [ 408 | // { 409 | // "name": "echo", 410 | // "description": "Echo back a message", 411 | // "inputSchema": { 412 | // "type": "object", 413 | // "properties": { 414 | // "message": {"type": "string"} 415 | // }, 416 | // "required": ["message"] 417 | // } 418 | // } 419 | // ] 420 | 421 | // @app.call_tool() 422 | // async def call_tool(name, arguments): 423 | // if name == "echo": 424 | // return [{"type": "text", "text": f"Echo: {arguments.get('message')}"}] 425 | // raise ValueError(f"Tool not found: {name}") 426 | 427 | // async def main(): 428 | // async with stdio_server() as streams: 429 | // await app.run( 430 | // streams[0], 431 | // streams[1], 432 | // app.create_initialization_options() 433 | // ) 434 | 435 | // if __name__ == "__main__": 436 | // asyncio.run(main()) 437 | // `; 438 | // break; 439 | 440 | // default: 441 | // throw new Error(`Unsupported template language: ${language}`); 442 | // } 443 | 444 | // const serverId = await this.createServer(templateCode, language); 445 | // return { 446 | // serverId, 447 | // message: `Created server from ${language} template`, 448 | // }; 449 | // } 450 | 451 | // 以下は他のメソッドも同様に修正することになりますが、 452 | // 主要な変更点は上記の通りです 453 | 454 | // 依存関係をインストールするメソッド 455 | async installDependencies( 456 | serverDir: string, 457 | dependencies: Record, 458 | language: string 459 | ): Promise { 460 | console.error(`Installing dependencies for ${language} in ${serverDir}`); 461 | 462 | switch (language) { 463 | case "typescript": 464 | case "javascript": 465 | await this.installNodeDependencies(serverDir, dependencies); 466 | break; 467 | case "python": 468 | await this.installPythonDependencies(serverDir, dependencies); 469 | break; 470 | default: 471 | throw new Error(`Unsupported language for dependencies: ${language}`); 472 | } 473 | } 474 | 475 | // Node.js (TypeScript/JavaScript) 用の依存関係インストール 476 | private async installNodeDependencies( 477 | serverDir: string, 478 | dependencies: Record 479 | ): Promise { 480 | try { 481 | // 既存のpackage.jsonを読み込む(存在する場合) 482 | let packageJson: any = { 483 | name: "mcp-dynamic-server", 484 | version: "1.0.0", 485 | type: "module", 486 | dependencies: {} 487 | }; 488 | 489 | // アプリケーションのpackage.jsonを読み込む 490 | try { 491 | const appPackageJsonPath = path.join("/app", "package.json"); 492 | const appPackageJsonContent = await fs.readFile(appPackageJsonPath, 'utf-8'); 493 | const appPackageJson = JSON.parse(appPackageJsonContent); 494 | 495 | // 必要な依存関係をマージ 496 | if (appPackageJson.dependencies) { 497 | // 特に@modelcontextprotocol関連の依存関係をコピー 498 | Object.entries(appPackageJson.dependencies).forEach(([pkg, ver]) => { 499 | if (pkg.startsWith('@modelcontextprotocol') || pkg === 'mcp') { 500 | packageJson.dependencies[pkg] = ver; 501 | } 502 | }); 503 | } 504 | 505 | console.error(`Merged dependencies from app package.json`); 506 | } catch (error) { 507 | console.error(`Error reading app package.json:`, error); 508 | // エラーがあっても続行 509 | } 510 | 511 | // ユーザー指定の依存関係をマージ 512 | Object.entries(dependencies).forEach(([pkg, ver]) => { 513 | packageJson.dependencies[pkg] = ver; 514 | }); 515 | 516 | // package.jsonを書き込む 517 | await fs.writeFile( 518 | path.join(serverDir, "package.json"), 519 | JSON.stringify(packageJson, null, 2) 520 | ); 521 | 522 | // npm install の実行 523 | const npmCommand = await getCommandPath("npm"); 524 | await new Promise((resolve, reject) => { 525 | const installProcess = spawn( 526 | npmCommand, 527 | ["install"], 528 | { 529 | stdio: ["ignore", "pipe", "pipe"], 530 | shell: true, 531 | env: { ...process.env }, 532 | cwd: serverDir 533 | } 534 | ); 535 | 536 | installProcess.stdout.on("data", (data) => { 537 | console.error(`NPM stdout: ${data}`); 538 | }); 539 | 540 | installProcess.stderr.on("data", (data) => { 541 | console.error(`NPM stderr: ${data}`); 542 | }); 543 | 544 | installProcess.on("exit", (code) => { 545 | if (code === 0) { 546 | console.error(`NPM install successful`); 547 | resolve(); 548 | } else { 549 | console.error(`NPM install failed with code ${code}`); 550 | reject(new Error(`NPM install failed with code ${code}`)); 551 | } 552 | }); 553 | }); 554 | } catch (error) { 555 | console.error(`Error installing Node.js dependencies:`, error); 556 | throw error; 557 | } 558 | } 559 | 560 | // Python 用の依存関係インストール 561 | private async installPythonDependencies( 562 | serverDir: string, 563 | dependencies: Record 564 | ): Promise { 565 | try { 566 | // requirements.txt の作成 567 | const requirementsContent = Object.entries(dependencies) 568 | .map(([pkg, ver]) => `${pkg}${ver}`) 569 | .join("\n"); 570 | 571 | await fs.writeFile( 572 | path.join(serverDir, "requirements.txt"), 573 | requirementsContent 574 | ); 575 | 576 | // pip install の実行 577 | const pipCommand = await getCommandPath("pip"); 578 | await new Promise((resolve, reject) => { 579 | const installProcess = spawn( 580 | pipCommand, 581 | ["install", "-r", "requirements.txt"], 582 | { 583 | stdio: ["ignore", "pipe", "pipe"], 584 | shell: true, 585 | env: { ...process.env }, 586 | cwd: serverDir 587 | } 588 | ); 589 | 590 | installProcess.stdout.on("data", (data) => { 591 | console.error(`PIP stdout: ${data}`); 592 | }); 593 | 594 | installProcess.stderr.on("data", (data) => { 595 | console.error(`PIP stderr: ${data}`); 596 | }); 597 | 598 | installProcess.on("exit", (code) => { 599 | if (code === 0) { 600 | console.error(`PIP install successful`); 601 | resolve(); 602 | } else { 603 | console.error(`PIP install failed with code ${code}`); 604 | reject(new Error(`PIP install failed with code ${code}`)); 605 | } 606 | }); 607 | }); 608 | } catch (error) { 609 | console.error(`Error installing Python dependencies:`, error); 610 | throw error; 611 | } 612 | } 613 | 614 | // Execute a tool on a server 615 | async executeToolOnServer( 616 | serverId: string, 617 | toolName: string, 618 | args: Record 619 | ): Promise { 620 | const server = this.servers.get(serverId); 621 | if (!server) { 622 | throw new Error(`Server ${serverId} not found`); 623 | } 624 | 625 | try { 626 | // Call the tool on the server using the MCP client 627 | const result = await server.client.callTool({ 628 | name: toolName, 629 | arguments: args, 630 | }); 631 | 632 | return result; 633 | } catch (error) { 634 | console.error(`Error executing tool on server ${serverId}:`, error); 635 | throw error; 636 | } 637 | } 638 | 639 | // Get tools from a server 640 | async getServerTools(serverId: string): Promise { 641 | const server = this.servers.get(serverId); 642 | if (!server) { 643 | throw new Error(`Server ${serverId} not found`); 644 | } 645 | 646 | try { 647 | // Get tools from the server using the MCP client 648 | const tools = await server.client.listTools(); 649 | return tools; 650 | } catch (error) { 651 | console.error(`Error getting tools from server ${serverId}:`, error); 652 | throw error; 653 | } 654 | } 655 | 656 | // Update a server 657 | async updateServer( 658 | serverId: string, 659 | code: string 660 | ): Promise<{ success: boolean; message: string }> { 661 | const server = this.servers.get(serverId); 662 | if (!server) { 663 | throw new Error(`Server ${serverId} not found`); 664 | } 665 | 666 | try { 667 | // Update server code 668 | await fs.writeFile(server.filePath, code); 669 | 670 | // Close the client connection 671 | await server.transport.close(); 672 | 673 | // Kill the server process 674 | server.process.kill(); 675 | 676 | // Wait for process to exit 677 | await new Promise((resolve) => { 678 | server.process.on("exit", () => { 679 | resolve(); 680 | }); 681 | }); 682 | 683 | // Remove the server from the map 684 | this.servers.delete(serverId); 685 | 686 | // Create new server with updated code 687 | const newServerId = await this.createServer(code, server.language); 688 | 689 | return { 690 | success: true, 691 | message: `Server ${serverId} updated and restarted as ${newServerId}`, 692 | }; 693 | } catch (error) { 694 | console.error(`Error updating server ${serverId}:`, error); 695 | throw error; 696 | } 697 | } 698 | 699 | // Delete a server 700 | async deleteServer( 701 | serverId: string 702 | ): Promise<{ success: boolean; message: string }> { 703 | const server = this.servers.get(serverId); 704 | if (!server) { 705 | throw new Error(`Server ${serverId} not found`); 706 | } 707 | 708 | try { 709 | // Close the client connection 710 | await server.transport.close(); 711 | 712 | // Kill server process 713 | server.process.kill(); 714 | 715 | // Remove server from map 716 | this.servers.delete(serverId); 717 | 718 | // Delete server directory 719 | const serverDir = path.dirname(server.filePath); 720 | await fs.rm(serverDir, { recursive: true, force: true }); 721 | 722 | return { 723 | success: true, 724 | message: `Server ${serverId} deleted`, 725 | }; 726 | } catch (error) { 727 | console.error(`Error deleting server ${serverId}:`, error); 728 | throw error; 729 | } 730 | } 731 | 732 | // List all servers 733 | listServers(): string[] { 734 | return Array.from(this.servers.keys()); 735 | } 736 | 737 | // Close all servers 738 | async closeAll(): Promise { 739 | for (const [serverId, server] of this.servers.entries()) { 740 | try { 741 | await server.transport.close(); 742 | server.process.kill(); 743 | console.error(`Closed server ${serverId}`); 744 | } catch (error) { 745 | console.error(`Error closing server ${serverId}:`, error); 746 | } 747 | } 748 | 749 | this.servers.clear(); 750 | } 751 | } 752 | 753 | // Tool definitions 754 | // const createServerTool: Tool = { 755 | // name: "create-server", 756 | // description: "Create a new MCP server from code", 757 | // inputSchema: { 758 | // type: "object", 759 | // properties: { 760 | // code: { 761 | // type: "string", 762 | // description: "The server code", 763 | // }, 764 | // language: { 765 | // type: "string", 766 | // enum: ["typescript", "javascript", "python"], 767 | // description: "The programming language of the server code", 768 | // }, 769 | // }, 770 | // required: ["code", "language"], 771 | // }, 772 | // }; 773 | 774 | const createServerFromTemplateTool: Tool = { 775 | name: "create-server-from-template", 776 | description: `Create a new MCP server from a template. 777 | 778 | 以下のテンプレートコードをベースに、ユーザーの要求に合わせたサーバーを実装してください。 779 | 言語に応じて適切なテンプレートを選択し、必要に応じて機能を追加・変更してください。 780 | 781 | TypeScriptテンプレート: 782 | \`\`\`typescript 783 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 784 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 785 | import { 786 | CallToolRequestSchema, 787 | ListToolsRequestSchema 788 | } from "@modelcontextprotocol/sdk/types.js"; 789 | 790 | const server = new Server({ 791 | name: "dynamic-test-server", 792 | version: "1.0.0" 793 | }, { 794 | capabilities: { 795 | tools: {} 796 | } 797 | }); 798 | 799 | // ここでツールを実装してください 800 | server.setRequestHandler(ListToolsRequestSchema, async () => { 801 | return { 802 | tools: [{ 803 | name: "echo", 804 | description: "Echo back a message", 805 | inputSchema: { 806 | type: "object", 807 | properties: { 808 | message: { type: "string" } 809 | }, 810 | required: ["message"] 811 | } 812 | }] 813 | }; 814 | }); 815 | 816 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 817 | if (request.params.name === "echo") { 818 | // TypeScriptの型を適切に扱うため、型アサーションを使用 819 | const message = request.params.arguments.message as string; 820 | // または any を使う: const message: any = request.params.arguments.message; 821 | 822 | return { 823 | content: [ 824 | { 825 | type: "text", 826 | text: \`Echo: \${message}\` 827 | } 828 | ] 829 | }; 830 | } 831 | throw new Error("Tool not found"); 832 | }); 833 | 834 | // Server startup 835 | const transport = new StdioServerTransport(); 836 | server.connect(transport); 837 | \`\`\` 838 | 839 | Pythonテンプレート: 840 | \`\`\`python 841 | import asyncio 842 | from mcp.server import Server 843 | from mcp.server.stdio import stdio_server 844 | 845 | app = Server("dynamic-test-server") 846 | 847 | @app.list_tools() 848 | async def list_tools(): 849 | return [ 850 | { 851 | "name": "echo", 852 | "description": "Echo back a message", 853 | "inputSchema": { 854 | "type": "object", 855 | "properties": { 856 | "message": {"type": "string"} 857 | }, 858 | "required": ["message"] 859 | } 860 | } 861 | ] 862 | 863 | @app.call_tool() 864 | async def call_tool(name, arguments): 865 | if name == "echo": 866 | return [{"type": "text", "text": f"Echo: {arguments.get('message')}"}] 867 | raise ValueError(f"Tool not found: {name}") 868 | 869 | async def main(): 870 | async with stdio_server() as streams: 871 | await app.run( 872 | streams[0], 873 | streams[1], 874 | app.create_initialization_options() 875 | ) 876 | 877 | if __name__ == "__main__": 878 | asyncio.run(main()) 879 | \`\`\` 880 | 881 | 注意事項: 882 | - TypeScript実装時は、引数の型を適切に扱うために型アサーション(as string)を使用するか、 883 | 明示的に型を宣言してください(例:const value: string = request.params.arguments.someValue)。 884 | - 複雑な型を扱う場合は、interface や type を定義して型安全性を確保することをお勧めします。 885 | 886 | ユーザーの要求に応じて上記のテンプレートを参考にカスタマイズしてください。その際、基本的な構造を維持しつつ、ツール名や機能を変更できます。`, 887 | inputSchema: { 888 | type: "object", 889 | properties: { 890 | language: { 891 | type: "string", 892 | enum: ["typescript", "python"], 893 | description: "The programming language for the template", 894 | }, 895 | code: { 896 | type: "string", 897 | description: 898 | "カスタマイズしたサーバーコード。テンプレートを元に変更したコードを入力してください。省略した場合はデフォルトのテンプレートが使用されます。", 899 | }, 900 | dependencies: { 901 | type: "object", 902 | description: "使用するライブラリとそのバージョン(例: { \"axios\": \"^1.0.0\" })", 903 | }, 904 | }, 905 | required: ["language"], 906 | }, 907 | }; 908 | 909 | const executeToolTool: Tool = { 910 | name: "execute-tool", 911 | description: "Execute a tool on a server", 912 | inputSchema: { 913 | type: "object", 914 | properties: { 915 | serverId: { 916 | type: "string", 917 | description: "The ID of the server", 918 | }, 919 | toolName: { 920 | type: "string", 921 | description: "The name of the tool to execute", 922 | }, 923 | args: { 924 | type: "object", 925 | description: "The arguments to pass to the tool", 926 | }, 927 | }, 928 | required: ["serverId", "toolName"], 929 | }, 930 | }; 931 | 932 | const getServerToolsTool: Tool = { 933 | name: "get-server-tools", 934 | description: "Get the tools available on a server", 935 | inputSchema: { 936 | type: "object", 937 | properties: { 938 | serverId: { 939 | type: "string", 940 | description: "The ID of the server", 941 | }, 942 | }, 943 | required: ["serverId"], 944 | }, 945 | }; 946 | 947 | // const updateServerTool: Tool = { 948 | // name: "update-server", 949 | // description: `Update a server's code.まずupdate前のコードを読み、その内容からupdateの差分を考えてください。 950 | // その差分をもとに、update後のコードを作成してください。`, 951 | // inputSchema: { 952 | // type: "object", 953 | // properties: { 954 | // serverId: { 955 | // type: "string", 956 | // description: "The ID of the server", 957 | // }, 958 | // code: { 959 | // type: "string", 960 | // description: `The new server code. 961 | // `, 962 | // }, 963 | // }, 964 | // required: ["serverId", "code"], 965 | // }, 966 | // }; 967 | 968 | const deleteServerTool: Tool = { 969 | name: "delete-server", 970 | description: "Delete a server", 971 | inputSchema: { 972 | type: "object", 973 | properties: { 974 | serverId: { 975 | type: "string", 976 | description: "The ID of the server", 977 | }, 978 | }, 979 | required: ["serverId"], 980 | }, 981 | }; 982 | 983 | const listServersTool: Tool = { 984 | name: "list-servers", 985 | description: "List all running servers", 986 | inputSchema: { 987 | type: "object", 988 | properties: {}, 989 | }, 990 | }; 991 | 992 | async function main() { 993 | try { 994 | console.error("Starting MCP Create Server..."); 995 | const server = new Server( 996 | { 997 | name: "MCP Create Server", 998 | version: "1.0.0", 999 | }, 1000 | { 1001 | capabilities: { 1002 | tools: {}, 1003 | }, 1004 | } 1005 | ); 1006 | 1007 | // Create server manager 1008 | const serverManager = new ServerManager(); 1009 | 1010 | // Register tool handlers 1011 | server.setRequestHandler(ListToolsRequestSchema, async () => { 1012 | console.error("Received ListToolsRequest"); 1013 | return { 1014 | tools: [ 1015 | createServerFromTemplateTool, 1016 | executeToolTool, 1017 | getServerToolsTool, 1018 | deleteServerTool, 1019 | listServersTool, 1020 | ], 1021 | }; 1022 | }); 1023 | 1024 | server.setRequestHandler( 1025 | CallToolRequestSchema, 1026 | async (request: CallToolRequest) => { 1027 | console.error("Received CallToolRequest:", request); 1028 | try { 1029 | if (!request.params.arguments) { 1030 | throw new Error("No arguments provided"); 1031 | } 1032 | 1033 | switch (request.params.name) { 1034 | case "create-server": { 1035 | const args = request.params 1036 | .arguments as unknown as CreateServerArgs; 1037 | if (!args.code || !args.language) { 1038 | throw new Error( 1039 | "Missing required arguments: code and language" 1040 | ); 1041 | } 1042 | 1043 | const serverId = await serverManager.createServer( 1044 | args.code, 1045 | args.language 1046 | ); 1047 | 1048 | return { 1049 | content: [ 1050 | { 1051 | type: "text", 1052 | text: JSON.stringify({ serverId }), 1053 | }, 1054 | ], 1055 | }; 1056 | } 1057 | 1058 | case "create-server-from-template": { 1059 | const args = request.params 1060 | .arguments as unknown as CreateServerFromTemplateArgs; 1061 | if (!args.language) { 1062 | throw new Error("Missing required argument: language"); 1063 | } 1064 | 1065 | // LLMから提供されたカスタムコードがあればそれを使用し、なければデフォルトのテンプレートを使用 1066 | let serverCode = args.code; 1067 | 1068 | // コードが提供されていない場合はデフォルトテンプレートを使用 1069 | if (!serverCode) { 1070 | // 既存のテンプレート選択ロジック 1071 | switch (args.language) { 1072 | case "typescript": 1073 | serverCode = `/* TypeScriptテンプレート */`; 1074 | break; 1075 | case "python": 1076 | serverCode = `# Pythonテンプレート`; 1077 | break; 1078 | default: 1079 | throw new Error( 1080 | `Unsupported template language: ${args.language}` 1081 | ); 1082 | } 1083 | } 1084 | 1085 | const result = await serverManager.createServer( 1086 | serverCode, 1087 | args.language, 1088 | args.dependencies 1089 | ); 1090 | 1091 | return { 1092 | content: [ 1093 | { 1094 | type: "text", 1095 | text: JSON.stringify({ 1096 | serverId: result, 1097 | message: args.code 1098 | ? `Created server from custom code in ${args.language}` 1099 | : `Created server from ${args.language} template`, 1100 | }), 1101 | }, 1102 | ], 1103 | }; 1104 | } 1105 | 1106 | case "execute-tool": { 1107 | const args = request.params 1108 | .arguments as unknown as ExecuteToolArgs; 1109 | if (!args.serverId || !args.toolName) { 1110 | throw new Error( 1111 | "Missing required arguments: serverId and toolName" 1112 | ); 1113 | } 1114 | 1115 | const result = await serverManager.executeToolOnServer( 1116 | args.serverId, 1117 | args.toolName, 1118 | args.args || {} 1119 | ); 1120 | 1121 | return { 1122 | content: [ 1123 | { 1124 | type: "text", 1125 | text: JSON.stringify(result), 1126 | }, 1127 | ], 1128 | }; 1129 | } 1130 | 1131 | case "get-server-tools": { 1132 | const args = request.params 1133 | .arguments as unknown as GetServerToolsArgs; 1134 | if (!args.serverId) { 1135 | throw new Error("Missing required argument: serverId"); 1136 | } 1137 | 1138 | const tools = await serverManager.getServerTools(args.serverId); 1139 | 1140 | return { 1141 | content: [ 1142 | { 1143 | type: "text", 1144 | text: JSON.stringify({ tools }), 1145 | }, 1146 | ], 1147 | }; 1148 | } 1149 | 1150 | case "update-server": { 1151 | const args = request.params 1152 | .arguments as unknown as UpdateServerArgs; 1153 | if (!args.serverId || !args.code) { 1154 | throw new Error( 1155 | "Missing required arguments: serverId and code" 1156 | ); 1157 | } 1158 | 1159 | const result = await serverManager.updateServer( 1160 | args.serverId, 1161 | args.code 1162 | ); 1163 | 1164 | return { 1165 | content: [ 1166 | { 1167 | type: "text", 1168 | text: JSON.stringify(result), 1169 | }, 1170 | ], 1171 | }; 1172 | } 1173 | 1174 | case "delete-server": { 1175 | const args = request.params 1176 | .arguments as unknown as DeleteServerArgs; 1177 | if (!args.serverId) { 1178 | throw new Error("Missing required argument: serverId"); 1179 | } 1180 | 1181 | const result = await serverManager.deleteServer(args.serverId); 1182 | 1183 | return { 1184 | content: [ 1185 | { 1186 | type: "text", 1187 | text: JSON.stringify(result), 1188 | }, 1189 | ], 1190 | }; 1191 | } 1192 | 1193 | case "list-servers": { 1194 | const servers = serverManager.listServers(); 1195 | 1196 | return { 1197 | content: [ 1198 | { 1199 | type: "text", 1200 | text: JSON.stringify({ servers }), 1201 | }, 1202 | ], 1203 | }; 1204 | } 1205 | 1206 | default: 1207 | throw new Error(`Unknown tool: ${request.params.name}`); 1208 | } 1209 | } catch (error) { 1210 | console.error("Error executing tool:", error); 1211 | return { 1212 | content: [ 1213 | { 1214 | type: "text", 1215 | text: JSON.stringify({ 1216 | error: error instanceof Error ? error.message : String(error), 1217 | }), 1218 | }, 1219 | ], 1220 | }; 1221 | } 1222 | } 1223 | ); 1224 | 1225 | // Set up transport and connect 1226 | const transport = new StdioServerTransport(); 1227 | console.error("Connecting server to transport..."); 1228 | await server.connect(transport); 1229 | 1230 | console.error("MCP Create Server running on stdio"); 1231 | } catch (error: unknown) { 1232 | const errorMessage = error instanceof Error ? error.message : String(error); 1233 | console.error(`Failed to start server: ${errorMessage}`); 1234 | process.exit(1); 1235 | } 1236 | } 1237 | 1238 | main().catch((error) => { 1239 | console.error("Fatal error in main():", error); 1240 | process.exit(1); 1241 | }); 1242 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcp-create", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "mcp-create", 9 | "version": "1.0.0", 10 | "dependencies": { 11 | "@modelcontextprotocol/sdk": "^1.0.0", 12 | "uuid": "^9.0.1", 13 | "zod": "^3.22.4" 14 | }, 15 | "bin": { 16 | "mcp-create": "build/index.js" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^20.10.0", 20 | "@types/uuid": "^9.0.8", 21 | "typescript": "^5.3.2" 22 | } 23 | }, 24 | "node_modules/@modelcontextprotocol/sdk": { 25 | "version": "1.6.1", 26 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.6.1.tgz", 27 | "integrity": "sha512-oxzMzYCkZHMntzuyerehK3fV6A2Kwh5BD6CGEJSVDU2QNEhfLOptf2X7esQgaHZXHZY0oHmMsOtIDLP71UJXgA==", 28 | "dependencies": { 29 | "content-type": "^1.0.5", 30 | "cors": "^2.8.5", 31 | "eventsource": "^3.0.2", 32 | "express": "^5.0.1", 33 | "express-rate-limit": "^7.5.0", 34 | "pkce-challenge": "^4.1.0", 35 | "raw-body": "^3.0.0", 36 | "zod": "^3.23.8", 37 | "zod-to-json-schema": "^3.24.1" 38 | }, 39 | "engines": { 40 | "node": ">=18" 41 | } 42 | }, 43 | "node_modules/@types/node": { 44 | "version": "20.17.22", 45 | "dev": true, 46 | "license": "MIT", 47 | "dependencies": { 48 | "undici-types": "~6.19.2" 49 | } 50 | }, 51 | "node_modules/@types/uuid": { 52 | "version": "9.0.8", 53 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", 54 | "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", 55 | "dev": true 56 | }, 57 | "node_modules/accepts": { 58 | "version": "2.0.0", 59 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", 60 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", 61 | "dependencies": { 62 | "mime-types": "^3.0.0", 63 | "negotiator": "^1.0.0" 64 | }, 65 | "engines": { 66 | "node": ">= 0.6" 67 | } 68 | }, 69 | "node_modules/body-parser": { 70 | "version": "2.1.0", 71 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz", 72 | "integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==", 73 | "dependencies": { 74 | "bytes": "^3.1.2", 75 | "content-type": "^1.0.5", 76 | "debug": "^4.4.0", 77 | "http-errors": "^2.0.0", 78 | "iconv-lite": "^0.5.2", 79 | "on-finished": "^2.4.1", 80 | "qs": "^6.14.0", 81 | "raw-body": "^3.0.0", 82 | "type-is": "^2.0.0" 83 | }, 84 | "engines": { 85 | "node": ">=18" 86 | } 87 | }, 88 | "node_modules/body-parser/node_modules/debug": { 89 | "version": "4.4.0", 90 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 91 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 92 | "dependencies": { 93 | "ms": "^2.1.3" 94 | }, 95 | "engines": { 96 | "node": ">=6.0" 97 | }, 98 | "peerDependenciesMeta": { 99 | "supports-color": { 100 | "optional": true 101 | } 102 | } 103 | }, 104 | "node_modules/body-parser/node_modules/ms": { 105 | "version": "2.1.3", 106 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 107 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 108 | }, 109 | "node_modules/body-parser/node_modules/qs": { 110 | "version": "6.14.0", 111 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 112 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 113 | "dependencies": { 114 | "side-channel": "^1.1.0" 115 | }, 116 | "engines": { 117 | "node": ">=0.6" 118 | }, 119 | "funding": { 120 | "url": "https://github.com/sponsors/ljharb" 121 | } 122 | }, 123 | "node_modules/bytes": { 124 | "version": "3.1.2", 125 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 126 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 127 | "engines": { 128 | "node": ">= 0.8" 129 | } 130 | }, 131 | "node_modules/call-bind-apply-helpers": { 132 | "version": "1.0.2", 133 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 134 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 135 | "dependencies": { 136 | "es-errors": "^1.3.0", 137 | "function-bind": "^1.1.2" 138 | }, 139 | "engines": { 140 | "node": ">= 0.4" 141 | } 142 | }, 143 | "node_modules/call-bound": { 144 | "version": "1.0.4", 145 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 146 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 147 | "dependencies": { 148 | "call-bind-apply-helpers": "^1.0.2", 149 | "get-intrinsic": "^1.3.0" 150 | }, 151 | "engines": { 152 | "node": ">= 0.4" 153 | }, 154 | "funding": { 155 | "url": "https://github.com/sponsors/ljharb" 156 | } 157 | }, 158 | "node_modules/content-disposition": { 159 | "version": "1.0.0", 160 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", 161 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", 162 | "dependencies": { 163 | "safe-buffer": "5.2.1" 164 | }, 165 | "engines": { 166 | "node": ">= 0.6" 167 | } 168 | }, 169 | "node_modules/content-type": { 170 | "version": "1.0.5", 171 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 172 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 173 | "engines": { 174 | "node": ">= 0.6" 175 | } 176 | }, 177 | "node_modules/cookie": { 178 | "version": "0.7.1", 179 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", 180 | "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", 181 | "engines": { 182 | "node": ">= 0.6" 183 | } 184 | }, 185 | "node_modules/cookie-signature": { 186 | "version": "1.2.2", 187 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", 188 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", 189 | "engines": { 190 | "node": ">=6.6.0" 191 | } 192 | }, 193 | "node_modules/cors": { 194 | "version": "2.8.5", 195 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 196 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 197 | "dependencies": { 198 | "object-assign": "^4", 199 | "vary": "^1" 200 | }, 201 | "engines": { 202 | "node": ">= 0.10" 203 | } 204 | }, 205 | "node_modules/debug": { 206 | "version": "4.3.6", 207 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", 208 | "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", 209 | "dependencies": { 210 | "ms": "2.1.2" 211 | }, 212 | "engines": { 213 | "node": ">=6.0" 214 | }, 215 | "peerDependenciesMeta": { 216 | "supports-color": { 217 | "optional": true 218 | } 219 | } 220 | }, 221 | "node_modules/depd": { 222 | "version": "2.0.0", 223 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 224 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 225 | "engines": { 226 | "node": ">= 0.8" 227 | } 228 | }, 229 | "node_modules/destroy": { 230 | "version": "1.2.0", 231 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 232 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 233 | "engines": { 234 | "node": ">= 0.8", 235 | "npm": "1.2.8000 || >= 1.4.16" 236 | } 237 | }, 238 | "node_modules/dunder-proto": { 239 | "version": "1.0.1", 240 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 241 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 242 | "dependencies": { 243 | "call-bind-apply-helpers": "^1.0.1", 244 | "es-errors": "^1.3.0", 245 | "gopd": "^1.2.0" 246 | }, 247 | "engines": { 248 | "node": ">= 0.4" 249 | } 250 | }, 251 | "node_modules/ee-first": { 252 | "version": "1.1.1", 253 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 254 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" 255 | }, 256 | "node_modules/encodeurl": { 257 | "version": "2.0.0", 258 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 259 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 260 | "engines": { 261 | "node": ">= 0.8" 262 | } 263 | }, 264 | "node_modules/es-define-property": { 265 | "version": "1.0.1", 266 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 267 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 268 | "engines": { 269 | "node": ">= 0.4" 270 | } 271 | }, 272 | "node_modules/es-errors": { 273 | "version": "1.3.0", 274 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 275 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 276 | "engines": { 277 | "node": ">= 0.4" 278 | } 279 | }, 280 | "node_modules/es-object-atoms": { 281 | "version": "1.1.1", 282 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 283 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 284 | "dependencies": { 285 | "es-errors": "^1.3.0" 286 | }, 287 | "engines": { 288 | "node": ">= 0.4" 289 | } 290 | }, 291 | "node_modules/escape-html": { 292 | "version": "1.0.3", 293 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 294 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" 295 | }, 296 | "node_modules/etag": { 297 | "version": "1.8.1", 298 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 299 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 300 | "engines": { 301 | "node": ">= 0.6" 302 | } 303 | }, 304 | "node_modules/eventsource": { 305 | "version": "3.0.5", 306 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz", 307 | "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==", 308 | "dependencies": { 309 | "eventsource-parser": "^3.0.0" 310 | }, 311 | "engines": { 312 | "node": ">=18.0.0" 313 | } 314 | }, 315 | "node_modules/eventsource-parser": { 316 | "version": "3.0.0", 317 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz", 318 | "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==", 319 | "engines": { 320 | "node": ">=18.0.0" 321 | } 322 | }, 323 | "node_modules/express": { 324 | "version": "5.0.1", 325 | "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", 326 | "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", 327 | "dependencies": { 328 | "accepts": "^2.0.0", 329 | "body-parser": "^2.0.1", 330 | "content-disposition": "^1.0.0", 331 | "content-type": "~1.0.4", 332 | "cookie": "0.7.1", 333 | "cookie-signature": "^1.2.1", 334 | "debug": "4.3.6", 335 | "depd": "2.0.0", 336 | "encodeurl": "~2.0.0", 337 | "escape-html": "~1.0.3", 338 | "etag": "~1.8.1", 339 | "finalhandler": "^2.0.0", 340 | "fresh": "2.0.0", 341 | "http-errors": "2.0.0", 342 | "merge-descriptors": "^2.0.0", 343 | "methods": "~1.1.2", 344 | "mime-types": "^3.0.0", 345 | "on-finished": "2.4.1", 346 | "once": "1.4.0", 347 | "parseurl": "~1.3.3", 348 | "proxy-addr": "~2.0.7", 349 | "qs": "6.13.0", 350 | "range-parser": "~1.2.1", 351 | "router": "^2.0.0", 352 | "safe-buffer": "5.2.1", 353 | "send": "^1.1.0", 354 | "serve-static": "^2.1.0", 355 | "setprototypeof": "1.2.0", 356 | "statuses": "2.0.1", 357 | "type-is": "^2.0.0", 358 | "utils-merge": "1.0.1", 359 | "vary": "~1.1.2" 360 | }, 361 | "engines": { 362 | "node": ">= 18" 363 | } 364 | }, 365 | "node_modules/express-rate-limit": { 366 | "version": "7.5.0", 367 | "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", 368 | "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", 369 | "engines": { 370 | "node": ">= 16" 371 | }, 372 | "funding": { 373 | "url": "https://github.com/sponsors/express-rate-limit" 374 | }, 375 | "peerDependencies": { 376 | "express": "^4.11 || 5 || ^5.0.0-beta.1" 377 | } 378 | }, 379 | "node_modules/finalhandler": { 380 | "version": "2.1.0", 381 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", 382 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", 383 | "dependencies": { 384 | "debug": "^4.4.0", 385 | "encodeurl": "^2.0.0", 386 | "escape-html": "^1.0.3", 387 | "on-finished": "^2.4.1", 388 | "parseurl": "^1.3.3", 389 | "statuses": "^2.0.1" 390 | }, 391 | "engines": { 392 | "node": ">= 0.8" 393 | } 394 | }, 395 | "node_modules/finalhandler/node_modules/debug": { 396 | "version": "4.4.0", 397 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 398 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 399 | "dependencies": { 400 | "ms": "^2.1.3" 401 | }, 402 | "engines": { 403 | "node": ">=6.0" 404 | }, 405 | "peerDependenciesMeta": { 406 | "supports-color": { 407 | "optional": true 408 | } 409 | } 410 | }, 411 | "node_modules/finalhandler/node_modules/ms": { 412 | "version": "2.1.3", 413 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 414 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 415 | }, 416 | "node_modules/forwarded": { 417 | "version": "0.2.0", 418 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 419 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 420 | "engines": { 421 | "node": ">= 0.6" 422 | } 423 | }, 424 | "node_modules/fresh": { 425 | "version": "2.0.0", 426 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", 427 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", 428 | "engines": { 429 | "node": ">= 0.8" 430 | } 431 | }, 432 | "node_modules/function-bind": { 433 | "version": "1.1.2", 434 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 435 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 436 | "funding": { 437 | "url": "https://github.com/sponsors/ljharb" 438 | } 439 | }, 440 | "node_modules/get-intrinsic": { 441 | "version": "1.3.0", 442 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 443 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 444 | "dependencies": { 445 | "call-bind-apply-helpers": "^1.0.2", 446 | "es-define-property": "^1.0.1", 447 | "es-errors": "^1.3.0", 448 | "es-object-atoms": "^1.1.1", 449 | "function-bind": "^1.1.2", 450 | "get-proto": "^1.0.1", 451 | "gopd": "^1.2.0", 452 | "has-symbols": "^1.1.0", 453 | "hasown": "^2.0.2", 454 | "math-intrinsics": "^1.1.0" 455 | }, 456 | "engines": { 457 | "node": ">= 0.4" 458 | }, 459 | "funding": { 460 | "url": "https://github.com/sponsors/ljharb" 461 | } 462 | }, 463 | "node_modules/get-proto": { 464 | "version": "1.0.1", 465 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 466 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 467 | "dependencies": { 468 | "dunder-proto": "^1.0.1", 469 | "es-object-atoms": "^1.0.0" 470 | }, 471 | "engines": { 472 | "node": ">= 0.4" 473 | } 474 | }, 475 | "node_modules/gopd": { 476 | "version": "1.2.0", 477 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 478 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 479 | "engines": { 480 | "node": ">= 0.4" 481 | }, 482 | "funding": { 483 | "url": "https://github.com/sponsors/ljharb" 484 | } 485 | }, 486 | "node_modules/has-symbols": { 487 | "version": "1.1.0", 488 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 489 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 490 | "engines": { 491 | "node": ">= 0.4" 492 | }, 493 | "funding": { 494 | "url": "https://github.com/sponsors/ljharb" 495 | } 496 | }, 497 | "node_modules/hasown": { 498 | "version": "2.0.2", 499 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 500 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 501 | "dependencies": { 502 | "function-bind": "^1.1.2" 503 | }, 504 | "engines": { 505 | "node": ">= 0.4" 506 | } 507 | }, 508 | "node_modules/http-errors": { 509 | "version": "2.0.0", 510 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 511 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 512 | "dependencies": { 513 | "depd": "2.0.0", 514 | "inherits": "2.0.4", 515 | "setprototypeof": "1.2.0", 516 | "statuses": "2.0.1", 517 | "toidentifier": "1.0.1" 518 | }, 519 | "engines": { 520 | "node": ">= 0.8" 521 | } 522 | }, 523 | "node_modules/iconv-lite": { 524 | "version": "0.5.2", 525 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", 526 | "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", 527 | "dependencies": { 528 | "safer-buffer": ">= 2.1.2 < 3" 529 | }, 530 | "engines": { 531 | "node": ">=0.10.0" 532 | } 533 | }, 534 | "node_modules/inherits": { 535 | "version": "2.0.4", 536 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 537 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 538 | }, 539 | "node_modules/ipaddr.js": { 540 | "version": "1.9.1", 541 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 542 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 543 | "engines": { 544 | "node": ">= 0.10" 545 | } 546 | }, 547 | "node_modules/is-promise": { 548 | "version": "4.0.0", 549 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 550 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" 551 | }, 552 | "node_modules/math-intrinsics": { 553 | "version": "1.1.0", 554 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 555 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 556 | "engines": { 557 | "node": ">= 0.4" 558 | } 559 | }, 560 | "node_modules/media-typer": { 561 | "version": "1.1.0", 562 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", 563 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", 564 | "engines": { 565 | "node": ">= 0.8" 566 | } 567 | }, 568 | "node_modules/merge-descriptors": { 569 | "version": "2.0.0", 570 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", 571 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", 572 | "engines": { 573 | "node": ">=18" 574 | }, 575 | "funding": { 576 | "url": "https://github.com/sponsors/sindresorhus" 577 | } 578 | }, 579 | "node_modules/methods": { 580 | "version": "1.1.2", 581 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 582 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 583 | "engines": { 584 | "node": ">= 0.6" 585 | } 586 | }, 587 | "node_modules/mime-db": { 588 | "version": "1.53.0", 589 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", 590 | "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", 591 | "engines": { 592 | "node": ">= 0.6" 593 | } 594 | }, 595 | "node_modules/mime-types": { 596 | "version": "3.0.0", 597 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", 598 | "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", 599 | "dependencies": { 600 | "mime-db": "^1.53.0" 601 | }, 602 | "engines": { 603 | "node": ">= 0.6" 604 | } 605 | }, 606 | "node_modules/ms": { 607 | "version": "2.1.2", 608 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 609 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 610 | }, 611 | "node_modules/negotiator": { 612 | "version": "1.0.0", 613 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", 614 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", 615 | "engines": { 616 | "node": ">= 0.6" 617 | } 618 | }, 619 | "node_modules/object-assign": { 620 | "version": "4.1.1", 621 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 622 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 623 | "engines": { 624 | "node": ">=0.10.0" 625 | } 626 | }, 627 | "node_modules/object-inspect": { 628 | "version": "1.13.4", 629 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 630 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 631 | "engines": { 632 | "node": ">= 0.4" 633 | }, 634 | "funding": { 635 | "url": "https://github.com/sponsors/ljharb" 636 | } 637 | }, 638 | "node_modules/on-finished": { 639 | "version": "2.4.1", 640 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 641 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 642 | "dependencies": { 643 | "ee-first": "1.1.1" 644 | }, 645 | "engines": { 646 | "node": ">= 0.8" 647 | } 648 | }, 649 | "node_modules/once": { 650 | "version": "1.4.0", 651 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 652 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 653 | "dependencies": { 654 | "wrappy": "1" 655 | } 656 | }, 657 | "node_modules/parseurl": { 658 | "version": "1.3.3", 659 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 660 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 661 | "engines": { 662 | "node": ">= 0.8" 663 | } 664 | }, 665 | "node_modules/path-to-regexp": { 666 | "version": "8.2.0", 667 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 668 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", 669 | "engines": { 670 | "node": ">=16" 671 | } 672 | }, 673 | "node_modules/pkce-challenge": { 674 | "version": "4.1.0", 675 | "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-4.1.0.tgz", 676 | "integrity": "sha512-ZBmhE1C9LcPoH9XZSdwiPtbPHZROwAnMy+kIFQVrnMCxY4Cudlz3gBOpzilgc0jOgRaiT3sIWfpMomW2ar2orQ==", 677 | "engines": { 678 | "node": ">=16.20.0" 679 | } 680 | }, 681 | "node_modules/proxy-addr": { 682 | "version": "2.0.7", 683 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 684 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 685 | "dependencies": { 686 | "forwarded": "0.2.0", 687 | "ipaddr.js": "1.9.1" 688 | }, 689 | "engines": { 690 | "node": ">= 0.10" 691 | } 692 | }, 693 | "node_modules/qs": { 694 | "version": "6.13.0", 695 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 696 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 697 | "dependencies": { 698 | "side-channel": "^1.0.6" 699 | }, 700 | "engines": { 701 | "node": ">=0.6" 702 | }, 703 | "funding": { 704 | "url": "https://github.com/sponsors/ljharb" 705 | } 706 | }, 707 | "node_modules/range-parser": { 708 | "version": "1.2.1", 709 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 710 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 711 | "engines": { 712 | "node": ">= 0.6" 713 | } 714 | }, 715 | "node_modules/raw-body": { 716 | "version": "3.0.0", 717 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 718 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 719 | "dependencies": { 720 | "bytes": "3.1.2", 721 | "http-errors": "2.0.0", 722 | "iconv-lite": "0.6.3", 723 | "unpipe": "1.0.0" 724 | }, 725 | "engines": { 726 | "node": ">= 0.8" 727 | } 728 | }, 729 | "node_modules/raw-body/node_modules/iconv-lite": { 730 | "version": "0.6.3", 731 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 732 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 733 | "dependencies": { 734 | "safer-buffer": ">= 2.1.2 < 3.0.0" 735 | }, 736 | "engines": { 737 | "node": ">=0.10.0" 738 | } 739 | }, 740 | "node_modules/router": { 741 | "version": "2.1.0", 742 | "resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz", 743 | "integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==", 744 | "dependencies": { 745 | "is-promise": "^4.0.0", 746 | "parseurl": "^1.3.3", 747 | "path-to-regexp": "^8.0.0" 748 | }, 749 | "engines": { 750 | "node": ">= 18" 751 | } 752 | }, 753 | "node_modules/safe-buffer": { 754 | "version": "5.2.1", 755 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 756 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 757 | "funding": [ 758 | { 759 | "type": "github", 760 | "url": "https://github.com/sponsors/feross" 761 | }, 762 | { 763 | "type": "patreon", 764 | "url": "https://www.patreon.com/feross" 765 | }, 766 | { 767 | "type": "consulting", 768 | "url": "https://feross.org/support" 769 | } 770 | ] 771 | }, 772 | "node_modules/safer-buffer": { 773 | "version": "2.1.2", 774 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 775 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 776 | }, 777 | "node_modules/send": { 778 | "version": "1.1.0", 779 | "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", 780 | "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", 781 | "dependencies": { 782 | "debug": "^4.3.5", 783 | "destroy": "^1.2.0", 784 | "encodeurl": "^2.0.0", 785 | "escape-html": "^1.0.3", 786 | "etag": "^1.8.1", 787 | "fresh": "^0.5.2", 788 | "http-errors": "^2.0.0", 789 | "mime-types": "^2.1.35", 790 | "ms": "^2.1.3", 791 | "on-finished": "^2.4.1", 792 | "range-parser": "^1.2.1", 793 | "statuses": "^2.0.1" 794 | }, 795 | "engines": { 796 | "node": ">= 18" 797 | } 798 | }, 799 | "node_modules/send/node_modules/fresh": { 800 | "version": "0.5.2", 801 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 802 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 803 | "engines": { 804 | "node": ">= 0.6" 805 | } 806 | }, 807 | "node_modules/send/node_modules/mime-db": { 808 | "version": "1.52.0", 809 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 810 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 811 | "engines": { 812 | "node": ">= 0.6" 813 | } 814 | }, 815 | "node_modules/send/node_modules/mime-types": { 816 | "version": "2.1.35", 817 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 818 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 819 | "dependencies": { 820 | "mime-db": "1.52.0" 821 | }, 822 | "engines": { 823 | "node": ">= 0.6" 824 | } 825 | }, 826 | "node_modules/send/node_modules/ms": { 827 | "version": "2.1.3", 828 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 829 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" 830 | }, 831 | "node_modules/serve-static": { 832 | "version": "2.1.0", 833 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", 834 | "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", 835 | "dependencies": { 836 | "encodeurl": "^2.0.0", 837 | "escape-html": "^1.0.3", 838 | "parseurl": "^1.3.3", 839 | "send": "^1.0.0" 840 | }, 841 | "engines": { 842 | "node": ">= 18" 843 | } 844 | }, 845 | "node_modules/setprototypeof": { 846 | "version": "1.2.0", 847 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 848 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" 849 | }, 850 | "node_modules/side-channel": { 851 | "version": "1.1.0", 852 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 853 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 854 | "dependencies": { 855 | "es-errors": "^1.3.0", 856 | "object-inspect": "^1.13.3", 857 | "side-channel-list": "^1.0.0", 858 | "side-channel-map": "^1.0.1", 859 | "side-channel-weakmap": "^1.0.2" 860 | }, 861 | "engines": { 862 | "node": ">= 0.4" 863 | }, 864 | "funding": { 865 | "url": "https://github.com/sponsors/ljharb" 866 | } 867 | }, 868 | "node_modules/side-channel-list": { 869 | "version": "1.0.0", 870 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 871 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 872 | "dependencies": { 873 | "es-errors": "^1.3.0", 874 | "object-inspect": "^1.13.3" 875 | }, 876 | "engines": { 877 | "node": ">= 0.4" 878 | }, 879 | "funding": { 880 | "url": "https://github.com/sponsors/ljharb" 881 | } 882 | }, 883 | "node_modules/side-channel-map": { 884 | "version": "1.0.1", 885 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 886 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 887 | "dependencies": { 888 | "call-bound": "^1.0.2", 889 | "es-errors": "^1.3.0", 890 | "get-intrinsic": "^1.2.5", 891 | "object-inspect": "^1.13.3" 892 | }, 893 | "engines": { 894 | "node": ">= 0.4" 895 | }, 896 | "funding": { 897 | "url": "https://github.com/sponsors/ljharb" 898 | } 899 | }, 900 | "node_modules/side-channel-weakmap": { 901 | "version": "1.0.2", 902 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 903 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 904 | "dependencies": { 905 | "call-bound": "^1.0.2", 906 | "es-errors": "^1.3.0", 907 | "get-intrinsic": "^1.2.5", 908 | "object-inspect": "^1.13.3", 909 | "side-channel-map": "^1.0.1" 910 | }, 911 | "engines": { 912 | "node": ">= 0.4" 913 | }, 914 | "funding": { 915 | "url": "https://github.com/sponsors/ljharb" 916 | } 917 | }, 918 | "node_modules/statuses": { 919 | "version": "2.0.1", 920 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 921 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 922 | "engines": { 923 | "node": ">= 0.8" 924 | } 925 | }, 926 | "node_modules/toidentifier": { 927 | "version": "1.0.1", 928 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 929 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 930 | "engines": { 931 | "node": ">=0.6" 932 | } 933 | }, 934 | "node_modules/type-is": { 935 | "version": "2.0.0", 936 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", 937 | "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", 938 | "dependencies": { 939 | "content-type": "^1.0.5", 940 | "media-typer": "^1.1.0", 941 | "mime-types": "^3.0.0" 942 | }, 943 | "engines": { 944 | "node": ">= 0.6" 945 | } 946 | }, 947 | "node_modules/typescript": { 948 | "version": "5.8.2", 949 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 950 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 951 | "dev": true, 952 | "bin": { 953 | "tsc": "bin/tsc", 954 | "tsserver": "bin/tsserver" 955 | }, 956 | "engines": { 957 | "node": ">=14.17" 958 | } 959 | }, 960 | "node_modules/undici-types": { 961 | "version": "6.19.8", 962 | "dev": true, 963 | "license": "MIT" 964 | }, 965 | "node_modules/unpipe": { 966 | "version": "1.0.0", 967 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 968 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 969 | "engines": { 970 | "node": ">= 0.8" 971 | } 972 | }, 973 | "node_modules/utils-merge": { 974 | "version": "1.0.1", 975 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 976 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 977 | "engines": { 978 | "node": ">= 0.4.0" 979 | } 980 | }, 981 | "node_modules/uuid": { 982 | "version": "9.0.1", 983 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", 984 | "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", 985 | "funding": [ 986 | "https://github.com/sponsors/broofa", 987 | "https://github.com/sponsors/ctavan" 988 | ], 989 | "bin": { 990 | "uuid": "dist/bin/uuid" 991 | } 992 | }, 993 | "node_modules/vary": { 994 | "version": "1.1.2", 995 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 996 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 997 | "engines": { 998 | "node": ">= 0.8" 999 | } 1000 | }, 1001 | "node_modules/wrappy": { 1002 | "version": "1.0.2", 1003 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1004 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" 1005 | }, 1006 | "node_modules/zod": { 1007 | "version": "3.24.2", 1008 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 1009 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 1010 | "funding": { 1011 | "url": "https://github.com/sponsors/colinhacks" 1012 | } 1013 | }, 1014 | "node_modules/zod-to-json-schema": { 1015 | "version": "3.24.3", 1016 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.3.tgz", 1017 | "integrity": "sha512-HIAfWdYIt1sssHfYZFCXp4rU1w2r8hVVXYIlmoa0r0gABLs5di3RCqPU5DDROogVz1pAdYBaz7HK5n9pSUNs3A==", 1018 | "peerDependencies": { 1019 | "zod": "^3.24.1" 1020 | } 1021 | } 1022 | } 1023 | } 1024 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mcp-create", 3 | "version": "1.0.0", 4 | "main": "build/index.js", 5 | "type": "module", 6 | "bin": { 7 | "mcp-create": "./build/index.js" 8 | }, 9 | "dependencies": { 10 | "@modelcontextprotocol/sdk": "^1.0.0", 11 | "uuid": "^9.0.1", 12 | "zod": "^3.22.4" 13 | }, 14 | "devDependencies": { 15 | "@types/node": "^20.10.0", 16 | "@types/uuid": "^9.0.8", 17 | "typescript": "^5.3.2" 18 | }, 19 | "scripts": { 20 | "build": "tsc", 21 | "postbuild": "chmod +x build/index.js", 22 | "start": "node build/index.js" 23 | }, 24 | "files": [ 25 | "build" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "NodeNext", 5 | "moduleResolution": "NodeNext", 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "skipLibCheck": true, 9 | "outDir": "build", // distからbuildに変更済み 10 | "rootDir": ".", 11 | "declaration": true 12 | }, 13 | "include": ["**/*.ts"], // すべてのサブディレクトリの.tsファイルを含める 14 | "exclude": ["node_modules", "build"] // 除外先も変更済み 15 | } 16 | --------------------------------------------------------------------------------