├── .github
├── conventional-changelog.config.cjs
├── conventional-changelog.config.js
└── workflows
│ ├── pr-validation.yml
│ ├── publish.yml
│ └── refresh-badges.yml
├── .gitignore
├── CHANGELOG.md
├── Dockerfile
├── LICENSE
├── README.md
├── commitlint.config.js
├── package-lock.json
├── package.json
├── scripts
└── build.js
├── smithery.yaml
├── src
├── index.ts
├── resources
│ ├── config.md
│ ├── examples.md
│ └── response-format.md
└── version.ts.template
└── tsconfig.json
/.github/conventional-changelog.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | types: [
3 | { type: 'feat', section: 'Features', hidden: false },
4 | { type: 'fix', section: 'Bug Fixes', hidden: false },
5 | { type: 'chore', section: 'Maintenance', hidden: false },
6 | { type: 'docs', section: 'Documentation', hidden: false },
7 | { type: 'style', section: 'Styling', hidden: false },
8 | { type: 'refactor', section: 'Code Refactoring', hidden: false },
9 | { type: 'perf', section: 'Performance', hidden: false },
10 | { type: 'test', section: 'Testing', hidden: false },
11 | { type: 'ci', section: 'CI/CD', hidden: false },
12 | { type: 'build', section: 'Build System', hidden: false }
13 | ],
14 | releaseRules: [
15 | { type: 'feat', release: 'minor' },
16 | { type: 'fix', release: 'patch' },
17 | { type: 'perf', release: 'patch' },
18 | { type: 'chore', release: 'patch' },
19 | { type: 'docs', release: 'patch' },
20 | { type: 'style', release: 'patch' },
21 | { type: 'refactor', release: 'patch' },
22 | { type: 'test', release: 'patch' },
23 | { type: 'ci', release: 'patch' },
24 | { type: 'build', release: 'patch' }
25 | ]
26 | };
27 |
--------------------------------------------------------------------------------
/.github/conventional-changelog.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | types: [
3 | { type: 'feat', section: 'Features' },
4 | { type: 'fix', section: 'Bug Fixes' },
5 | { type: 'chore', section: 'Maintenance' },
6 | { type: 'docs', section: 'Documentation' },
7 | { type: 'style', section: 'Styling' },
8 | { type: 'refactor', section: 'Code Refactoring' },
9 | { type: 'perf', section: 'Performance' },
10 | { type: 'test', section: 'Testing' },
11 | { type: 'ci', section: 'CI/CD' },
12 | { type: 'build', section: 'Build System' }
13 | ]
14 | };
15 |
--------------------------------------------------------------------------------
/.github/workflows/pr-validation.yml:
--------------------------------------------------------------------------------
1 | name: Pull Request Validation
2 |
3 | on:
4 | pull_request:
5 | branches: [ main ]
6 |
7 | jobs:
8 | validate:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@v4
12 | with:
13 | fetch-depth: 0
14 |
15 | - name: Setup Node.js
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version: '18'
19 | cache: 'npm'
20 |
21 | - name: Install dependencies
22 | run: npm ci
23 |
24 | - name: Validate Conventional Commits
25 | run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
26 |
27 | - name: Build
28 | run: npm run build
29 |
30 | - name: Run Tests
31 | run: |
32 | if [ -f "package.json" ] && grep -q "\"test\":" "package.json"; then
33 | npm test
34 | else
35 | echo "No test script found in package.json"
36 | fi
37 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish Package
2 |
3 | on:
4 | push:
5 | branches: [ main ]
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: write
10 | pull-requests: write
11 |
12 | jobs:
13 | publish:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v4
17 | with:
18 | fetch-depth: 0
19 |
20 | - name: Setup Node.js
21 | uses: actions/setup-node@v4
22 | with:
23 | node-version: '18.x'
24 | registry-url: 'https://registry.npmjs.org'
25 |
26 | - name: Install dependencies
27 | run: npm ci
28 |
29 | - name: Conventional Changelog Action
30 | id: changelog
31 | uses: TriPSs/conventional-changelog-action@v6
32 | with:
33 | github-token: ${{ secrets.GITHUB_TOKEN }}
34 | git-message: 'chore(release): {version}'
35 | config-file-path: '.github/conventional-changelog.config.cjs'
36 | tag-prefix: 'v'
37 | output-file: 'CHANGELOG.md'
38 | skip-version-file: false
39 | skip-commit: false
40 | skip-on-empty: false
41 | git-user-name: ${{ secrets.CHANGELOG_GIT_NAME }}
42 | git-user-email: ${{ secrets.CHANGELOG_GIT_EMAIL }}
43 |
44 | - name: Build
45 | run: npm run build
46 |
47 | - name: Create Release
48 | if: steps.changelog.outputs.skipped == 'false'
49 | env:
50 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
51 | run: |
52 | gh release create v${{ steps.changelog.outputs.version }} \
53 | --title "Release v${{ steps.changelog.outputs.version }}" \
54 | --notes "${{ steps.changelog.outputs.clean_changelog }}"
55 |
56 | - name: Publish to NPM
57 | if: steps.changelog.outputs.skipped == 'false'
58 | run: npm publish
59 | env:
60 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
61 |
--------------------------------------------------------------------------------
/.github/workflows/refresh-badges.yml:
--------------------------------------------------------------------------------
1 | name: Refresh Badges
2 |
3 | on:
4 | schedule:
5 | - cron: '0 0 * * *' # Run at 00:00 UTC every day
6 | push:
7 | branches:
8 | - main
9 | workflow_dispatch: # Allow manual triggering
10 |
11 | jobs:
12 | refresh:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Refresh badges
16 | uses: b3b00/refreshBadgesAction@v1.0.7
17 | with:
18 | repository: 'zenturacp/mcp-rest-api'
19 | branch: 'main'
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | build/
3 | src/version.ts
4 | .DS_Store
5 | *.log
6 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [0.4.0](https://github.com/dkmaker/mcp-rest-api/compare/v0.3.0...v0.4.0) (2025-01-08)
2 |
3 |
4 | ### Features
5 |
6 | * add custom header support ([9a48e0d](https://github.com/dkmaker/mcp-rest-api/commit/9a48e0d794a743f7a62c7cb73d6f5b1be9e44107))
7 |
8 | ## [0.3.0](https://github.com/dkmaker/mcp-rest-api/compare/v0.2.0...v0.3.0) (2024-12-28)
9 |
10 |
11 | ### Features
12 |
13 | * add config documentation and improve URL resolution examples ([8c6100f](https://github.com/dkmaker/mcp-rest-api/commit/8c6100f47777605a0571edbd161ffd20fc48b640))
14 | * add MCP resources for documentation ([a20cf35](https://github.com/dkmaker/mcp-rest-api/commit/a20cf352e9731841a8d7e833007a96bdd1a0c390))
15 |
16 |
17 | ### Bug Fixes
18 |
19 | * correct response truncation to return first N bytes ([ce34649](https://github.com/dkmaker/mcp-rest-api/commit/ce34649c4d8e6bc6d740e8f3fbc6e3df517e0eec))
20 |
21 | ## [0.2.0](https://github.com/dkmaker/mcp-rest-api/compare/0fdbe844dd4ce8b79f38a33df323a29e28253724...v0.2.0) (2024-12-21)
22 |
23 |
24 | ### Features
25 |
26 | * **ssl:** add SSL verification control with secure defaults ([0fdbe84](https://github.com/dkmaker/mcp-rest-api/commit/0fdbe844dd4ce8b79f38a33df323a29e28253724))
27 |
28 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile
2 | # Use the Node.js image with the required version for the project
3 | FROM node:18-alpine AS builder
4 |
5 | # Set working directory
6 | WORKDIR /app
7 |
8 | # Copy package files to the working directory
9 | COPY package.json package-lock.json ./
10 |
11 | # Install dependencies
12 | RUN npm install
13 |
14 | # Copy all files to the working directory
15 | COPY . .
16 |
17 | # Build the TypeScript files
18 | RUN npm run build
19 |
20 | # Create the final release image
21 | FROM node:18-alpine AS release
22 |
23 | # Set working directory
24 | WORKDIR /app
25 |
26 | # Copy built files and necessary package information
27 | COPY --from=builder /app/build /app/build
28 | COPY --from=builder /app/package.json /app/package-lock.json /app/node_modules ./
29 |
30 | # Environment configuration for runtime (configured externally)
31 | ENV REST_BASE_URL=""
32 | ENV AUTH_BASIC_USERNAME=""
33 | ENV AUTH_BASIC_PASSWORD=""
34 | ENV AUTH_BEARER=""
35 | ENV AUTH_APIKEY_HEADER_NAME=""
36 | ENV AUTH_APIKEY_VALUE=""
37 | ENV REST_ENABLE_SSL_VERIFY="true"
38 | ENV REST_RESPONSE_SIZE_LIMIT="10000"
39 |
40 | # Command to run the server
41 | ENTRYPOINT ["node", "build/index.js"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Christian Pedersen
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 REST API Tester
2 | [](https://opensource.org/licenses/MIT)
3 | [](https://www.npmjs.com/package/dkmaker-mcp-rest-api)
4 | [](https://smithery.ai/server/dkmaker-mcp-rest-api)
5 |
6 | A TypeScript-based MCP server that enables testing of REST APIs through Cline. This tool allows you to test and interact with any REST API endpoints directly from your development environment.
7 |
8 |
9 |
10 |
11 |
12 | ## Installation
13 |
14 | ### Installing via Smithery
15 |
16 | To install REST API Tester for Claude Desktop automatically via [Smithery](https://smithery.ai/server/dkmaker-mcp-rest-api):
17 |
18 | ```bash
19 | npx -y @smithery/cli install dkmaker-mcp-rest-api --client claude
20 | ```
21 |
22 | ### Installing Manually
23 | 1. Install the package globally:
24 | ```bash
25 | npm install -g dkmaker-mcp-rest-api
26 | ```
27 |
28 | 2. Configure Cline Custom Instructions:
29 |
30 | To ensure Cline understands how to effectively use this tool, add the following to your Cline custom instructions (Settings > Custom Instructions):
31 |
32 | ```markdown
33 | # REST API Testing Instructions
34 |
35 | The `test_request` tool enables testing, debugging, and interacting with REST API endpoints. The tool provides comprehensive request/response information and handles authentication automatically.
36 |
37 | ## When to Use
38 |
39 | - Testing specific API endpoints
40 | - Debugging API responses
41 | - Verifying API functionality
42 | - Checking response times
43 | - Validating request/response formats
44 | - Testing local development servers
45 | - Testing API sequences
46 | - Verifying error handling
47 |
48 | ## Key Features
49 |
50 | - Supports GET, POST, PUT, DELETE methods
51 | - Handles authentication (Basic, Bearer, API Key)
52 | - Normalizes endpoints automatically
53 | - Provides detailed response information
54 | - Configurable SSL verification and response limits
55 |
56 | ## Resources
57 |
58 | The following resources provide detailed documentation:
59 |
60 | - examples: Usage examples and common patterns
61 | - response-format: Response structure and fields
62 | - config: Configuration options and setup guide
63 |
64 | Access these resources to understand usage, response formats, and configuration options.
65 |
66 | ## Important Notes
67 |
68 | - Review API implementation for expected behavior
69 | - Handle sensitive data appropriately
70 | - Consider rate limits and API constraints
71 | - Restart server after configuration changes
72 | ```
73 |
74 | 3. Add the server to your MCP configuration:
75 |
76 | While these instructions are for Cline, the server should work with any MCP implementation. Configure based on your operating system:
77 |
78 | ### Windows
79 | ⚠️ **IMPORTANT**: Due to a known issue with Windows path resolution ([issue #40](https://github.com/modelcontextprotocol/servers/issues/40)), you must use the full path instead of %APPDATA%.
80 |
81 | Add to `C:\Users\\AppData\Roaming\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json`:
82 | ```json
83 | {
84 | "mcpServers": {
85 | "rest-api": {
86 | "command": "node",
87 | "args": [
88 | "C:/Users//AppData/Roaming/npm/node_modules/dkmaker-mcp-rest-api/build/index.js"
89 | ],
90 | "env": {
91 | "REST_BASE_URL": "https://api.example.com",
92 | // Basic Auth
93 | "AUTH_BASIC_USERNAME": "your-username",
94 | "AUTH_BASIC_PASSWORD": "your-password",
95 | // OR Bearer Token
96 | "AUTH_BEARER": "your-token",
97 | // OR API Key
98 | "AUTH_APIKEY_HEADER_NAME": "X-API-Key",
99 | "AUTH_APIKEY_VALUE": "your-api-key",
100 | // SSL Verification (enabled by default)
101 | "REST_ENABLE_SSL_VERIFY": "false", // Set to false to disable SSL verification for self-signed certificates
102 | // Response Size Limit (optional, defaults to 10000 bytes)
103 | "REST_RESPONSE_SIZE_LIMIT": "10000", // Maximum response size in bytes
104 | // Custom Headers (optional)
105 | "HEADER_X-API-Version": "2.0",
106 | "HEADER_Custom-Client": "my-client",
107 | "HEADER_Accept": "application/json"
108 | }
109 | }
110 | }
111 | }
112 | ```
113 |
114 | ### macOS
115 | Add to `~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json`:
116 | ```json
117 | {
118 | "mcpServers": {
119 | "rest-api": {
120 | "command": "npx",
121 | "args": [
122 | "-y",
123 | "dkmaker-mcp-rest-api"
124 | ],
125 | "env": {
126 | "REST_BASE_URL": "https://api.example.com",
127 | // Basic Auth
128 | "AUTH_BASIC_USERNAME": "your-username",
129 | "AUTH_BASIC_PASSWORD": "your-password",
130 | // OR Bearer Token
131 | "AUTH_BEARER": "your-token",
132 | // OR API Key
133 | "AUTH_APIKEY_HEADER_NAME": "X-API-Key",
134 | "AUTH_APIKEY_VALUE": "your-api-key",
135 | // SSL Verification (enabled by default)
136 | "REST_ENABLE_SSL_VERIFY": "false", // Set to false to disable SSL verification for self-signed certificates
137 | // Custom Headers (optional)
138 | "HEADER_X-API-Version": "2.0",
139 | "HEADER_Custom-Client": "my-client",
140 | "HEADER_Accept": "application/json"
141 | }
142 | }
143 | }
144 | }
145 | ```
146 |
147 | Note: Replace the environment variables with your actual values. Only configure one authentication method at a time:
148 | 1. Basic Authentication (username/password)
149 | 2. Bearer Token (if Basic Auth is not configured)
150 | 3. API Key (if neither Basic Auth nor Bearer Token is configured)
151 |
152 | ## Features
153 |
154 | - Test REST API endpoints with different HTTP methods
155 | - Support for GET, POST, PUT, and DELETE requests
156 | - Detailed response information including status, headers, and body
157 | - Custom Headers:
158 | - Global headers via HEADER_* environment variables
159 | - Case-insensitive prefix (HEADER_, header_, HeAdEr_)
160 | - Case preservation for header names
161 | - Priority-based application (per-request > auth > custom)
162 | - Request body handling for POST/PUT methods
163 | - Response Size Management:
164 | - Automatic response size limiting (default: 10KB/10000 bytes)
165 | - Configurable size limit via REST_RESPONSE_SIZE_LIMIT environment variable
166 | - Clear truncation metadata when responses exceed limit
167 | - Preserves response structure while only truncating body content
168 |
169 | - SSL Certificate Verification:
170 | - Enabled by default for secure operation
171 | - Can be disabled for self-signed certificates or development environments
172 | - Control via REST_ENABLE_SSL_VERIFY environment variable
173 | - Multiple authentication methods:
174 | - Basic Authentication (username/password)
175 | - Bearer Token Authentication
176 | - API Key Authentication (custom header)
177 |
178 | ## Usage Examples
179 |
180 | Once installed and configured, you can use the REST API Tester through Cline to test your API endpoints:
181 |
182 | ```typescript
183 | // Test a GET endpoint
184 | use_mcp_tool('rest-api', 'test_request', {
185 | "method": "GET",
186 | "endpoint": "/users"
187 | });
188 |
189 | // Test a POST endpoint with body
190 | use_mcp_tool('rest-api', 'test_request', {
191 | "method": "POST",
192 | "endpoint": "/users",
193 | "body": {
194 | "name": "John Doe",
195 | "email": "john@example.com"
196 | }
197 | });
198 |
199 | // Test with custom headers
200 | use_mcp_tool('rest-api', 'test_request', {
201 | "method": "GET",
202 | "endpoint": "/products",
203 | "headers": {
204 | "Accept-Language": "en-US",
205 | "X-Custom-Header": "custom-value"
206 | }
207 | });
208 | ```
209 |
210 | ## Development
211 |
212 | 1. Clone the repository:
213 | ```bash
214 | git clone https://github.com/zenturacp/mcp-rest-api.git
215 | cd mcp-rest-api
216 | ```
217 |
218 | 2. Install dependencies:
219 | ```bash
220 | npm install
221 | ```
222 |
223 | 3. Build the project:
224 | ```bash
225 | npm run build
226 | ```
227 |
228 | For development with auto-rebuild:
229 | ```bash
230 | npm run watch
231 | ```
232 |
233 | ## License
234 |
235 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
236 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | extends: ['@commitlint/config-conventional'],
3 | rules: {
4 | 'type-enum': [
5 | 2,
6 | 'always',
7 | [
8 | 'build',
9 | 'chore',
10 | 'ci',
11 | 'docs',
12 | 'feat',
13 | 'fix',
14 | 'perf',
15 | 'refactor',
16 | 'revert',
17 | 'style',
18 | 'test'
19 | ]
20 | ],
21 | 'type-case': [2, 'always', 'lower-case'],
22 | 'type-empty': [2, 'never'],
23 | 'scope-case': [2, 'always', 'lower-case'],
24 | 'subject-case': [2, 'always', 'lower-case'],
25 | 'subject-empty': [2, 'never'],
26 | 'subject-full-stop': [2, 'never', '.']
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dkmaker-mcp-rest-api",
3 | "version": "0.4.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "dkmaker-mcp-rest-api",
9 | "version": "0.4.0",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@modelcontextprotocol/sdk": "^1.0.4",
13 | "axios": "^1.7.9"
14 | },
15 | "bin": {
16 | "dkmaker-mcp-rest-api": "build/index.js"
17 | },
18 | "devDependencies": {
19 | "@commitlint/cli": "^19.6.1",
20 | "@commitlint/config-conventional": "^19.6.0",
21 | "@types/node": "^20.11.24",
22 | "typescript": "^5.3.3"
23 | },
24 | "engines": {
25 | "node": ">=18.0.0"
26 | }
27 | },
28 | "node_modules/@babel/code-frame": {
29 | "version": "7.26.2",
30 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
31 | "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
32 | "dev": true,
33 | "license": "MIT",
34 | "dependencies": {
35 | "@babel/helper-validator-identifier": "^7.25.9",
36 | "js-tokens": "^4.0.0",
37 | "picocolors": "^1.0.0"
38 | },
39 | "engines": {
40 | "node": ">=6.9.0"
41 | }
42 | },
43 | "node_modules/@babel/helper-validator-identifier": {
44 | "version": "7.25.9",
45 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
46 | "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
47 | "dev": true,
48 | "license": "MIT",
49 | "engines": {
50 | "node": ">=6.9.0"
51 | }
52 | },
53 | "node_modules/@commitlint/cli": {
54 | "version": "19.6.1",
55 | "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.6.1.tgz",
56 | "integrity": "sha512-8hcyA6ZoHwWXC76BoC8qVOSr8xHy00LZhZpauiD0iO0VYbVhMnED0da85lTfIULxl7Lj4c6vZgF0Wu/ed1+jlQ==",
57 | "dev": true,
58 | "license": "MIT",
59 | "dependencies": {
60 | "@commitlint/format": "^19.5.0",
61 | "@commitlint/lint": "^19.6.0",
62 | "@commitlint/load": "^19.6.1",
63 | "@commitlint/read": "^19.5.0",
64 | "@commitlint/types": "^19.5.0",
65 | "tinyexec": "^0.3.0",
66 | "yargs": "^17.0.0"
67 | },
68 | "bin": {
69 | "commitlint": "cli.js"
70 | },
71 | "engines": {
72 | "node": ">=v18"
73 | }
74 | },
75 | "node_modules/@commitlint/config-conventional": {
76 | "version": "19.6.0",
77 | "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.6.0.tgz",
78 | "integrity": "sha512-DJT40iMnTYtBtUfw9ApbsLZFke1zKh6llITVJ+x9mtpHD08gsNXaIRqHTmwTZL3dNX5+WoyK7pCN/5zswvkBCQ==",
79 | "dev": true,
80 | "license": "MIT",
81 | "dependencies": {
82 | "@commitlint/types": "^19.5.0",
83 | "conventional-changelog-conventionalcommits": "^7.0.2"
84 | },
85 | "engines": {
86 | "node": ">=v18"
87 | }
88 | },
89 | "node_modules/@commitlint/config-validator": {
90 | "version": "19.5.0",
91 | "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.5.0.tgz",
92 | "integrity": "sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==",
93 | "dev": true,
94 | "license": "MIT",
95 | "dependencies": {
96 | "@commitlint/types": "^19.5.0",
97 | "ajv": "^8.11.0"
98 | },
99 | "engines": {
100 | "node": ">=v18"
101 | }
102 | },
103 | "node_modules/@commitlint/ensure": {
104 | "version": "19.5.0",
105 | "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.5.0.tgz",
106 | "integrity": "sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==",
107 | "dev": true,
108 | "license": "MIT",
109 | "dependencies": {
110 | "@commitlint/types": "^19.5.0",
111 | "lodash.camelcase": "^4.3.0",
112 | "lodash.kebabcase": "^4.1.1",
113 | "lodash.snakecase": "^4.1.1",
114 | "lodash.startcase": "^4.4.0",
115 | "lodash.upperfirst": "^4.3.1"
116 | },
117 | "engines": {
118 | "node": ">=v18"
119 | }
120 | },
121 | "node_modules/@commitlint/execute-rule": {
122 | "version": "19.5.0",
123 | "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.5.0.tgz",
124 | "integrity": "sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==",
125 | "dev": true,
126 | "license": "MIT",
127 | "engines": {
128 | "node": ">=v18"
129 | }
130 | },
131 | "node_modules/@commitlint/format": {
132 | "version": "19.5.0",
133 | "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.5.0.tgz",
134 | "integrity": "sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==",
135 | "dev": true,
136 | "license": "MIT",
137 | "dependencies": {
138 | "@commitlint/types": "^19.5.0",
139 | "chalk": "^5.3.0"
140 | },
141 | "engines": {
142 | "node": ">=v18"
143 | }
144 | },
145 | "node_modules/@commitlint/is-ignored": {
146 | "version": "19.6.0",
147 | "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.6.0.tgz",
148 | "integrity": "sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==",
149 | "dev": true,
150 | "license": "MIT",
151 | "dependencies": {
152 | "@commitlint/types": "^19.5.0",
153 | "semver": "^7.6.0"
154 | },
155 | "engines": {
156 | "node": ">=v18"
157 | }
158 | },
159 | "node_modules/@commitlint/lint": {
160 | "version": "19.6.0",
161 | "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.6.0.tgz",
162 | "integrity": "sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==",
163 | "dev": true,
164 | "license": "MIT",
165 | "dependencies": {
166 | "@commitlint/is-ignored": "^19.6.0",
167 | "@commitlint/parse": "^19.5.0",
168 | "@commitlint/rules": "^19.6.0",
169 | "@commitlint/types": "^19.5.0"
170 | },
171 | "engines": {
172 | "node": ">=v18"
173 | }
174 | },
175 | "node_modules/@commitlint/load": {
176 | "version": "19.6.1",
177 | "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.6.1.tgz",
178 | "integrity": "sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==",
179 | "dev": true,
180 | "license": "MIT",
181 | "dependencies": {
182 | "@commitlint/config-validator": "^19.5.0",
183 | "@commitlint/execute-rule": "^19.5.0",
184 | "@commitlint/resolve-extends": "^19.5.0",
185 | "@commitlint/types": "^19.5.0",
186 | "chalk": "^5.3.0",
187 | "cosmiconfig": "^9.0.0",
188 | "cosmiconfig-typescript-loader": "^6.1.0",
189 | "lodash.isplainobject": "^4.0.6",
190 | "lodash.merge": "^4.6.2",
191 | "lodash.uniq": "^4.5.0"
192 | },
193 | "engines": {
194 | "node": ">=v18"
195 | }
196 | },
197 | "node_modules/@commitlint/message": {
198 | "version": "19.5.0",
199 | "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.5.0.tgz",
200 | "integrity": "sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==",
201 | "dev": true,
202 | "license": "MIT",
203 | "engines": {
204 | "node": ">=v18"
205 | }
206 | },
207 | "node_modules/@commitlint/parse": {
208 | "version": "19.5.0",
209 | "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.5.0.tgz",
210 | "integrity": "sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==",
211 | "dev": true,
212 | "license": "MIT",
213 | "dependencies": {
214 | "@commitlint/types": "^19.5.0",
215 | "conventional-changelog-angular": "^7.0.0",
216 | "conventional-commits-parser": "^5.0.0"
217 | },
218 | "engines": {
219 | "node": ">=v18"
220 | }
221 | },
222 | "node_modules/@commitlint/read": {
223 | "version": "19.5.0",
224 | "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.5.0.tgz",
225 | "integrity": "sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==",
226 | "dev": true,
227 | "license": "MIT",
228 | "dependencies": {
229 | "@commitlint/top-level": "^19.5.0",
230 | "@commitlint/types": "^19.5.0",
231 | "git-raw-commits": "^4.0.0",
232 | "minimist": "^1.2.8",
233 | "tinyexec": "^0.3.0"
234 | },
235 | "engines": {
236 | "node": ">=v18"
237 | }
238 | },
239 | "node_modules/@commitlint/resolve-extends": {
240 | "version": "19.5.0",
241 | "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.5.0.tgz",
242 | "integrity": "sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==",
243 | "dev": true,
244 | "license": "MIT",
245 | "dependencies": {
246 | "@commitlint/config-validator": "^19.5.0",
247 | "@commitlint/types": "^19.5.0",
248 | "global-directory": "^4.0.1",
249 | "import-meta-resolve": "^4.0.0",
250 | "lodash.mergewith": "^4.6.2",
251 | "resolve-from": "^5.0.0"
252 | },
253 | "engines": {
254 | "node": ">=v18"
255 | }
256 | },
257 | "node_modules/@commitlint/rules": {
258 | "version": "19.6.0",
259 | "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.6.0.tgz",
260 | "integrity": "sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==",
261 | "dev": true,
262 | "license": "MIT",
263 | "dependencies": {
264 | "@commitlint/ensure": "^19.5.0",
265 | "@commitlint/message": "^19.5.0",
266 | "@commitlint/to-lines": "^19.5.0",
267 | "@commitlint/types": "^19.5.0"
268 | },
269 | "engines": {
270 | "node": ">=v18"
271 | }
272 | },
273 | "node_modules/@commitlint/to-lines": {
274 | "version": "19.5.0",
275 | "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.5.0.tgz",
276 | "integrity": "sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==",
277 | "dev": true,
278 | "license": "MIT",
279 | "engines": {
280 | "node": ">=v18"
281 | }
282 | },
283 | "node_modules/@commitlint/top-level": {
284 | "version": "19.5.0",
285 | "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.5.0.tgz",
286 | "integrity": "sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==",
287 | "dev": true,
288 | "license": "MIT",
289 | "dependencies": {
290 | "find-up": "^7.0.0"
291 | },
292 | "engines": {
293 | "node": ">=v18"
294 | }
295 | },
296 | "node_modules/@commitlint/types": {
297 | "version": "19.5.0",
298 | "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.5.0.tgz",
299 | "integrity": "sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==",
300 | "dev": true,
301 | "license": "MIT",
302 | "dependencies": {
303 | "@types/conventional-commits-parser": "^5.0.0",
304 | "chalk": "^5.3.0"
305 | },
306 | "engines": {
307 | "node": ">=v18"
308 | }
309 | },
310 | "node_modules/@modelcontextprotocol/sdk": {
311 | "version": "1.0.4",
312 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.0.4.tgz",
313 | "integrity": "sha512-C+jw1lF6HSGzs7EZpzHbXfzz9rj9him4BaoumlTciW/IDDgIpweF/qiCWKlP02QKg5PPcgY6xY2WCt5y2tpYow==",
314 | "license": "MIT",
315 | "dependencies": {
316 | "content-type": "^1.0.5",
317 | "raw-body": "^3.0.0",
318 | "zod": "^3.23.8"
319 | }
320 | },
321 | "node_modules/@types/conventional-commits-parser": {
322 | "version": "5.0.1",
323 | "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz",
324 | "integrity": "sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==",
325 | "dev": true,
326 | "license": "MIT",
327 | "dependencies": {
328 | "@types/node": "*"
329 | }
330 | },
331 | "node_modules/@types/node": {
332 | "version": "20.17.10",
333 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.10.tgz",
334 | "integrity": "sha512-/jrvh5h6NXhEauFFexRin69nA0uHJ5gwk4iDivp/DeoEua3uwCUto6PC86IpRITBOs4+6i2I56K5x5b6WYGXHA==",
335 | "dev": true,
336 | "license": "MIT",
337 | "dependencies": {
338 | "undici-types": "~6.19.2"
339 | }
340 | },
341 | "node_modules/ajv": {
342 | "version": "8.17.1",
343 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
344 | "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
345 | "dev": true,
346 | "license": "MIT",
347 | "dependencies": {
348 | "fast-deep-equal": "^3.1.3",
349 | "fast-uri": "^3.0.1",
350 | "json-schema-traverse": "^1.0.0",
351 | "require-from-string": "^2.0.2"
352 | },
353 | "funding": {
354 | "type": "github",
355 | "url": "https://github.com/sponsors/epoberezkin"
356 | }
357 | },
358 | "node_modules/ansi-regex": {
359 | "version": "5.0.1",
360 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
361 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
362 | "dev": true,
363 | "license": "MIT",
364 | "engines": {
365 | "node": ">=8"
366 | }
367 | },
368 | "node_modules/ansi-styles": {
369 | "version": "4.3.0",
370 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
371 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
372 | "dev": true,
373 | "license": "MIT",
374 | "dependencies": {
375 | "color-convert": "^2.0.1"
376 | },
377 | "engines": {
378 | "node": ">=8"
379 | },
380 | "funding": {
381 | "url": "https://github.com/chalk/ansi-styles?sponsor=1"
382 | }
383 | },
384 | "node_modules/argparse": {
385 | "version": "2.0.1",
386 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
387 | "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
388 | "dev": true,
389 | "license": "Python-2.0"
390 | },
391 | "node_modules/array-ify": {
392 | "version": "1.0.0",
393 | "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
394 | "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
395 | "dev": true,
396 | "license": "MIT"
397 | },
398 | "node_modules/asynckit": {
399 | "version": "0.4.0",
400 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
401 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
402 | "license": "MIT"
403 | },
404 | "node_modules/axios": {
405 | "version": "1.7.9",
406 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
407 | "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
408 | "license": "MIT",
409 | "dependencies": {
410 | "follow-redirects": "^1.15.6",
411 | "form-data": "^4.0.0",
412 | "proxy-from-env": "^1.1.0"
413 | }
414 | },
415 | "node_modules/bytes": {
416 | "version": "3.1.2",
417 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
418 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
419 | "license": "MIT",
420 | "engines": {
421 | "node": ">= 0.8"
422 | }
423 | },
424 | "node_modules/callsites": {
425 | "version": "3.1.0",
426 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
427 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
428 | "dev": true,
429 | "license": "MIT",
430 | "engines": {
431 | "node": ">=6"
432 | }
433 | },
434 | "node_modules/chalk": {
435 | "version": "5.4.1",
436 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
437 | "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
438 | "dev": true,
439 | "license": "MIT",
440 | "engines": {
441 | "node": "^12.17.0 || ^14.13 || >=16.0.0"
442 | },
443 | "funding": {
444 | "url": "https://github.com/chalk/chalk?sponsor=1"
445 | }
446 | },
447 | "node_modules/cliui": {
448 | "version": "8.0.1",
449 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
450 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
451 | "dev": true,
452 | "license": "ISC",
453 | "dependencies": {
454 | "string-width": "^4.2.0",
455 | "strip-ansi": "^6.0.1",
456 | "wrap-ansi": "^7.0.0"
457 | },
458 | "engines": {
459 | "node": ">=12"
460 | }
461 | },
462 | "node_modules/color-convert": {
463 | "version": "2.0.1",
464 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
465 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
466 | "dev": true,
467 | "license": "MIT",
468 | "dependencies": {
469 | "color-name": "~1.1.4"
470 | },
471 | "engines": {
472 | "node": ">=7.0.0"
473 | }
474 | },
475 | "node_modules/color-name": {
476 | "version": "1.1.4",
477 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
478 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
479 | "dev": true,
480 | "license": "MIT"
481 | },
482 | "node_modules/combined-stream": {
483 | "version": "1.0.8",
484 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
485 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
486 | "license": "MIT",
487 | "dependencies": {
488 | "delayed-stream": "~1.0.0"
489 | },
490 | "engines": {
491 | "node": ">= 0.8"
492 | }
493 | },
494 | "node_modules/compare-func": {
495 | "version": "2.0.0",
496 | "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
497 | "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
498 | "dev": true,
499 | "license": "MIT",
500 | "dependencies": {
501 | "array-ify": "^1.0.0",
502 | "dot-prop": "^5.1.0"
503 | }
504 | },
505 | "node_modules/content-type": {
506 | "version": "1.0.5",
507 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
508 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
509 | "license": "MIT",
510 | "engines": {
511 | "node": ">= 0.6"
512 | }
513 | },
514 | "node_modules/conventional-changelog-angular": {
515 | "version": "7.0.0",
516 | "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
517 | "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
518 | "dev": true,
519 | "license": "ISC",
520 | "dependencies": {
521 | "compare-func": "^2.0.0"
522 | },
523 | "engines": {
524 | "node": ">=16"
525 | }
526 | },
527 | "node_modules/conventional-changelog-conventionalcommits": {
528 | "version": "7.0.2",
529 | "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
530 | "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
531 | "dev": true,
532 | "license": "ISC",
533 | "dependencies": {
534 | "compare-func": "^2.0.0"
535 | },
536 | "engines": {
537 | "node": ">=16"
538 | }
539 | },
540 | "node_modules/conventional-commits-parser": {
541 | "version": "5.0.0",
542 | "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
543 | "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
544 | "dev": true,
545 | "license": "MIT",
546 | "dependencies": {
547 | "is-text-path": "^2.0.0",
548 | "JSONStream": "^1.3.5",
549 | "meow": "^12.0.1",
550 | "split2": "^4.0.0"
551 | },
552 | "bin": {
553 | "conventional-commits-parser": "cli.mjs"
554 | },
555 | "engines": {
556 | "node": ">=16"
557 | }
558 | },
559 | "node_modules/cosmiconfig": {
560 | "version": "9.0.0",
561 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
562 | "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
563 | "dev": true,
564 | "license": "MIT",
565 | "dependencies": {
566 | "env-paths": "^2.2.1",
567 | "import-fresh": "^3.3.0",
568 | "js-yaml": "^4.1.0",
569 | "parse-json": "^5.2.0"
570 | },
571 | "engines": {
572 | "node": ">=14"
573 | },
574 | "funding": {
575 | "url": "https://github.com/sponsors/d-fischer"
576 | },
577 | "peerDependencies": {
578 | "typescript": ">=4.9.5"
579 | },
580 | "peerDependenciesMeta": {
581 | "typescript": {
582 | "optional": true
583 | }
584 | }
585 | },
586 | "node_modules/cosmiconfig-typescript-loader": {
587 | "version": "6.1.0",
588 | "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz",
589 | "integrity": "sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==",
590 | "dev": true,
591 | "license": "MIT",
592 | "dependencies": {
593 | "jiti": "^2.4.1"
594 | },
595 | "engines": {
596 | "node": ">=v18"
597 | },
598 | "peerDependencies": {
599 | "@types/node": "*",
600 | "cosmiconfig": ">=9",
601 | "typescript": ">=5"
602 | }
603 | },
604 | "node_modules/dargs": {
605 | "version": "8.1.0",
606 | "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
607 | "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
608 | "dev": true,
609 | "license": "MIT",
610 | "engines": {
611 | "node": ">=12"
612 | },
613 | "funding": {
614 | "url": "https://github.com/sponsors/sindresorhus"
615 | }
616 | },
617 | "node_modules/delayed-stream": {
618 | "version": "1.0.0",
619 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
620 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
621 | "license": "MIT",
622 | "engines": {
623 | "node": ">=0.4.0"
624 | }
625 | },
626 | "node_modules/depd": {
627 | "version": "2.0.0",
628 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
629 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
630 | "license": "MIT",
631 | "engines": {
632 | "node": ">= 0.8"
633 | }
634 | },
635 | "node_modules/dot-prop": {
636 | "version": "5.3.0",
637 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
638 | "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
639 | "dev": true,
640 | "license": "MIT",
641 | "dependencies": {
642 | "is-obj": "^2.0.0"
643 | },
644 | "engines": {
645 | "node": ">=8"
646 | }
647 | },
648 | "node_modules/emoji-regex": {
649 | "version": "8.0.0",
650 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
651 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
652 | "dev": true,
653 | "license": "MIT"
654 | },
655 | "node_modules/env-paths": {
656 | "version": "2.2.1",
657 | "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
658 | "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
659 | "dev": true,
660 | "license": "MIT",
661 | "engines": {
662 | "node": ">=6"
663 | }
664 | },
665 | "node_modules/error-ex": {
666 | "version": "1.3.2",
667 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
668 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
669 | "dev": true,
670 | "license": "MIT",
671 | "dependencies": {
672 | "is-arrayish": "^0.2.1"
673 | }
674 | },
675 | "node_modules/escalade": {
676 | "version": "3.2.0",
677 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
678 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
679 | "dev": true,
680 | "license": "MIT",
681 | "engines": {
682 | "node": ">=6"
683 | }
684 | },
685 | "node_modules/fast-deep-equal": {
686 | "version": "3.1.3",
687 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
688 | "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
689 | "dev": true,
690 | "license": "MIT"
691 | },
692 | "node_modules/fast-uri": {
693 | "version": "3.0.6",
694 | "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
695 | "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
696 | "dev": true,
697 | "funding": [
698 | {
699 | "type": "github",
700 | "url": "https://github.com/sponsors/fastify"
701 | },
702 | {
703 | "type": "opencollective",
704 | "url": "https://opencollective.com/fastify"
705 | }
706 | ],
707 | "license": "BSD-3-Clause"
708 | },
709 | "node_modules/find-up": {
710 | "version": "7.0.0",
711 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
712 | "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
713 | "dev": true,
714 | "license": "MIT",
715 | "dependencies": {
716 | "locate-path": "^7.2.0",
717 | "path-exists": "^5.0.0",
718 | "unicorn-magic": "^0.1.0"
719 | },
720 | "engines": {
721 | "node": ">=18"
722 | },
723 | "funding": {
724 | "url": "https://github.com/sponsors/sindresorhus"
725 | }
726 | },
727 | "node_modules/follow-redirects": {
728 | "version": "1.15.9",
729 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
730 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
731 | "funding": [
732 | {
733 | "type": "individual",
734 | "url": "https://github.com/sponsors/RubenVerborgh"
735 | }
736 | ],
737 | "license": "MIT",
738 | "engines": {
739 | "node": ">=4.0"
740 | },
741 | "peerDependenciesMeta": {
742 | "debug": {
743 | "optional": true
744 | }
745 | }
746 | },
747 | "node_modules/form-data": {
748 | "version": "4.0.1",
749 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz",
750 | "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
751 | "license": "MIT",
752 | "dependencies": {
753 | "asynckit": "^0.4.0",
754 | "combined-stream": "^1.0.8",
755 | "mime-types": "^2.1.12"
756 | },
757 | "engines": {
758 | "node": ">= 6"
759 | }
760 | },
761 | "node_modules/get-caller-file": {
762 | "version": "2.0.5",
763 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
764 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
765 | "dev": true,
766 | "license": "ISC",
767 | "engines": {
768 | "node": "6.* || 8.* || >= 10.*"
769 | }
770 | },
771 | "node_modules/git-raw-commits": {
772 | "version": "4.0.0",
773 | "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
774 | "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
775 | "dev": true,
776 | "license": "MIT",
777 | "dependencies": {
778 | "dargs": "^8.0.0",
779 | "meow": "^12.0.1",
780 | "split2": "^4.0.0"
781 | },
782 | "bin": {
783 | "git-raw-commits": "cli.mjs"
784 | },
785 | "engines": {
786 | "node": ">=16"
787 | }
788 | },
789 | "node_modules/global-directory": {
790 | "version": "4.0.1",
791 | "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
792 | "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
793 | "dev": true,
794 | "license": "MIT",
795 | "dependencies": {
796 | "ini": "4.1.1"
797 | },
798 | "engines": {
799 | "node": ">=18"
800 | },
801 | "funding": {
802 | "url": "https://github.com/sponsors/sindresorhus"
803 | }
804 | },
805 | "node_modules/http-errors": {
806 | "version": "2.0.0",
807 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
808 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==",
809 | "license": "MIT",
810 | "dependencies": {
811 | "depd": "2.0.0",
812 | "inherits": "2.0.4",
813 | "setprototypeof": "1.2.0",
814 | "statuses": "2.0.1",
815 | "toidentifier": "1.0.1"
816 | },
817 | "engines": {
818 | "node": ">= 0.8"
819 | }
820 | },
821 | "node_modules/iconv-lite": {
822 | "version": "0.6.3",
823 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
824 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
825 | "license": "MIT",
826 | "dependencies": {
827 | "safer-buffer": ">= 2.1.2 < 3.0.0"
828 | },
829 | "engines": {
830 | "node": ">=0.10.0"
831 | }
832 | },
833 | "node_modules/import-fresh": {
834 | "version": "3.3.0",
835 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
836 | "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
837 | "dev": true,
838 | "license": "MIT",
839 | "dependencies": {
840 | "parent-module": "^1.0.0",
841 | "resolve-from": "^4.0.0"
842 | },
843 | "engines": {
844 | "node": ">=6"
845 | },
846 | "funding": {
847 | "url": "https://github.com/sponsors/sindresorhus"
848 | }
849 | },
850 | "node_modules/import-fresh/node_modules/resolve-from": {
851 | "version": "4.0.0",
852 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
853 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
854 | "dev": true,
855 | "license": "MIT",
856 | "engines": {
857 | "node": ">=4"
858 | }
859 | },
860 | "node_modules/import-meta-resolve": {
861 | "version": "4.1.0",
862 | "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz",
863 | "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==",
864 | "dev": true,
865 | "license": "MIT",
866 | "funding": {
867 | "type": "github",
868 | "url": "https://github.com/sponsors/wooorm"
869 | }
870 | },
871 | "node_modules/inherits": {
872 | "version": "2.0.4",
873 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
874 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
875 | "license": "ISC"
876 | },
877 | "node_modules/ini": {
878 | "version": "4.1.1",
879 | "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
880 | "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
881 | "dev": true,
882 | "license": "ISC",
883 | "engines": {
884 | "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
885 | }
886 | },
887 | "node_modules/is-arrayish": {
888 | "version": "0.2.1",
889 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
890 | "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
891 | "dev": true,
892 | "license": "MIT"
893 | },
894 | "node_modules/is-fullwidth-code-point": {
895 | "version": "3.0.0",
896 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
897 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
898 | "dev": true,
899 | "license": "MIT",
900 | "engines": {
901 | "node": ">=8"
902 | }
903 | },
904 | "node_modules/is-obj": {
905 | "version": "2.0.0",
906 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
907 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
908 | "dev": true,
909 | "license": "MIT",
910 | "engines": {
911 | "node": ">=8"
912 | }
913 | },
914 | "node_modules/is-text-path": {
915 | "version": "2.0.0",
916 | "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
917 | "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
918 | "dev": true,
919 | "license": "MIT",
920 | "dependencies": {
921 | "text-extensions": "^2.0.0"
922 | },
923 | "engines": {
924 | "node": ">=8"
925 | }
926 | },
927 | "node_modules/jiti": {
928 | "version": "2.4.2",
929 | "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
930 | "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
931 | "dev": true,
932 | "license": "MIT",
933 | "bin": {
934 | "jiti": "lib/jiti-cli.mjs"
935 | }
936 | },
937 | "node_modules/js-tokens": {
938 | "version": "4.0.0",
939 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
940 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
941 | "dev": true,
942 | "license": "MIT"
943 | },
944 | "node_modules/js-yaml": {
945 | "version": "4.1.0",
946 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
947 | "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
948 | "dev": true,
949 | "license": "MIT",
950 | "dependencies": {
951 | "argparse": "^2.0.1"
952 | },
953 | "bin": {
954 | "js-yaml": "bin/js-yaml.js"
955 | }
956 | },
957 | "node_modules/json-parse-even-better-errors": {
958 | "version": "2.3.1",
959 | "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
960 | "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
961 | "dev": true,
962 | "license": "MIT"
963 | },
964 | "node_modules/json-schema-traverse": {
965 | "version": "1.0.0",
966 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
967 | "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
968 | "dev": true,
969 | "license": "MIT"
970 | },
971 | "node_modules/jsonparse": {
972 | "version": "1.3.1",
973 | "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
974 | "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
975 | "dev": true,
976 | "engines": [
977 | "node >= 0.2.0"
978 | ],
979 | "license": "MIT"
980 | },
981 | "node_modules/JSONStream": {
982 | "version": "1.3.5",
983 | "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
984 | "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
985 | "dev": true,
986 | "license": "(MIT OR Apache-2.0)",
987 | "dependencies": {
988 | "jsonparse": "^1.2.0",
989 | "through": ">=2.2.7 <3"
990 | },
991 | "bin": {
992 | "JSONStream": "bin.js"
993 | },
994 | "engines": {
995 | "node": "*"
996 | }
997 | },
998 | "node_modules/lines-and-columns": {
999 | "version": "1.2.4",
1000 | "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
1001 | "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
1002 | "dev": true,
1003 | "license": "MIT"
1004 | },
1005 | "node_modules/locate-path": {
1006 | "version": "7.2.0",
1007 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
1008 | "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
1009 | "dev": true,
1010 | "license": "MIT",
1011 | "dependencies": {
1012 | "p-locate": "^6.0.0"
1013 | },
1014 | "engines": {
1015 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1016 | },
1017 | "funding": {
1018 | "url": "https://github.com/sponsors/sindresorhus"
1019 | }
1020 | },
1021 | "node_modules/lodash.camelcase": {
1022 | "version": "4.3.0",
1023 | "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
1024 | "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
1025 | "dev": true,
1026 | "license": "MIT"
1027 | },
1028 | "node_modules/lodash.isplainobject": {
1029 | "version": "4.0.6",
1030 | "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
1031 | "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
1032 | "dev": true,
1033 | "license": "MIT"
1034 | },
1035 | "node_modules/lodash.kebabcase": {
1036 | "version": "4.1.1",
1037 | "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
1038 | "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
1039 | "dev": true,
1040 | "license": "MIT"
1041 | },
1042 | "node_modules/lodash.merge": {
1043 | "version": "4.6.2",
1044 | "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
1045 | "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
1046 | "dev": true,
1047 | "license": "MIT"
1048 | },
1049 | "node_modules/lodash.mergewith": {
1050 | "version": "4.6.2",
1051 | "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
1052 | "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
1053 | "dev": true,
1054 | "license": "MIT"
1055 | },
1056 | "node_modules/lodash.snakecase": {
1057 | "version": "4.1.1",
1058 | "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
1059 | "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
1060 | "dev": true,
1061 | "license": "MIT"
1062 | },
1063 | "node_modules/lodash.startcase": {
1064 | "version": "4.4.0",
1065 | "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
1066 | "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
1067 | "dev": true,
1068 | "license": "MIT"
1069 | },
1070 | "node_modules/lodash.uniq": {
1071 | "version": "4.5.0",
1072 | "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
1073 | "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
1074 | "dev": true,
1075 | "license": "MIT"
1076 | },
1077 | "node_modules/lodash.upperfirst": {
1078 | "version": "4.3.1",
1079 | "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
1080 | "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
1081 | "dev": true,
1082 | "license": "MIT"
1083 | },
1084 | "node_modules/meow": {
1085 | "version": "12.1.1",
1086 | "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
1087 | "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
1088 | "dev": true,
1089 | "license": "MIT",
1090 | "engines": {
1091 | "node": ">=16.10"
1092 | },
1093 | "funding": {
1094 | "url": "https://github.com/sponsors/sindresorhus"
1095 | }
1096 | },
1097 | "node_modules/mime-db": {
1098 | "version": "1.52.0",
1099 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
1100 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
1101 | "license": "MIT",
1102 | "engines": {
1103 | "node": ">= 0.6"
1104 | }
1105 | },
1106 | "node_modules/mime-types": {
1107 | "version": "2.1.35",
1108 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
1109 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
1110 | "license": "MIT",
1111 | "dependencies": {
1112 | "mime-db": "1.52.0"
1113 | },
1114 | "engines": {
1115 | "node": ">= 0.6"
1116 | }
1117 | },
1118 | "node_modules/minimist": {
1119 | "version": "1.2.8",
1120 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1121 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1122 | "dev": true,
1123 | "license": "MIT",
1124 | "funding": {
1125 | "url": "https://github.com/sponsors/ljharb"
1126 | }
1127 | },
1128 | "node_modules/p-limit": {
1129 | "version": "4.0.0",
1130 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
1131 | "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
1132 | "dev": true,
1133 | "license": "MIT",
1134 | "dependencies": {
1135 | "yocto-queue": "^1.0.0"
1136 | },
1137 | "engines": {
1138 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1139 | },
1140 | "funding": {
1141 | "url": "https://github.com/sponsors/sindresorhus"
1142 | }
1143 | },
1144 | "node_modules/p-locate": {
1145 | "version": "6.0.0",
1146 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
1147 | "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
1148 | "dev": true,
1149 | "license": "MIT",
1150 | "dependencies": {
1151 | "p-limit": "^4.0.0"
1152 | },
1153 | "engines": {
1154 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1155 | },
1156 | "funding": {
1157 | "url": "https://github.com/sponsors/sindresorhus"
1158 | }
1159 | },
1160 | "node_modules/parent-module": {
1161 | "version": "1.0.1",
1162 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
1163 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
1164 | "dev": true,
1165 | "license": "MIT",
1166 | "dependencies": {
1167 | "callsites": "^3.0.0"
1168 | },
1169 | "engines": {
1170 | "node": ">=6"
1171 | }
1172 | },
1173 | "node_modules/parse-json": {
1174 | "version": "5.2.0",
1175 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
1176 | "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
1177 | "dev": true,
1178 | "license": "MIT",
1179 | "dependencies": {
1180 | "@babel/code-frame": "^7.0.0",
1181 | "error-ex": "^1.3.1",
1182 | "json-parse-even-better-errors": "^2.3.0",
1183 | "lines-and-columns": "^1.1.6"
1184 | },
1185 | "engines": {
1186 | "node": ">=8"
1187 | },
1188 | "funding": {
1189 | "url": "https://github.com/sponsors/sindresorhus"
1190 | }
1191 | },
1192 | "node_modules/path-exists": {
1193 | "version": "5.0.0",
1194 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
1195 | "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
1196 | "dev": true,
1197 | "license": "MIT",
1198 | "engines": {
1199 | "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1200 | }
1201 | },
1202 | "node_modules/picocolors": {
1203 | "version": "1.1.1",
1204 | "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1205 | "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1206 | "dev": true,
1207 | "license": "ISC"
1208 | },
1209 | "node_modules/proxy-from-env": {
1210 | "version": "1.1.0",
1211 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
1212 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
1213 | "license": "MIT"
1214 | },
1215 | "node_modules/raw-body": {
1216 | "version": "3.0.0",
1217 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz",
1218 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==",
1219 | "license": "MIT",
1220 | "dependencies": {
1221 | "bytes": "3.1.2",
1222 | "http-errors": "2.0.0",
1223 | "iconv-lite": "0.6.3",
1224 | "unpipe": "1.0.0"
1225 | },
1226 | "engines": {
1227 | "node": ">= 0.8"
1228 | }
1229 | },
1230 | "node_modules/require-directory": {
1231 | "version": "2.1.1",
1232 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
1233 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
1234 | "dev": true,
1235 | "license": "MIT",
1236 | "engines": {
1237 | "node": ">=0.10.0"
1238 | }
1239 | },
1240 | "node_modules/require-from-string": {
1241 | "version": "2.0.2",
1242 | "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
1243 | "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
1244 | "dev": true,
1245 | "license": "MIT",
1246 | "engines": {
1247 | "node": ">=0.10.0"
1248 | }
1249 | },
1250 | "node_modules/resolve-from": {
1251 | "version": "5.0.0",
1252 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
1253 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
1254 | "dev": true,
1255 | "license": "MIT",
1256 | "engines": {
1257 | "node": ">=8"
1258 | }
1259 | },
1260 | "node_modules/safer-buffer": {
1261 | "version": "2.1.2",
1262 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
1263 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1264 | "license": "MIT"
1265 | },
1266 | "node_modules/semver": {
1267 | "version": "7.7.0",
1268 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz",
1269 | "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==",
1270 | "dev": true,
1271 | "license": "ISC",
1272 | "bin": {
1273 | "semver": "bin/semver.js"
1274 | },
1275 | "engines": {
1276 | "node": ">=10"
1277 | }
1278 | },
1279 | "node_modules/setprototypeof": {
1280 | "version": "1.2.0",
1281 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
1282 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1283 | "license": "ISC"
1284 | },
1285 | "node_modules/split2": {
1286 | "version": "4.2.0",
1287 | "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
1288 | "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
1289 | "dev": true,
1290 | "license": "ISC",
1291 | "engines": {
1292 | "node": ">= 10.x"
1293 | }
1294 | },
1295 | "node_modules/statuses": {
1296 | "version": "2.0.1",
1297 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
1298 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==",
1299 | "license": "MIT",
1300 | "engines": {
1301 | "node": ">= 0.8"
1302 | }
1303 | },
1304 | "node_modules/string-width": {
1305 | "version": "4.2.3",
1306 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
1307 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
1308 | "dev": true,
1309 | "license": "MIT",
1310 | "dependencies": {
1311 | "emoji-regex": "^8.0.0",
1312 | "is-fullwidth-code-point": "^3.0.0",
1313 | "strip-ansi": "^6.0.1"
1314 | },
1315 | "engines": {
1316 | "node": ">=8"
1317 | }
1318 | },
1319 | "node_modules/strip-ansi": {
1320 | "version": "6.0.1",
1321 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
1322 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
1323 | "dev": true,
1324 | "license": "MIT",
1325 | "dependencies": {
1326 | "ansi-regex": "^5.0.1"
1327 | },
1328 | "engines": {
1329 | "node": ">=8"
1330 | }
1331 | },
1332 | "node_modules/text-extensions": {
1333 | "version": "2.4.0",
1334 | "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
1335 | "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
1336 | "dev": true,
1337 | "license": "MIT",
1338 | "engines": {
1339 | "node": ">=8"
1340 | },
1341 | "funding": {
1342 | "url": "https://github.com/sponsors/sindresorhus"
1343 | }
1344 | },
1345 | "node_modules/through": {
1346 | "version": "2.3.8",
1347 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
1348 | "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
1349 | "dev": true,
1350 | "license": "MIT"
1351 | },
1352 | "node_modules/tinyexec": {
1353 | "version": "0.3.2",
1354 | "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
1355 | "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
1356 | "dev": true,
1357 | "license": "MIT"
1358 | },
1359 | "node_modules/toidentifier": {
1360 | "version": "1.0.1",
1361 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
1362 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
1363 | "license": "MIT",
1364 | "engines": {
1365 | "node": ">=0.6"
1366 | }
1367 | },
1368 | "node_modules/typescript": {
1369 | "version": "5.7.2",
1370 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz",
1371 | "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==",
1372 | "dev": true,
1373 | "license": "Apache-2.0",
1374 | "bin": {
1375 | "tsc": "bin/tsc",
1376 | "tsserver": "bin/tsserver"
1377 | },
1378 | "engines": {
1379 | "node": ">=14.17"
1380 | }
1381 | },
1382 | "node_modules/undici-types": {
1383 | "version": "6.19.8",
1384 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
1385 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
1386 | "dev": true,
1387 | "license": "MIT"
1388 | },
1389 | "node_modules/unicorn-magic": {
1390 | "version": "0.1.0",
1391 | "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
1392 | "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
1393 | "dev": true,
1394 | "license": "MIT",
1395 | "engines": {
1396 | "node": ">=18"
1397 | },
1398 | "funding": {
1399 | "url": "https://github.com/sponsors/sindresorhus"
1400 | }
1401 | },
1402 | "node_modules/unpipe": {
1403 | "version": "1.0.0",
1404 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
1405 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
1406 | "license": "MIT",
1407 | "engines": {
1408 | "node": ">= 0.8"
1409 | }
1410 | },
1411 | "node_modules/wrap-ansi": {
1412 | "version": "7.0.0",
1413 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
1414 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
1415 | "dev": true,
1416 | "license": "MIT",
1417 | "dependencies": {
1418 | "ansi-styles": "^4.0.0",
1419 | "string-width": "^4.1.0",
1420 | "strip-ansi": "^6.0.0"
1421 | },
1422 | "engines": {
1423 | "node": ">=10"
1424 | },
1425 | "funding": {
1426 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
1427 | }
1428 | },
1429 | "node_modules/y18n": {
1430 | "version": "5.0.8",
1431 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
1432 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
1433 | "dev": true,
1434 | "license": "ISC",
1435 | "engines": {
1436 | "node": ">=10"
1437 | }
1438 | },
1439 | "node_modules/yargs": {
1440 | "version": "17.7.2",
1441 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
1442 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
1443 | "dev": true,
1444 | "license": "MIT",
1445 | "dependencies": {
1446 | "cliui": "^8.0.1",
1447 | "escalade": "^3.1.1",
1448 | "get-caller-file": "^2.0.5",
1449 | "require-directory": "^2.1.1",
1450 | "string-width": "^4.2.3",
1451 | "y18n": "^5.0.5",
1452 | "yargs-parser": "^21.1.1"
1453 | },
1454 | "engines": {
1455 | "node": ">=12"
1456 | }
1457 | },
1458 | "node_modules/yargs-parser": {
1459 | "version": "21.1.1",
1460 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
1461 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
1462 | "dev": true,
1463 | "license": "ISC",
1464 | "engines": {
1465 | "node": ">=12"
1466 | }
1467 | },
1468 | "node_modules/yocto-queue": {
1469 | "version": "1.1.1",
1470 | "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
1471 | "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
1472 | "dev": true,
1473 | "license": "MIT",
1474 | "engines": {
1475 | "node": ">=12.20"
1476 | },
1477 | "funding": {
1478 | "url": "https://github.com/sponsors/sindresorhus"
1479 | }
1480 | },
1481 | "node_modules/zod": {
1482 | "version": "3.24.1",
1483 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.1.tgz",
1484 | "integrity": "sha512-muH7gBL9sI1nciMZV67X5fTKKBLtwpZ5VBp1vsOQzj1MhrBZ4wlVCm3gedKZWLp0Oyel8sIGfeiz54Su+OVT+A==",
1485 | "license": "MIT",
1486 | "funding": {
1487 | "url": "https://github.com/sponsors/colinhacks"
1488 | }
1489 | }
1490 | }
1491 | }
1492 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dkmaker-mcp-rest-api",
3 | "version": "0.4.0",
4 | "description": "A generic REST API tester for testing HTTP endpoints",
5 | "license": "MIT",
6 | "type": "module",
7 | "bin": {
8 | "dkmaker-mcp-rest-api": "./build/index.js"
9 | },
10 | "files": [
11 | "build",
12 | "README.md",
13 | "LICENSE"
14 | ],
15 | "scripts": {
16 | "prebuild": "node scripts/build.js",
17 | "build": "tsc",
18 | "prepare": "npm run build",
19 | "watch": "tsc --watch",
20 | "inspector": "npx @modelcontextprotocol/inspector build/index.js"
21 | },
22 | "dependencies": {
23 | "@modelcontextprotocol/sdk": "^1.0.4",
24 | "axios": "^1.7.9"
25 | },
26 | "devDependencies": {
27 | "@commitlint/cli": "^19.6.1",
28 | "@commitlint/config-conventional": "^19.6.0",
29 | "@types/node": "^20.11.24",
30 | "typescript": "^5.3.3"
31 | },
32 | "keywords": [
33 | "mcp",
34 | "rest",
35 | "api",
36 | "http",
37 | "testing",
38 | "cline",
39 | "development",
40 | "typescript"
41 | ],
42 | "author": "zenturacp",
43 | "repository": {
44 | "type": "git",
45 | "url": "git+https://github.com/dkmaker/mcp-rest-api.git"
46 | },
47 | "bugs": {
48 | "url": "https://github.com/dkmaker/mcp-rest-api/issues"
49 | },
50 | "homepage": "https://github.com/dkmaker/mcp-rest-api#readme",
51 | "engines": {
52 | "node": ">=18.0.0"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/scripts/build.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import fs from 'fs/promises';
3 | import path from 'path';
4 | import { fileURLToPath } from 'url';
5 |
6 | const __filename = fileURLToPath(import.meta.url);
7 | const __dirname = path.dirname(__filename);
8 |
9 | async function main() {
10 | const pkg = JSON.parse(
11 | await fs.readFile(
12 | path.join(__dirname, '..', 'package.json'),
13 | 'utf8'
14 | )
15 | );
16 |
17 | const versionPath = path.join(__dirname, '..', 'src', 'version.ts');
18 |
19 | // Always generate version.ts with actual values during build
20 | const content = `// Auto-generated by build script
21 | export const VERSION = '${pkg.version}';
22 | export const PACKAGE_NAME = '${pkg.name}';
23 | export const SERVER_NAME = '${pkg.name.split('-').slice(-2).join('-')}';
24 | `;
25 |
26 | await fs.writeFile(versionPath, content);
27 | console.log('Generated version.ts with package values');
28 |
29 | // Copy resources to build directory
30 | const resourcesSrcDir = path.join(__dirname, '..', 'src', 'resources');
31 | const resourcesBuildDir = path.join(__dirname, '..', 'build', 'resources');
32 |
33 | try {
34 | await fs.mkdir(resourcesBuildDir, { recursive: true });
35 | const files = await fs.readdir(resourcesSrcDir);
36 |
37 | for (const file of files) {
38 | await fs.copyFile(
39 | path.join(resourcesSrcDir, file),
40 | path.join(resourcesBuildDir, file)
41 | );
42 | }
43 | console.log('Copied resources to build directory');
44 | } catch (error) {
45 | console.error('Error copying resources:', error);
46 | throw error;
47 | }
48 | }
49 |
50 | main().catch(console.error);
51 |
--------------------------------------------------------------------------------
/smithery.yaml:
--------------------------------------------------------------------------------
1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml
2 |
3 | startCommand:
4 | type: stdio
5 | configSchema:
6 | # JSON Schema defining the configuration options for the MCP.
7 | type: object
8 | required:
9 | - restBaseUrl
10 | properties:
11 | restBaseUrl:
12 | type: string
13 | description: The base URL for the REST API.
14 | authBasicUsername:
15 | type: string
16 | description: The username for Basic Authentication.
17 | authBasicPassword:
18 | type: string
19 | description: The password for Basic Authentication.
20 | authBearer:
21 | type: string
22 | description: The bearer token for authentication.
23 | authApiKeyHeaderName:
24 | type: string
25 | description: The header name for API Key Authentication.
26 | authApiKeyValue:
27 | type: string
28 | description: The API key value for API Key Authentication.
29 | restEnableSslVerify:
30 | type: boolean
31 | default: true
32 | description: Enable or disable SSL verification.
33 | restResponseSizeLimit:
34 | type: number
35 | default: 10000
36 | description: The maximum response size limit in bytes.
37 | commandFunction:
38 | # A function that produces the CLI command to start the MCP on stdio.
39 | |-
40 | config => ({ command: 'node', args: ['build/index.js'], env: { REST_BASE_URL: config.restBaseUrl, AUTH_BASIC_USERNAME: config.authBasicUsername, AUTH_BASIC_PASSWORD: config.authBasicPassword, AUTH_BEARER: config.authBearer, AUTH_APIKEY_HEADER_NAME: config.authApiKeyHeaderName, AUTH_APIKEY_VALUE: config.authApiKeyValue, REST_ENABLE_SSL_VERIFY: config.restEnableSslVerify.toString(), REST_RESPONSE_SIZE_LIMIT: config.restResponseSizeLimit.toString() } })
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js';
3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
4 | import {
5 | CallToolRequestSchema,
6 | ErrorCode,
7 | ListToolsRequestSchema,
8 | ListResourcesRequestSchema,
9 | ReadResourceRequestSchema,
10 | McpError,
11 | } from '@modelcontextprotocol/sdk/types.js';
12 | import axios, { AxiosInstance, AxiosRequestConfig, Method } from 'axios';
13 | import { VERSION, SERVER_NAME } from './version.js';
14 |
15 | if (!process.env.REST_BASE_URL) {
16 | throw new Error('REST_BASE_URL environment variable is required');
17 | }
18 |
19 | // Default response size limit: 10KB (10000 bytes)
20 | const RESPONSE_SIZE_LIMIT = process.env.REST_RESPONSE_SIZE_LIMIT
21 | ? parseInt(process.env.REST_RESPONSE_SIZE_LIMIT, 10)
22 | : 10000;
23 |
24 | if (isNaN(RESPONSE_SIZE_LIMIT) || RESPONSE_SIZE_LIMIT <= 0) {
25 | throw new Error('REST_RESPONSE_SIZE_LIMIT must be a positive number');
26 | }
27 | const AUTH_BASIC_USERNAME = process.env.AUTH_BASIC_USERNAME;
28 | const AUTH_BASIC_PASSWORD = process.env.AUTH_BASIC_PASSWORD;
29 | const AUTH_BEARER = process.env.AUTH_BEARER;
30 | const AUTH_APIKEY_HEADER_NAME = process.env.AUTH_APIKEY_HEADER_NAME;
31 | const AUTH_APIKEY_VALUE = process.env.AUTH_APIKEY_VALUE;
32 | const REST_ENABLE_SSL_VERIFY = process.env.REST_ENABLE_SSL_VERIFY !== 'false';
33 |
34 | interface EndpointArgs {
35 | method: 'GET' | 'POST' | 'PUT' | 'DELETE';
36 | endpoint: string;
37 | body?: any;
38 | headers?: Record;
39 | }
40 |
41 | interface ValidationResult {
42 | isError: boolean;
43 | messages: string[];
44 | truncated?: {
45 | originalSize: number;
46 | returnedSize: number;
47 | truncationPoint: number;
48 | sizeLimit: number;
49 | };
50 | }
51 |
52 | // Function to sanitize headers by removing sensitive values and non-approved headers
53 | const sanitizeHeaders = (
54 | headers: Record,
55 | isFromOptionalParams: boolean = false
56 | ): Record => {
57 | const sanitized: Record = {};
58 |
59 | for (const [key, value] of Object.entries(headers)) {
60 | const lowerKey = key.toLowerCase();
61 |
62 | // Always include headers from optional parameters
63 | if (isFromOptionalParams) {
64 | sanitized[key] = value;
65 | continue;
66 | }
67 |
68 | // Handle authentication headers
69 | if (
70 | lowerKey === 'authorization' ||
71 | (AUTH_APIKEY_HEADER_NAME && lowerKey === AUTH_APIKEY_HEADER_NAME.toLowerCase())
72 | ) {
73 | sanitized[key] = '[REDACTED]';
74 | continue;
75 | }
76 |
77 | // For headers from config/env
78 | const customHeaders = getCustomHeaders();
79 | if (key in customHeaders) {
80 | // Show value only for headers that are in the approved list
81 | const safeHeaders = new Set([
82 | 'accept',
83 | 'accept-language',
84 | 'content-type',
85 | 'user-agent',
86 | 'cache-control',
87 | 'if-match',
88 | 'if-none-match',
89 | 'if-modified-since',
90 | 'if-unmodified-since'
91 | ]);
92 | const lowerKey = key.toLowerCase();
93 | sanitized[key] = safeHeaders.has(lowerKey) ? value : '[REDACTED]';
94 | }
95 | }
96 |
97 | return sanitized;
98 | };
99 |
100 | interface ResponseObject {
101 | request: {
102 | url: string;
103 | method: string;
104 | headers: Record;
105 | body: any;
106 | authMethod: string;
107 | };
108 | response: {
109 | statusCode: number;
110 | statusText: string;
111 | timing: string;
112 | headers: Record;
113 | body: any;
114 | };
115 | validation: ValidationResult;
116 | }
117 |
118 | const normalizeBaseUrl = (url: string): string => url.replace(/\/+$/, '');
119 |
120 | const isValidEndpointArgs = (args: any): args is EndpointArgs => {
121 | if (typeof args !== 'object' || args === null) return false;
122 | if (!['GET', 'POST', 'PUT', 'DELETE'].includes(args.method)) return false;
123 | if (typeof args.endpoint !== 'string') return false;
124 | if (args.headers !== undefined && (typeof args.headers !== 'object' || args.headers === null)) return false;
125 |
126 | // Check if endpoint contains a full URL
127 | const urlPattern = /^(https?:\/\/|www\.)/i;
128 | if (urlPattern.test(args.endpoint)) {
129 | throw new McpError(
130 | ErrorCode.InvalidParams,
131 | `Invalid endpoint format. Do not include full URLs. Instead of "${args.endpoint}", use just the path (e.g. "/api/users"). ` +
132 | `Your path will be resolved to: ${process.env.REST_BASE_URL}${args.endpoint.replace(/^\/+|\/+$/g, '')}. ` +
133 | `To test a different base URL, update the REST_BASE_URL environment variable.`
134 | );
135 | }
136 |
137 | return true;
138 | };
139 |
140 | const hasBasicAuth = () => AUTH_BASIC_USERNAME && AUTH_BASIC_PASSWORD;
141 | const hasBearerAuth = () => !!AUTH_BEARER;
142 | const hasApiKeyAuth = () => AUTH_APIKEY_HEADER_NAME && AUTH_APIKEY_VALUE;
143 |
144 | // Collect custom headers from environment variables
145 | const getCustomHeaders = (): Record => {
146 | const headers: Record = {};
147 | const headerPrefix = /^header_/i; // Case-insensitive match for 'header_'
148 |
149 | for (const [key, value] of Object.entries(process.env)) {
150 | if (headerPrefix.test(key) && value !== undefined) {
151 | // Extract header name after the prefix, preserving case
152 | const headerName = key.replace(headerPrefix, '');
153 | headers[headerName] = value;
154 | }
155 | }
156 |
157 | return headers;
158 | };
159 |
160 | class RestTester {
161 | private server!: Server;
162 | private axiosInstance!: AxiosInstance;
163 |
164 | constructor() {
165 | this.setupServer();
166 | }
167 |
168 | private async setupServer() {
169 | this.server = new Server(
170 | {
171 | name: SERVER_NAME,
172 | version: VERSION,
173 | },
174 | {
175 | capabilities: {
176 | tools: {},
177 | resources: {},
178 | },
179 | }
180 | );
181 |
182 | const https = await import('https');
183 | this.axiosInstance = axios.create({
184 | baseURL: normalizeBaseUrl(process.env.REST_BASE_URL!),
185 | validateStatus: () => true, // Allow any status code
186 | httpsAgent: REST_ENABLE_SSL_VERIFY ? undefined : new https.Agent({ // Disable SSL verification only when explicitly set to false
187 | rejectUnauthorized: false
188 | })
189 | });
190 |
191 | this.setupToolHandlers();
192 | this.setupResourceHandlers();
193 |
194 | this.server.onerror = (error) => console.error('[MCP Error]', error);
195 | process.on('SIGINT', async () => {
196 | await this.server.close();
197 | process.exit(0);
198 | });
199 | }
200 |
201 | private setupResourceHandlers() {
202 | this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
203 | resources: [
204 | {
205 | uri: `${SERVER_NAME}://examples`,
206 | name: 'REST API Usage Examples',
207 | description: 'Detailed examples of using the REST API testing tool',
208 | mimeType: 'text/markdown'
209 | },
210 | {
211 | uri: `${SERVER_NAME}://response-format`,
212 | name: 'Response Format Documentation',
213 | description: 'Documentation of the response format and structure',
214 | mimeType: 'text/markdown'
215 | },
216 | {
217 | uri: `${SERVER_NAME}://config`,
218 | name: 'Configuration Documentation',
219 | description: 'Documentation of all configuration options and how to use them',
220 | mimeType: 'text/markdown'
221 | }
222 | ]
223 | }));
224 |
225 | this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
226 | const uriPattern = new RegExp(`^${SERVER_NAME}://(.+)$`);
227 | const match = request.params.uri.match(uriPattern);
228 |
229 | if (!match) {
230 | throw new McpError(
231 | ErrorCode.InvalidRequest,
232 | `Invalid resource URI format: ${request.params.uri}`
233 | );
234 | }
235 |
236 | const resource = match[1];
237 | const fs = await import('fs');
238 | const path = await import('path');
239 |
240 | try {
241 | const url = await import('url');
242 | const __filename = url.fileURLToPath(import.meta.url);
243 | const __dirname = path.dirname(__filename);
244 |
245 | // In the built app, resources are in build/resources
246 | // In development, they're in src/resources
247 | const resourcePath = path.join(__dirname, 'resources', `${resource}.md`);
248 | const content = await fs.promises.readFile(resourcePath, 'utf8');
249 |
250 | return {
251 | contents: [{
252 | uri: request.params.uri,
253 | mimeType: 'text/markdown',
254 | text: content
255 | }]
256 | };
257 | } catch (error) {
258 | throw new McpError(
259 | ErrorCode.InvalidRequest,
260 | `Resource not found: ${resource}`
261 | );
262 | }
263 | });
264 | }
265 |
266 | private setupToolHandlers() {
267 | this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
268 | tools: [
269 | {
270 | name: 'test_request',
271 | description: `Test a REST API endpoint and get detailed response information. Base URL: ${normalizeBaseUrl(process.env.REST_BASE_URL!)} | SSL Verification ${REST_ENABLE_SSL_VERIFY ? 'enabled' : 'disabled'} (see config resource for SSL settings) | Authentication: ${
272 | hasBasicAuth() ?
273 | `Basic Auth with username: ${AUTH_BASIC_USERNAME}` :
274 | hasBearerAuth() ?
275 | 'Bearer token authentication configured' :
276 | hasApiKeyAuth() ?
277 | `API Key using header: ${AUTH_APIKEY_HEADER_NAME}` :
278 | 'No authentication configured'
279 | } | ${(() => {
280 | const customHeaders = getCustomHeaders();
281 | if (Object.keys(customHeaders).length === 0) {
282 | return 'No custom headers defined (see config resource for headers)';
283 | }
284 |
285 | // List of common headers that are safe to show values for
286 | const safeHeaders = new Set([
287 | 'accept',
288 | 'accept-language',
289 | 'content-type',
290 | 'user-agent',
291 | 'cache-control',
292 | 'if-match',
293 | 'if-none-match',
294 | 'if-modified-since',
295 | 'if-unmodified-since'
296 | ]);
297 |
298 | const headerList = Object.entries(customHeaders).map(([name, value]) => {
299 | const lowerName = name.toLowerCase();
300 | return safeHeaders.has(lowerName) ?
301 | `${name}(${value})` :
302 | name;
303 | }).join(', ');
304 |
305 | return `Custom headers defined: ${headerList} (see config resource for headers)`;
306 | })()} | The tool automatically: - Normalizes endpoints (adds leading slash, removes trailing slashes) - Handles authentication header injection - Applies custom headers from HEADER_* environment variables - Accepts any HTTP status code as valid - Limits response size to ${RESPONSE_SIZE_LIMIT} bytes (see config resource for size limit settings) - Returns detailed response information including: * Full URL called * Status code and text * Response headers * Response body * Request details (method, headers, body) * Response timing * Validation messages | Error Handling: - Network errors are caught and returned with descriptive messages - Invalid status codes are still returned with full response details - Authentication errors include the attempted auth method | See the config resource for all configuration options, including header configuration.
307 | `,
308 | inputSchema: {
309 | type: 'object',
310 | properties: {
311 | method: {
312 | type: 'string',
313 | enum: ['GET', 'POST', 'PUT', 'DELETE'],
314 | description: 'HTTP method to use',
315 | },
316 | endpoint: {
317 | type: 'string',
318 | description: `Endpoint path (e.g. "/users"). Do not include full URLs - only the path. Example: "/api/users" will resolve to "${normalizeBaseUrl(process.env.REST_BASE_URL!)}/api/users"`,
319 | },
320 | body: {
321 | type: 'object',
322 | description: 'Optional request body for POST/PUT requests',
323 | },
324 | headers: {
325 | type: 'object',
326 | description: 'Optional request headers for one-time use. IMPORTANT: Do not use for sensitive data like API keys - those should be configured via environment variables. This parameter is intended for dynamic, non-sensitive headers that may be needed for specific requests.',
327 | additionalProperties: {
328 | type: 'string'
329 | }
330 | }
331 | },
332 | required: ['method', 'endpoint'],
333 | },
334 | },
335 | ],
336 | }));
337 |
338 | this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
339 | if (request.params.name !== 'test_request') {
340 | throw new McpError(
341 | ErrorCode.MethodNotFound,
342 | `Unknown tool: ${request.params.name}`
343 | );
344 | }
345 |
346 | if (!isValidEndpointArgs(request.params.arguments)) {
347 | throw new McpError(
348 | ErrorCode.InvalidParams,
349 | 'Invalid test endpoint arguments'
350 | );
351 | }
352 |
353 | // Ensure endpoint starts with / and remove any trailing slashes
354 | const normalizedEndpoint = `/${request.params.arguments.endpoint.replace(/^\/+|\/+$/g, '')}`;
355 |
356 | // Initialize request config
357 | const config: AxiosRequestConfig = {
358 | method: request.params.arguments.method as Method,
359 | url: normalizedEndpoint,
360 | headers: {},
361 | };
362 |
363 | // Add request body for POST/PUT
364 | if (['POST', 'PUT'].includes(request.params.arguments.method) && request.params.arguments.body) {
365 | config.data = request.params.arguments.body;
366 | }
367 |
368 | // Apply headers in order of priority (lowest to highest)
369 |
370 | // 1. Custom global headers (lowest priority)
371 | const customHeaders = getCustomHeaders();
372 | config.headers = {
373 | ...customHeaders,
374 | ...config.headers,
375 | ...(request.params.arguments.headers || {}) // Request-specific headers (middle priority)
376 | };
377 |
378 | // 3. Authentication headers (highest priority)
379 | if (hasBasicAuth()) {
380 | const base64Credentials = Buffer.from(`${AUTH_BASIC_USERNAME}:${AUTH_BASIC_PASSWORD}`).toString('base64');
381 | config.headers = {
382 | ...config.headers,
383 | 'Authorization': `Basic ${base64Credentials}`
384 | };
385 | } else if (hasBearerAuth()) {
386 | config.headers = {
387 | ...config.headers,
388 | 'Authorization': `Bearer ${AUTH_BEARER}`
389 | };
390 | } else if (hasApiKeyAuth()) {
391 | config.headers = {
392 | ...config.headers,
393 | [AUTH_APIKEY_HEADER_NAME as string]: AUTH_APIKEY_VALUE
394 | };
395 | }
396 |
397 | try {
398 | const startTime = Date.now();
399 | const response = await this.axiosInstance.request(config);
400 | const endTime = Date.now();
401 | const fullUrl = `${process.env.REST_BASE_URL}${normalizedEndpoint}`;
402 |
403 | // Determine auth method used
404 | let authMethod = 'none';
405 | if (hasBasicAuth()) authMethod = 'basic';
406 | else if (hasBearerAuth()) authMethod = 'bearer';
407 | else if (hasApiKeyAuth()) authMethod = 'apikey';
408 |
409 | // Prepare response object
410 | const responseObj: ResponseObject = {
411 | request: {
412 | url: fullUrl,
413 | method: config.method || 'GET',
414 | headers: {
415 | ...sanitizeHeaders(config.headers as Record, false),
416 | ...sanitizeHeaders(request.params.arguments.headers || {}, true)
417 | },
418 | body: config.data,
419 | authMethod
420 | },
421 | response: {
422 | statusCode: response.status,
423 | statusText: response.statusText,
424 | timing: `${endTime - startTime}ms`,
425 | headers: sanitizeHeaders(response.headers as Record, false),
426 | body: response.data,
427 | },
428 | validation: {
429 | isError: response.status >= 400,
430 | messages: response.status >= 400 ?
431 | [`Request failed with status ${response.status}`] :
432 | ['Request completed successfully']
433 | }
434 | };
435 |
436 | // Check response body size independently
437 | const bodyStr = typeof response.data === 'string'
438 | ? response.data
439 | : JSON.stringify(response.data);
440 | const bodySize = Buffer.from(bodyStr).length;
441 |
442 | if (bodySize > RESPONSE_SIZE_LIMIT) {
443 | // Simply truncate to the size limit
444 | responseObj.response.body = bodyStr.slice(0, RESPONSE_SIZE_LIMIT);
445 | responseObj.validation.messages.push(
446 | `Response truncated: ${RESPONSE_SIZE_LIMIT} of ${bodySize} bytes returned due to size limit (${RESPONSE_SIZE_LIMIT} bytes)`
447 | );
448 | responseObj.validation.truncated = {
449 | originalSize: bodySize,
450 | returnedSize: RESPONSE_SIZE_LIMIT,
451 | truncationPoint: RESPONSE_SIZE_LIMIT,
452 | sizeLimit: RESPONSE_SIZE_LIMIT
453 | };
454 | }
455 |
456 | return {
457 | content: [
458 | {
459 | type: 'text',
460 | text: JSON.stringify(responseObj, null, 2),
461 | },
462 | ],
463 | };
464 | } catch (error) {
465 | if (axios.isAxiosError(error)) {
466 | return {
467 | content: [
468 | {
469 | type: 'text',
470 | text: JSON.stringify({
471 | error: {
472 | message: error.message,
473 | code: error.code,
474 | request: {
475 | url: `${process.env.REST_BASE_URL}${normalizedEndpoint}`,
476 | method: config.method,
477 | headers: {
478 | ...sanitizeHeaders(config.headers as Record, false),
479 | ...sanitizeHeaders(request.params.arguments.headers || {}, true)
480 | },
481 | body: config.data
482 | }
483 | }
484 | }, null, 2),
485 | },
486 | ],
487 | isError: true,
488 | };
489 | }
490 | throw error;
491 | }
492 | });
493 | }
494 |
495 | async run() {
496 | await this.setupServer();
497 | const transport = new StdioServerTransport();
498 | await this.server.connect(transport);
499 | console.error('REST API Tester MCP server running on stdio');
500 | }
501 | }
502 |
503 | const server = new RestTester();
504 | server.run().catch(console.error);
505 |
--------------------------------------------------------------------------------
/src/resources/config.md:
--------------------------------------------------------------------------------
1 | # REST API Tester Configuration
2 |
3 | This document describes all available configuration options for the REST API testing tool.
4 |
5 | ## Core Configuration
6 |
7 | ### REST_BASE_URL (Required)
8 | - Description: The base URL that all endpoint paths will be resolved against
9 | - Example: `http://localhost:3000` or `https://api.example.com`
10 | - Usage: All endpoint paths will be appended to this URL. For example, if REST_BASE_URL is `http://localhost:3000` and you use the endpoint `/api/users`, the full URL will be `http://localhost:3000/api/users`
11 |
12 | ### REST_RESPONSE_SIZE_LIMIT (Optional)
13 | - Description: Maximum size in bytes for response data
14 | - Default: 10000 (10KB)
15 | - Example: `50000` for 50KB limit
16 | - Usage: Helps prevent memory issues with large responses. If a response exceeds this size, it will be truncated and a warning message will be included
17 |
18 | ### REST_ENABLE_SSL_VERIFY (Optional)
19 | - Description: Controls SSL certificate verification
20 | - Default: `true`
21 | - Values: Set to `false` to disable SSL verification for self-signed certificates
22 | - Usage: Disable when testing APIs with self-signed certificates in development environments
23 |
24 | ## Custom Headers Configuration
25 |
26 | ### Custom Headers (Optional)
27 | - Description: Add custom headers to all requests using environment variables
28 | - Pattern: `HEADER_=` (prefix is case-insensitive)
29 | - Examples:
30 | ```bash
31 | HEADER_X-API-Version=2.0
32 | header_Custom-Client=my-client
33 | HeAdEr_Accept=application/json
34 | ```
35 | - Usage: Headers are added to all requests. The header name after `HEADER_` preserves its exact case
36 | - Priority: Per-request headers > Authentication headers > Custom global headers
37 |
38 | ## Authentication Configuration
39 |
40 | The tool supports three authentication methods. Configure one based on your API's requirements.
41 |
42 | ### Basic Authentication
43 | - REST_BASIC_USERNAME: Username for Basic Auth
44 | - REST_BASIC_PASSWORD: Password for Basic Auth
45 | - Usage: When both are set, requests will include Basic Auth header
46 |
47 | ### Bearer Token
48 | - REST_BEARER: Bearer token value
49 | - Usage: When set, requests will include `Authorization: Bearer ` header
50 |
51 | ### API Key
52 | - REST_APIKEY_HEADER_NAME: Name of the header for API key
53 | - REST_APIKEY_VALUE: Value of the API key
54 | - Example:
55 | ```
56 | REST_APIKEY_HEADER_NAME=X-API-Key
57 | REST_APIKEY_VALUE=your-api-key-here
58 | ```
59 | - Usage: When both are set, requests will include the specified header with the API key
60 |
61 | ## Configuration Examples
62 |
63 | ### Local Development
64 | ```bash
65 | REST_BASE_URL=http://localhost:3000
66 | REST_ENABLE_SSL_VERIFY=false
67 | REST_RESPONSE_SIZE_LIMIT=50000
68 | ```
69 |
70 | ### Production API with Bearer Token
71 | ```bash
72 | REST_BASE_URL=https://api.example.com
73 | REST_BEARER=your-bearer-token
74 | ```
75 |
76 | ### API with Basic Auth
77 | ```bash
78 | REST_BASE_URL=https://api.example.com
79 | REST_BASIC_USERNAME=admin
80 | REST_BASIC_PASSWORD=secret
81 | ```
82 |
83 | ### API with API Key
84 | ```bash
85 | REST_BASE_URL=https://api.example.com
86 | REST_APIKEY_HEADER_NAME=X-API-Key
87 | REST_APIKEY_VALUE=your-api-key
88 | ```
89 |
90 | ### API with Custom Headers
91 | ```bash
92 | REST_BASE_URL=https://api.example.com
93 | HEADER_X-API-Version=2.0
94 | HEADER_Custom-Client=my-client
95 | HEADER_Accept=application/json
96 | ```
97 |
98 | ## Changing Configuration
99 |
100 | Configuration can be updated by:
101 | 1. Setting environment variables before starting the server
102 | 2. Modifying the MCP server configuration file
103 | 3. Using environment variable commands in your terminal
104 |
105 | Remember to restart the server after changing configuration for the changes to take effect.
106 |
--------------------------------------------------------------------------------
/src/resources/examples.md:
--------------------------------------------------------------------------------
1 | # REST API Testing Examples
2 |
3 | ⚠️ IMPORTANT: Only provide the endpoint path - do not include full URLs. Your path will be automatically resolved to the full URL.
4 |
5 | For example, if the base URL is `http://localhost:3000`:
6 | ✅ Correct: `"/api/users"` → Resolves to: `http://localhost:3000/api/users`
7 | ❌ Incorrect: `"http://localhost:3000/api/users"` or `"www.example.com/api/users"`
8 |
9 | ## Basic GET Request
10 | ```typescript
11 | use_mcp_tool('rest-api', 'test_request', {
12 | "method": "GET",
13 | "endpoint": "/users" // Will be appended to REST_BASE_URL
14 | });
15 | ```
16 |
17 | ## GET with Query Parameters
18 | ```typescript
19 | use_mcp_tool('rest-api', 'test_request', {
20 | "method": "GET",
21 | "endpoint": "/users?role=admin&status=active"
22 | });
23 | ```
24 |
25 | ## POST Request with Body
26 | ```typescript
27 | use_mcp_tool('rest-api', 'test_request', {
28 | "method": "POST",
29 | "endpoint": "/users",
30 | "body": {
31 | "name": "John Doe",
32 | "email": "john@example.com"
33 | }
34 | });
35 | ```
36 |
37 | ## Request with Custom Headers
38 | ```typescript
39 | use_mcp_tool('rest-api', 'test_request', {
40 | "method": "GET",
41 | "endpoint": "/secure-resource",
42 | "headers": {
43 | "Custom-Header": "value",
44 | "Another-Header": "another-value"
45 | }
46 | });
47 | ```
48 |
49 | ## PUT Request Example
50 | ```typescript
51 | use_mcp_tool('rest-api', 'test_request', {
52 | "method": "PUT",
53 | "endpoint": "/users/123",
54 | "body": {
55 | "name": "Updated Name",
56 | "status": "inactive"
57 | }
58 | });
59 | ```
60 |
61 | ## DELETE Request Example
62 | ```typescript
63 | use_mcp_tool('rest-api', 'test_request', {
64 | "method": "DELETE",
65 | "endpoint": "/users/123"
66 | });
67 | ```
68 |
69 | ## Changing Base URL
70 | If you need to test against a different base URL, update the base URL configuration rather than including the full URL in the endpoint parameter.
71 |
72 | Example:
73 | ```bash
74 | # Instead of this:
75 | ❌ "endpoint": "https://api.example.com/users" # Wrong - don't include the full URL
76 |
77 | # Do this:
78 | # 1. Update the base URL configuration to: https://api.example.com
79 | # 2. Then use just the path:
80 | ✅ "endpoint": "/users" # This will resolve to: https://api.example.com/users
81 |
--------------------------------------------------------------------------------
/src/resources/response-format.md:
--------------------------------------------------------------------------------
1 | # Response Format Documentation
2 |
3 | The REST API testing tool returns a comprehensive JSON response containing request details, response information, and validation results.
4 |
5 | ## Response Structure
6 |
7 | ```json
8 | {
9 | "request": {
10 | "url": "http://api.example.com/users",
11 | "method": "GET",
12 | "headers": {},
13 | "body": null,
14 | "authMethod": "none"
15 | },
16 | "response": {
17 | "statusCode": 200,
18 | "statusText": "OK",
19 | "timing": "123ms",
20 | "headers": {},
21 | "body": {}
22 | },
23 | "validation": {
24 | "isError": false,
25 | "messages": ["Request completed successfully"]
26 | }
27 | }
28 | ```
29 |
30 | ## Response Fields
31 |
32 | ### Request Details
33 | - `url`: Full URL including base URL and endpoint
34 | - `method`: HTTP method used
35 | - `headers`: Request headers sent
36 | - `body`: Request body (if applicable)
37 | - `authMethod`: Authentication method used (none, basic, bearer, or apikey)
38 |
39 | ### Response Details
40 | - `statusCode`: HTTP status code
41 | - `statusText`: Status message
42 | - `timing`: Request duration in milliseconds
43 | - `headers`: Response headers received
44 | - `body`: Response body content
45 |
46 | ### Validation
47 | - `isError`: true if status code >= 400
48 | - `messages`: Array of validation or error messages
49 |
50 | ## Error Response Example
51 |
52 | ```json
53 | {
54 | "error": {
55 | "message": "Connection refused",
56 | "code": "ECONNREFUSED",
57 | "request": {
58 | "url": "http://api.example.com/users",
59 | "method": "GET",
60 | "headers": {},
61 | "body": null
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/version.ts.template:
--------------------------------------------------------------------------------
1 | // Template file for TypeScript during development
2 | // The actual version.ts will be generated during build
3 |
4 | export const VERSION = '0.0.0';
5 | export const PACKAGE_NAME = 'dkmaker-mcp-rest-api';
6 | export const SERVER_NAME = 'rest-api';
7 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "Node16",
5 | "moduleResolution": "Node16",
6 | "outDir": "./build",
7 | "rootDir": "./src",
8 | "strict": true,
9 | "esModuleInterop": true,
10 | "skipLibCheck": true,
11 | "forceConsistentCasingInFileNames": true
12 | },
13 | "include": ["src/**/*"],
14 | "exclude": ["node_modules"]
15 | }
16 |
--------------------------------------------------------------------------------