From 084067fd4452041c36cea2c553254b8c30ac8b3b Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Mon, 8 Sep 2025 16:33:19 +0300 Subject: [PATCH 01/21] release: v1.0.1 with Docker marketplace support (#70) * release: v1.0.1 with Docker marketplace support - Upgrade docker/build-push-action from v4 to v6 for annotations support - Add required Google Cloud Marketplace annotation to manifest index - Update version from 1.1.0 to 1.0.1 for proper release sequence - Include Docker container support with multi-platform builds - Add graceful shutdown on SIGINT/SIGTERM signals * Update CHANGELOG for version 1.0.1 Updated release date for version 1.0.1 and added Docker support. --- .github/workflows/cd.yaml | 4 +++- CHANGELOG.md | 10 ++++++---- package.json | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 9e9e0a3..65859da 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -85,10 +85,12 @@ jobs: - name: Build and push Docker image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v6 with: push: true platforms: linux/amd64,linux/arm64 + annotations: | + index:com.googleapis.cloudmarketplace.product.service.name=services/human-mcp-server tags: | us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:${{ needs.extract_version.outputs.version }} us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 9be9ce6..9003b09 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,16 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). -## [1.1.0] - 2025-09-08 +## [1.0.1] - 2025-09-08 ### Added -* Release as Docker image -* Graceful shutdown on SIGINT and SIGTERM +* Docker container support with Google Cloud Marketplace compatibility +* Graceful shutdown on SIGINT and SIGTERM signals +* Multi-platform Docker images (linux/amd64, linux/arm64) +* Required marketplace annotation for service identification ### Changed -* Upgraded dependencies +* Upgraded dependencies to latest versions ## [1.0.0] - 2025-07-22 diff --git a/package.json b/package.json index 1492d65..3e716b2 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.1.0", + "version": "1.0.1", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs", From 7fef464f1bd881e1b48be3b54584130648228c2e Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Mon, 8 Sep 2025 16:46:50 +0300 Subject: [PATCH 02/21] release: v1.0.2 with correct marketplace service name - Fix service name annotation to use full Google Cloud endpoints format - Update to services/human-mcp-server.endpoints.px-gcp-marketplace-prod.cloud.goog - This matches the exact format expected by Google Cloud Marketplace verification - Bump version to 1.0.2 --- .github/workflows/cd.yaml | 2 +- CHANGELOG.md | 6 ++++++ Dockerfile | 2 +- package.json | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 65859da..8f8d801 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -90,7 +90,7 @@ jobs: push: true platforms: linux/amd64,linux/arm64 annotations: | - index:com.googleapis.cloudmarketplace.product.service.name=services/human-mcp-server + index:com.googleapis.cloudmarketplace.product.service.name=services/human-mcp-server.endpoints.px-gcp-marketplace-prod.cloud.goog tags: | us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:${{ needs.extract_version.outputs.version }} us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 9003b09..0c53e27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.2] - 2025-09-08 + +### Fixed + +* GCP marketplace annotation + ## [1.0.1] - 2025-09-08 ### Added diff --git a/Dockerfile b/Dockerfile index 7e61cff..9c403e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,7 +16,7 @@ COPY tsconfig.json . RUN npm run build RUN rm -rf src -LABEL com.googleapis.cloudmarketplace.product.service.name="services/human-mcp-server" +LABEL com.googleapis.cloudmarketplace.product.service.name="services/human-mcp-server.endpoints.px-gcp-marketplace-prod.cloud.goog" # Set entrypoint ENTRYPOINT ["npm", "run", "start"] \ No newline at end of file diff --git a/package.json b/package.json index 3e716b2..6cad5cf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.0.1", + "version": "1.0.2", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs", From d4e0c3431ec406d9f24420baf99ec3bf196a7713 Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Mon, 8 Sep 2025 16:48:54 +0300 Subject: [PATCH 03/21] update package-lock.json for version 1.0.2 --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdb8f62..f040d2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@humansecurity/human-mcp-server", - "version": "1.1.0", + "version": "1.0.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@humansecurity/human-mcp-server", - "version": "1.1.0", + "version": "1.0.2", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.1", From 33fa196f4c1d3253589a2592101acdde2f31b564 Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Tue, 9 Sep 2025 11:50:35 +0300 Subject: [PATCH 04/21] Changed docker image registry location (#73) * Changed docker image registry location * Remove old Docker tags from cd.yaml Removed deprecated Docker tags from the workflow. --- .github/workflows/cd.yaml | 10 +++++----- CHANGELOG.md | 6 ++++++ README.md | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 8f8d801..bb54e79 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -71,9 +71,9 @@ jobs: uses: 'google-github-actions/auth@6fc4af4b145ae7821d527454aa9bd537d1f2dc5f' with: token_format: 'access_token' - project_id: 'hmn-registry' - service_account: ${{ vars.SERVICE_ACCOUNT }} - workload_identity_provider: ${{ vars.WORKLOAD_IDENTITY_PROVIDER }} + project_id: 'hmn-registry-public' + service_account: ${{ secrets.SERVICE_ACCOUNT }} + workload_identity_provider: ${{ secrets.WORKLOAD_IDENTITY_PROVIDER }} - name: Docker Auth id: docker-auth @@ -92,5 +92,5 @@ jobs: annotations: | index:com.googleapis.cloudmarketplace.product.service.name=services/human-mcp-server.endpoints.px-gcp-marketplace-prod.cloud.goog tags: | - us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:${{ needs.extract_version.outputs.version }} - us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:latest + us-docker.pkg.dev/hmn-registry-public/containers/human-mcp-server:${{ needs.extract_version.outputs.version }} + us-docker.pkg.dev/hmn-registry-public/containers/human-mcp-server:latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c53e27..7b10a00 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.3] - 2025-09-09 + +### Changed + +* Docker container registry location + ## [1.0.2] - 2025-09-08 ### Fixed diff --git a/README.md b/README.md index b26e46b..a9884b8 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ If you prefer Docker over NPM, run the MCP server container directly: docker run --rm -i \ -e HUMAN_CYBERFRAUD_API_TOKEN= \ -e HUMAN_CODE_DEFENDER_API_TOKEN= \ - us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:latest + us-docker.pkg.dev/hmn-registry-public/containers/human-mcp-server:latest ``` To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), replace the NPM command with a Docker invocation: @@ -78,7 +78,7 @@ To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), repl "run", "--rm", "-i", "-e", "HUMAN_CYBERFRAUD_API_TOKEN", "-e", "HUMAN_CODE_DEFENDER_API_TOKEN", - "us-docker.pkg.dev/hmn-registry/docker-public/human-mcp-server:latest" + "us-docker.pkg.dev/hmn-registry-public/containers/human-mcp-server:latest" ], "env": { "HUMAN_CYBERFRAUD_API_TOKEN": "your-cyberfraud-token", diff --git a/package-lock.json b/package-lock.json index f040d2d..1ded436 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@humansecurity/human-mcp-server", - "version": "1.0.2", + "version": "1.0.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@humansecurity/human-mcp-server", - "version": "1.0.2", + "version": "1.0.3", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.1", diff --git a/package.json b/package.json index 6cad5cf..a77164f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.0.2", + "version": "1.0.3", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs", From 23d9d5371fe4353dd2d97a5b48c7892d67e9c0ee Mon Sep 17 00:00:00 2001 From: DorAshkenaziHuman Date: Tue, 9 Sep 2025 12:07:56 +0300 Subject: [PATCH 05/21] bump version to 1.0.4 to resolve NPM publish conflict - Update version from 1.0.3 to 1.0.4 - Update changelog with version bump note - Resolves NPM publish conflict for 1.0.3 --- CHANGELOG.md | 8 +++++++- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f62a09c..de90c46 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,12 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.4] - 2025-09-09 + +### Changed + +* Fixed service account permissions + ## [1.0.3] - 2025-09-09 ### Changed * Docker container registry location -* + ## [1.0.2] - 2025-09-08 ### Fixed diff --git a/package-lock.json b/package-lock.json index 1ded436..ab683d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@humansecurity/human-mcp-server", - "version": "1.0.3", + "version": "1.0.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@humansecurity/human-mcp-server", - "version": "1.0.3", + "version": "1.0.4", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.17.1", diff --git a/package.json b/package.json index a77164f..8a309a9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.0.3", + "version": "1.0.4", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs", From 0fca14962ac2af3a91cc25cbe5afd8451e1067d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 10:39:04 -0700 Subject: [PATCH 06/21] Bump @typescript-eslint/parser from 8.42.0 to 8.43.0 (#76) Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 8.42.0 to 8.43.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.43.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-version: 8.43.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 147 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 2 +- 2 files changed, 140 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index ab683d5..8ff0de9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -23,7 +23,7 @@ "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", "@typescript-eslint/eslint-plugin": "^8.41.0", - "@typescript-eslint/parser": "^8.40.0", + "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^5.2.1", "chai-as-promised": "^8.0.1", @@ -2169,16 +2169,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.42.0.tgz", - "integrity": "sha512-r1XG74QgShUgXph1BYseJ+KZd17bKQib/yF3SR+demvytiRXrwd12Blnz5eYGm8tXaeRdd4x88MlfwldHoudGg==", + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.43.0.tgz", + "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", + "@typescript-eslint/scope-manager": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/typescript-estree": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", "debug": "^4.3.4" }, "engines": { @@ -2193,6 +2193,137 @@ "typescript": ">=4.8.4 <6.0.0" } }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.43.0.tgz", + "integrity": "sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.43.0", + "@typescript-eslint/types": "^8.43.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", + "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.43.0.tgz", + "integrity": "sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", + "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", + "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.43.0", + "@typescript-eslint/tsconfig-utils": "8.43.0", + "@typescript-eslint/types": "8.43.0", + "@typescript-eslint/visitor-keys": "8.43.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.43.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", + "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.43.0", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@typescript-eslint/project-service": { "version": "8.42.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.42.0.tgz", diff --git a/package.json b/package.json index 8a309a9..ecd207d 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", "@typescript-eslint/eslint-plugin": "^8.41.0", - "@typescript-eslint/parser": "^8.40.0", + "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^5.2.1", "chai-as-promised": "^8.0.1", From 134522eb2764fc31efdcbc60e6e90591d6deb442 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 10:41:56 -0700 Subject: [PATCH 07/21] Bump @typescript-eslint/eslint-plugin from 8.42.0 to 8.43.0 (#81) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.42.0 to 8.43.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.43.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.43.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 241 +++++++++++----------------------------------- package.json | 2 +- 2 files changed, 56 insertions(+), 187 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8ff0de9..44ce5a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.44.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^5.2.1", @@ -2139,17 +2139,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.42.0.tgz", - "integrity": "sha512-Aq2dPqsQkxHOLfb2OPv43RnIvfj05nw8v/6n3B2NABIPpHnjQnaLo9QGMTvml+tv4korl/Cjfrb/BYhoL8UUTQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz", + "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/type-utils": "8.42.0", - "@typescript-eslint/utils": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", + "@typescript-eslint/scope-manager": "8.44.0", + "@typescript-eslint/type-utils": "8.44.0", + "@typescript-eslint/utils": "8.44.0", + "@typescript-eslint/visitor-keys": "8.44.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -2163,22 +2163,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.42.0", + "@typescript-eslint/parser": "^8.44.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.43.0.tgz", - "integrity": "sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz", + "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.43.0", - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/typescript-estree": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0", + "@typescript-eslint/scope-manager": "8.44.0", + "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/typescript-estree": "8.44.0", + "@typescript-eslint/visitor-keys": "8.44.0", "debug": "^4.3.4" }, "engines": { @@ -2193,146 +2193,15 @@ "typescript": ">=4.8.4 <6.0.0" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.43.0.tgz", - "integrity": "sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.43.0", - "@typescript-eslint/types": "^8.43.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.43.0.tgz", - "integrity": "sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.43.0.tgz", - "integrity": "sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.43.0.tgz", - "integrity": "sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.43.0.tgz", - "integrity": "sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/project-service": "8.43.0", - "@typescript-eslint/tsconfig-utils": "8.43.0", - "@typescript-eslint/types": "8.43.0", - "@typescript-eslint/visitor-keys": "8.43.0", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "typescript": ">=4.8.4 <6.0.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.43.0.tgz", - "integrity": "sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.43.0", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@typescript-eslint/project-service": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.42.0.tgz", - "integrity": "sha512-vfVpLHAhbPjilrabtOSNcUDmBboQNrJUiNAGoImkZKnMjs2TIcWG33s4Ds0wY3/50aZmTMqJa6PiwkwezaAklg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.0.tgz", + "integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.42.0", - "@typescript-eslint/types": "^8.42.0", + "@typescript-eslint/tsconfig-utils": "^8.44.0", + "@typescript-eslint/types": "^8.44.0", "debug": "^4.3.4" }, "engines": { @@ -2347,14 +2216,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.42.0.tgz", - "integrity": "sha512-51+x9o78NBAVgQzOPd17DkNTnIzJ8T/O2dmMBLoK9qbY0Gm52XJcdJcCl18ExBMiHo6jPMErUQWUv5RLE51zJw==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", + "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0" + "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/visitor-keys": "8.44.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2365,9 +2234,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.42.0.tgz", - "integrity": "sha512-kHeFUOdwAJfUmYKjR3CLgZSglGHjbNTi1H8sTYRYV2xX6eNz4RyJ2LIgsDLKf8Yi0/GL1WZAC/DgZBeBft8QAQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.0.tgz", + "integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==", "dev": true, "license": "MIT", "engines": { @@ -2382,15 +2251,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.42.0.tgz", - "integrity": "sha512-9KChw92sbPTYVFw3JLRH1ockhyR3zqqn9lQXol3/YbI6jVxzWoGcT3AsAW0mu1MY0gYtsXnUGV/AKpkAj5tVlQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz", + "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0", - "@typescript-eslint/utils": "8.42.0", + "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/typescript-estree": "8.44.0", + "@typescript-eslint/utils": "8.44.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2407,9 +2276,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.42.0.tgz", - "integrity": "sha512-LdtAWMiFmbRLNP7JNeY0SqEtJvGMYSzfiWBSmx+VSZ1CH+1zyl8Mmw1TT39OrtsRvIYShjJWzTDMPWZJCpwBlw==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", + "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", "dev": true, "license": "MIT", "engines": { @@ -2421,16 +2290,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.42.0.tgz", - "integrity": "sha512-ku/uYtT4QXY8sl9EDJETD27o3Ewdi72hcXg1ah/kkUgBvAYHLwj2ofswFFNXS+FL5G+AGkxBtvGt8pFBHKlHsQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", + "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.42.0", - "@typescript-eslint/tsconfig-utils": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/visitor-keys": "8.42.0", + "@typescript-eslint/project-service": "8.44.0", + "@typescript-eslint/tsconfig-utils": "8.44.0", + "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/visitor-keys": "8.44.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2450,16 +2319,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.42.0.tgz", - "integrity": "sha512-JnIzu7H3RH5BrKC4NoZqRfmjqCIS1u3hGZltDYJgkVdqAezl4L9d1ZLw+36huCujtSBSAirGINF/S4UxOcR+/g==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", + "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.42.0", - "@typescript-eslint/types": "8.42.0", - "@typescript-eslint/typescript-estree": "8.42.0" + "@typescript-eslint/scope-manager": "8.44.0", + "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/typescript-estree": "8.44.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2474,13 +2343,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.42.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.42.0.tgz", - "integrity": "sha512-3WbiuzoEowaEn8RSnhJBrxSwX8ULYE9CXaPepS2C2W3NSA5NNIvBaslpBSBElPq0UGr0xVJlXFWOAKIkyylydQ==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", + "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.42.0", + "@typescript-eslint/types": "8.44.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { diff --git a/package.json b/package.json index ecd207d..cf5a323 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.41.0", + "@typescript-eslint/eslint-plugin": "^8.44.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^5.2.1", From b0f0faf53ddb7e05a42e56c5422c32f0c39f449e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 10:47:51 -0700 Subject: [PATCH 08/21] Bump actions/setup-node from 4 to 5 (#64) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 5. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '5' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index bb54e79..b8a2f06 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -14,7 +14,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - name: Setup Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '22.x' - name: Get package version @@ -50,7 +50,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - name: Setup npmrc - uses: actions/setup-node@v4 + uses: actions/setup-node@v5 with: node-version: '22.x' registry-url: 'https://registry.npmjs.org' From e5defca8b81ef7e6b7d718b68f291b55c7652acf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 11:19:13 -0700 Subject: [PATCH 09/21] Bump lint-staged from 16.1.6 to 16.2.0 (#84) Bumps [lint-staged](https://github.com/lint-staged/lint-staged) from 16.1.6 to 16.2.0. - [Release notes](https://github.com/lint-staged/lint-staged/releases) - [Changelog](https://github.com/lint-staged/lint-staged/blob/main/CHANGELOG.md) - [Commits](https://github.com/lint-staged/lint-staged/compare/v16.1.6...v16.2.0) --- updated-dependencies: - dependency-name: lint-staged dependency-version: 16.2.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 205 +++++++++++++++++----------------------------- package.json | 2 +- 2 files changed, 76 insertions(+), 131 deletions(-) diff --git a/package-lock.json b/package-lock.json index 44ce5a9..481d6d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.3", "husky": "^9.1.7", - "lint-staged": "^16.1.5", + "lint-staged": "^16.2.0", "mocha": "^11.7.1", "prettier": "^3.6.2", "sinon": "^21.0.0", @@ -2690,9 +2690,9 @@ "peer": true }, "node_modules/ansi-escapes": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", - "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.1.0.tgz", + "integrity": "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g==", "dev": true, "license": "MIT", "dependencies": { @@ -3130,17 +3130,17 @@ } }, "node_modules/cli-truncate": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", - "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.0.tgz", + "integrity": "sha512-7JDGG+4Zp0CsknDCedl0DYdaeOhc46QNpXi3NLQblkZpXXgA6LncLDUUyvrjSvZeF3VRQa+KiMGomazQrC1V8g==", "dev": true, "license": "MIT", "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^7.0.0" + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4354,9 +4354,9 @@ } }, "node_modules/get-east-asian-width": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.1.tgz", - "integrity": "sha512-R1QfovbPsKmosqTnPoRFiJ7CF9MLRgb53ChvMZm+r4p76/+8yKDy17qLL2PKInORy2RkZZekuK0efYgmzTkXyQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, "license": "MIT", "engines": { @@ -4677,13 +4677,16 @@ } }, "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.3.1" + }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -4938,36 +4941,20 @@ "node": ">= 0.8.0" } }, - "node_modules/lilconfig": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz", - "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antonk52" - } - }, "node_modules/lint-staged": { - "version": "16.1.6", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.1.6.tgz", - "integrity": "sha512-U4kuulU3CKIytlkLlaHcGgKscNfJPNTiDF2avIUGFCv7K95/DCYQ7Ra62ydeRWmgQGg9zJYw2dzdbztwJlqrow==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.2.0.tgz", + "integrity": "sha512-spdYSOCQ2MdZ9CM1/bu/kDmaYGsrpNOeu1InFFV8uhv14x6YIubGxbCpSmGILFoxkiheNQPDXSg5Sbb5ZuVnug==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^5.6.0", - "commander": "^14.0.0", - "debug": "^4.4.1", - "lilconfig": "^3.1.3", - "listr2": "^9.0.3", - "micromatch": "^4.0.8", - "nano-spawn": "^1.0.2", - "pidtree": "^0.6.0", - "string-argv": "^0.3.2", - "yaml": "^2.8.1" + "commander": "14.0.1", + "listr2": "9.0.4", + "micromatch": "4.0.8", + "nano-spawn": "1.0.3", + "pidtree": "0.6.0", + "string-argv": "0.3.2", + "yaml": "2.8.1" }, "bin": { "lint-staged": "bin/lint-staged.js" @@ -4979,23 +4966,10 @@ "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lint-staged/node_modules/chalk": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", - "integrity": "sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/lint-staged/node_modules/commander": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.0.tgz", - "integrity": "sha512-2uM9rYjPvyq39NwLRqaiLtWHyDC1FvryJDa2ATTVims5YAS4PupsEQsDvP14FqhFr0P49CYDugi59xaxJlTXRA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.1.tgz", + "integrity": "sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==", "dev": true, "license": "MIT", "engines": { @@ -5003,13 +4977,13 @@ } }, "node_modules/listr2": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.3.tgz", - "integrity": "sha512-0aeh5HHHgmq1KRdMMDHfhMWQmIT/m7nRDTlxlFqni2Sp0had9baqsjJRvDGdlvgd6NmPE0nPloOipiQJGFtTHQ==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.4.tgz", + "integrity": "sha512-1wd/kpAdKRLwv7/3OKC8zZ5U8e/fajCfWMxacUvB79S5nLrYGPtUI/8chMQhn3LQjsRVErTb9i1ECAwW0ZIHnQ==", "dev": true, "license": "MIT", "dependencies": { - "cli-truncate": "^4.0.0", + "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", @@ -5091,52 +5065,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/log-update/node_modules/is-fullwidth-code-point": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", - "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-east-asian-width": "^1.3.1" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/node_modules/slice-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", - "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -6530,26 +6458,26 @@ } }, "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -6623,18 +6551,17 @@ } }, "node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", + "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -7404,9 +7331,9 @@ "license": "Apache-2.0" }, "node_modules/wrap-ansi": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", - "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, "license": "MIT", "dependencies": { @@ -7496,9 +7423,9 @@ } }, "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -7508,6 +7435,24 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index cf5a323..7887044 100644 --- a/package.json +++ b/package.json @@ -80,7 +80,7 @@ "eslint-config-prettier": "^10.1.8", "eslint-plugin-prettier": "^5.5.3", "husky": "^9.1.7", - "lint-staged": "^16.1.5", + "lint-staged": "^16.2.0", "mocha": "^11.7.1", "prettier": "^3.6.2", "sinon": "^21.0.0", From 590eae39f2ec55978bd73923cc6d42204c0da4e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 24 Sep 2025 11:19:48 -0700 Subject: [PATCH 10/21] Bump @modelcontextprotocol/sdk from 1.17.5 to 1.18.1 (#82) Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.17.5 to 1.18.1. - [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases) - [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/1.17.5...1.18.1) --- updated-dependencies: - dependency-name: "@modelcontextprotocol/sdk" dependency-version: 1.18.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 481d6d9..abff99f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.17.1", + "@modelcontextprotocol/sdk": "^1.18.1", "node-fetch": "^3.3.2", "zod": "^3.25.67" }, @@ -1049,9 +1049,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.17.5", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.5.tgz", - "integrity": "sha512-QakrKIGniGuRVfWBdMsDea/dx1PNE739QJ7gCM41s9q+qaCYTHCdsIBXQVVXry3mfWAiaM9kT22Hyz53Uw8mfg==", + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.18.1.tgz", + "integrity": "sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw==", "license": "MIT", "dependencies": { "ajv": "^6.12.6", diff --git a/package.json b/package.json index 7887044..a451648 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "coverage": "c8 npm test" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.17.1", + "@modelcontextprotocol/sdk": "^1.18.1", "node-fetch": "^3.3.2", "zod": "^3.25.67" }, From e73e3e168b0d567ce666e2f042eb3a18d19416da Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:55:59 -0700 Subject: [PATCH 11/21] Bump chai from 5.3.3 to 6.2.0 (#87) Bumps [chai](https://github.com/chaijs/chai) from 5.3.3 to 6.2.0. - [Release notes](https://github.com/chaijs/chai/releases) - [Changelog](https://github.com/chaijs/chai/blob/main/History.md) - [Commits](https://github.com/chaijs/chai/compare/v5.3.3...v6.2.0) --- updated-dependencies: - dependency-name: chai dependency-version: 6.2.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 52 ++++------------------------------------------- package.json | 2 +- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/package-lock.json b/package-lock.json index abff99f..a964c2c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -25,7 +25,7 @@ "@typescript-eslint/eslint-plugin": "^8.44.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", - "chai": "^5.2.1", + "chai": "^6.2.0", "chai-as-promised": "^8.0.1", "esbuild": "^0.25.8", "eslint": "^9.32.0", @@ -2761,16 +2761,6 @@ "node": ">=10" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - } - }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -3004,18 +2994,11 @@ "peer": true }, "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.0.tgz", + "integrity": "sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" - }, "engines": { "node": ">=18" } @@ -3449,16 +3432,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5078,13 +5051,6 @@ "loose-envify": "cli.js" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -5581,16 +5547,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14.16" - } - }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", diff --git a/package.json b/package.json index a451648..a9ebb04 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "@typescript-eslint/eslint-plugin": "^8.44.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", - "chai": "^5.2.1", + "chai": "^6.2.0", "chai-as-promised": "^8.0.1", "esbuild": "^0.25.8", "eslint": "^9.32.0", From 8a8438feb1f9d1bf7850d591d7aab915b32e1799 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 10:59:02 -0700 Subject: [PATCH 12/21] Bump @typescript-eslint/eslint-plugin from 8.44.0 to 8.45.0 (#90) Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 8.44.0 to 8.45.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.45.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.45.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 110 +++++++++++++++++++++++----------------------- package.json | 2 +- 2 files changed, 56 insertions(+), 56 deletions(-) diff --git a/package-lock.json b/package-lock.json index a964c2c..004a435 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,7 @@ "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.44.0", + "@typescript-eslint/eslint-plugin": "^8.46.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^6.2.0", @@ -2139,17 +2139,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.0.tgz", - "integrity": "sha512-EGDAOGX+uwwekcS0iyxVDmRV9HX6FLSM5kzrAToLTsr9OWCIKG/y3lQheCq18yZ5Xh78rRKJiEpP0ZaCs4ryOQ==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.0.tgz", + "integrity": "sha512-hA8gxBq4ukonVXPy0OKhiaUh/68D0E88GSmtC1iAEnGaieuDi38LhS7jdCHRLi6ErJBNDGCzvh5EnzdPwUc0DA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/type-utils": "8.44.0", - "@typescript-eslint/utils": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/type-utils": "8.46.0", + "@typescript-eslint/utils": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", @@ -2163,22 +2163,22 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.44.0", + "@typescript-eslint/parser": "^8.46.0", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.0.tgz", - "integrity": "sha512-VGMpFQGUQWYT9LfnPcX8ouFojyrZ/2w3K5BucvxL/spdNehccKhB4jUyB1yBCXpr2XFm0jkECxgrpXBW2ipoAw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.0.tgz", + "integrity": "sha512-n1H6IcDhmmUEG7TNVSspGmiHHutt7iVKtZwRppD7e04wha5MrkV1h3pti9xQLcCMt6YWsncpoT0HMjkH1FNwWQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", "debug": "^4.3.4" }, "engines": { @@ -2194,14 +2194,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.0.tgz", - "integrity": "sha512-ZeaGNraRsq10GuEohKTo4295Z/SuGcSq2LzfGlqiuEvfArzo/VRrT0ZaJsVPuKZ55lVbNk8U6FcL+ZMH8CoyVA==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.0.tgz", + "integrity": "sha512-OEhec0mH+U5Je2NZOeK1AbVCdm0ChyapAyTeXVIYTPXDJ3F07+cu87PPXcGoYqZ7M9YJVvFnfpGg1UmCIqM+QQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.44.0", - "@typescript-eslint/types": "^8.44.0", + "@typescript-eslint/tsconfig-utils": "^8.46.0", + "@typescript-eslint/types": "^8.46.0", "debug": "^4.3.4" }, "engines": { @@ -2216,14 +2216,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.0.tgz", - "integrity": "sha512-87Jv3E+al8wpD+rIdVJm/ItDBe/Im09zXIjFoipOjr5gHUhJmTzfFLuTJ/nPTMc2Srsroy4IBXwcTCHyRR7KzA==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.0.tgz", + "integrity": "sha512-lWETPa9XGcBes4jqAMYD9fW0j4n6hrPtTJwWDmtqgFO/4HF4jmdH/Q6wggTw5qIT5TXjKzbt7GsZUBnWoO3dqw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0" + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2234,9 +2234,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.0.tgz", - "integrity": "sha512-x5Y0+AuEPqAInc6yd0n5DAcvtoQ/vyaGwuX5HE9n6qAefk1GaedqrLQF8kQGylLUb9pnZyLf+iEiL9fr8APDtQ==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.0.tgz", + "integrity": "sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==", "dev": true, "license": "MIT", "engines": { @@ -2251,15 +2251,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.0.tgz", - "integrity": "sha512-9cwsoSxJ8Sak67Be/hD2RNt/fsqmWnNE1iHohG8lxqLSNY8xNfyY7wloo5zpW3Nu9hxVgURevqfcH6vvKCt6yg==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.0.tgz", + "integrity": "sha512-hy+lvYV1lZpVs2jRaEYvgCblZxUoJiPyCemwbQZ+NGulWkQRy0HRPYAoef/CNSzaLt+MLvMptZsHXHlkEilaeg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0", - "@typescript-eslint/utils": "8.44.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0", + "@typescript-eslint/utils": "8.46.0", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, @@ -2276,9 +2276,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.0.tgz", - "integrity": "sha512-ZSl2efn44VsYM0MfDQe68RKzBz75NPgLQXuGypmym6QVOWL5kegTZuZ02xRAT9T+onqvM6T8CdQk0OwYMB6ZvA==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.0.tgz", + "integrity": "sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==", "dev": true, "license": "MIT", "engines": { @@ -2290,16 +2290,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.0.tgz", - "integrity": "sha512-lqNj6SgnGcQZwL4/SBJ3xdPEfcBuhCG8zdcwCPgYcmiPLgokiNDKlbPzCwEwu7m279J/lBYWtDYL+87OEfn8Jw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.0.tgz", + "integrity": "sha512-ekDCUfVpAKWJbRfm8T1YRrCot1KFxZn21oV76v5Fj4tr7ELyk84OS+ouvYdcDAwZL89WpEkEj2DKQ+qg//+ucg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.44.0", - "@typescript-eslint/tsconfig-utils": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/visitor-keys": "8.44.0", + "@typescript-eslint/project-service": "8.46.0", + "@typescript-eslint/tsconfig-utils": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/visitor-keys": "8.46.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", @@ -2319,16 +2319,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.0.tgz", - "integrity": "sha512-nktOlVcg3ALo0mYlV+L7sWUD58KG4CMj1rb2HUVOO4aL3K/6wcD+NERqd0rrA5Vg06b42YhF6cFxeixsp9Riqg==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.0.tgz", + "integrity": "sha512-nD6yGWPj1xiOm4Gk0k6hLSZz2XkNXhuYmyIrOWcHoPuAhjT9i5bAG+xbWPgFeNR8HPHHtpNKdYUXJl/D3x7f5g==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.44.0", - "@typescript-eslint/types": "8.44.0", - "@typescript-eslint/typescript-estree": "8.44.0" + "@typescript-eslint/scope-manager": "8.46.0", + "@typescript-eslint/types": "8.46.0", + "@typescript-eslint/typescript-estree": "8.46.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2343,13 +2343,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.0.tgz", - "integrity": "sha512-zaz9u8EJ4GBmnehlrpoKvj/E3dNbuQ7q0ucyZImm3cLqJ8INTc970B1qEqDX/Rzq65r3TvVTN7kHWPBoyW7DWw==", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.0.tgz", + "integrity": "sha512-FrvMpAK+hTbFy7vH5j1+tMYHMSKLE6RzluFJlkFNKD0p9YsUT75JlBSmr5so3QRzvMwU5/bIEdeNrxm8du8l3Q==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.44.0", + "@typescript-eslint/types": "8.46.0", "eslint-visitor-keys": "^4.2.1" }, "engines": { diff --git a/package.json b/package.json index a9ebb04..1390110 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@types/chai-as-promised": "^8.0.2", "@types/mocha": "^10.0.10", "@types/sinon": "^17.0.4", - "@typescript-eslint/eslint-plugin": "^8.44.0", + "@typescript-eslint/eslint-plugin": "^8.46.0", "@typescript-eslint/parser": "^8.43.0", "c8": "^10.1.3", "chai": "^6.2.0", From 32de4a67353f450abf0b81e1394d8b44a5fcabca Mon Sep 17 00:00:00 2001 From: Ori Gold <77228321+ori-gold-px@users.noreply.github.com> Date: Sun, 19 Oct 2025 23:49:24 -0700 Subject: [PATCH 13/21] fix: README updates (#95) * fix: README updates * fix links --- README.md | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a9884b8..ab748e9 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,15 @@ Supercharge your AI workflows with comprehensive cybersecurity intelligence from - **Custom Security Rules**: Manage and audit your custom mitigation policies and security controls **Code Defender - Client-Side Security** -- **Supply Chain Protection**: Monitor third-party scripts and vendors on your payment and sensitive pages -- **PCI DSS Compliance**: Automated compliance validation and security assessment for payment environments -- **Security Incident Response**: Track client-side attacks, XSS attempts, and code injection threats -- **HTTP Security Headers**: Comprehensive security posture analysis and misconfiguration detection +- **Client-Side Supply Chain Protection**: Monitor first- and third-party scripts and vendors on your payment and sensitive pages +- **PCI DSS Compliance**: Streamline PCI DSS compliance and confirm that your site is not susceptible to attacks from scripts +- **Security Incident Monitoring**: Track client-side attacks, e-skimming attempts, and code injection threats +- **HTTP Security-Impacting Headers**: Monitor and alert personnel to changes to security-impacting HTTP headers + +## ๐Ÿ”‘ Prerequisites + +* If running with NPM, download and install [Node.js](https://nodejs.org/en/download). +* If running with Docker, download and install [Docker](https://www.docker.com/get-started/). ## ๐Ÿš€ Quick Start @@ -58,7 +63,7 @@ You'll need API tokens from your HUMAN Security account to access the services. ## ๐Ÿณ Run with Docker -If you prefer Docker over NPM, run the MCP server container directly: +If you prefer to use Docker over NPM, run the MCP server container directly: ```bash docker run --rm -i \ @@ -101,7 +106,7 @@ To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), repl * *"Show me attack trends over the last 24 hours"* * *"Investigate suspicious activity for account ID XXXXX"* * *"What third-party scripts are running on our payment pages?"* -* *"Are we PCI DSS compliant based on our current security headers?"* +* *"Show me the scripts and headers in my PCI inventory"* * *"Analyze the effectiveness of our custom security rules"* * *"Show me details about attack cluster XXXXX"* @@ -116,7 +121,7 @@ To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), repl ### Code Defender Security - **Security Incidents**: Client-side attack detection and investigation -- **Script Inventory**: Third-party script monitoring and PCI compliance +- **Script Inventory**: First- and third-party script monitoring and PCI compliance - **Header Inventory**: HTTP security header analysis and optimization ## ๐Ÿ”— Integration Options @@ -154,8 +159,8 @@ If you only need one service, you can configure just that token: - **Documentation**: [HUMAN Security Documentation](https://docs.humansecurity.com) - **API Tokens**: - - [Cyberfraud](https://docs.humansecurity.com/applications-and-accounts/reference/api-authentication#getting-a-token-for-account-defender-bot-defender-or-credential-intelligence) - - [Code Defender](https://docs.humansecurity.com/applications-and-accounts/reference/api-authentication#getting-a-token-for-code-defender-or-pci-dss) + - [Cyberfraud](https://docs.humansecurity.com/applications/reference/authentication) + - [Code Defender](https://docs.humansecurity.com/applications/reference/authentication#getting-a-token-for-the-code-defender-or-pci-dss-api) - **Technical Support**: Available through your HUMAN Security support channels ## ๐Ÿ“„ License From 298c62cbf18dac39231bafb76da4de8b25d29591 Mon Sep 17 00:00:00 2001 From: chen-zimmer-px <101555597+chen-zimmer-px@users.noreply.github.com> Date: Mon, 27 Oct 2025 14:21:31 +0200 Subject: [PATCH 14/21] updated cd.yaml (#103) --- .github/workflows/cd.yaml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index b8a2f06..a3d52ac 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -14,7 +14,7 @@ jobs: - name: Checkout code uses: actions/checkout@v5 - name: Setup Node.js - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: '22.x' - name: Get package version @@ -41,16 +41,14 @@ jobs: needs: - create_release - extract_version - permissions: - contents: 'read' - id-token: 'write' - + id-token: write + contents: read steps: - name: Checkout code uses: actions/checkout@v5 - name: Setup npmrc - uses: actions/setup-node@v5 + uses: actions/setup-node@v6 with: node-version: '22.x' registry-url: 'https://registry.npmjs.org' @@ -60,8 +58,6 @@ jobs: run: npm run build - name: Publish package to NPM run: npm publish --access public - env: - NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Setup Docker uses: docker/setup-buildx-action@v3 From ff081a0d9f33dfa811f7e347a29ba5de47500881 Mon Sep 17 00:00:00 2001 From: Ori Gold <77228321+ori-gold-px@users.noreply.github.com> Date: Wed, 29 Oct 2025 08:18:45 -0700 Subject: [PATCH 15/21] fix: setup node 22 in all github action workflows (#100) --- .github/workflows/ci.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f683363..5298493 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,6 +6,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22.x' - name: Install dependencies run: npm ci - name: Build @@ -15,6 +19,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22.x' - name: Install dependencies run: npm ci - name: Run linter @@ -24,6 +32,10 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v5 + - name: Setup Node.js + uses: actions/setup-node@v6 + with: + node-version: '22.x' - name: Install dependencies run: npm ci - name: Run unit tests From 19371edbad6475f1d47a6ed410e6afe15d0694d1 Mon Sep 17 00:00:00 2001 From: chen-zimmer-px <101555597+chen-zimmer-px@users.noreply.github.com> Date: Mon, 3 Nov 2025 22:01:39 +0200 Subject: [PATCH 16/21] Upgrade Node.js version and update npm (#104) Updated Node.js version from 22.x to 24.x and added npm update step. --- .github/workflows/cd.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index a3d52ac..9b554f5 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -16,7 +16,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v6 with: - node-version: '22.x' + node-version: '24.x' - name: Get package version id: version run: echo "value=$(node -p -e "require('./package.json').version")" >> "$GITHUB_OUTPUT" @@ -50,8 +50,10 @@ jobs: - name: Setup npmrc uses: actions/setup-node@v6 with: - node-version: '22.x' + node-version: '24.x' registry-url: 'https://registry.npmjs.org' + - name: Update npm + run: npm install -g npm@11.6.2 - name: Install dependencies run: npm install - name: Build From 87fac4120ae7967d6b951e65895bb4478ecb03d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 07:10:32 -0800 Subject: [PATCH 17/21] Bump actions/checkout from 5 to 6 (#105) Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v5...v6) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd.yaml | 6 +++--- .github/workflows/ci.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 9b554f5..49d5d08 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -12,7 +12,7 @@ jobs: version: ${{ steps.version.outputs.value }} steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: @@ -29,7 +29,7 @@ jobs: contents: write steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - run: gh release create v${{ needs.extract_version.outputs.version }} --generate-notes -t "Version ${{ needs.extract_version.outputs.version }}" env: GITHUB_TOKEN: ${{ github.TOKEN }} @@ -46,7 +46,7 @@ jobs: contents: read steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup npmrc uses: actions/setup-node@v6 with: diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5298493..541b501 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -5,7 +5,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: @@ -31,7 +31,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout code - uses: actions/checkout@v5 + uses: actions/checkout@v6 - name: Setup Node.js uses: actions/setup-node@v6 with: From b8ea438f85035a00643024fb22ef0d45dfee16b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Dec 2025 07:11:46 -0800 Subject: [PATCH 18/21] Bump @modelcontextprotocol/sdk from 1.18.1 to 1.20.2 (#102) Bumps [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk) from 1.18.1 to 1.20.2. - [Release notes](https://github.com/modelcontextprotocol/typescript-sdk/releases) - [Commits](https://github.com/modelcontextprotocol/typescript-sdk/compare/1.18.1...1.20.2) --- updated-dependencies: - dependency-name: "@modelcontextprotocol/sdk" dependency-version: 1.20.2 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 004a435..08b8f88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.4", "license": "MIT", "dependencies": { - "@modelcontextprotocol/sdk": "^1.18.1", + "@modelcontextprotocol/sdk": "^1.20.2", "node-fetch": "^3.3.2", "zod": "^3.25.67" }, @@ -1049,9 +1049,9 @@ } }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.18.1.tgz", - "integrity": "sha512-d//GE8/Yh7aC3e7p+kZG8JqqEAwwDUmAfvH1quogtbk+ksS6E0RR6toKKESPYYZVre0meqkJb27zb+dhqE9Sgw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.20.2.tgz", + "integrity": "sha512-6rqTdFt67AAAzln3NOKsXRmv5ZzPkgbfaebKBqUbts7vK1GZudqnrun5a8d3M/h955cam9RHZ6Jb4Y1XhnmFPg==", "license": "MIT", "dependencies": { "ajv": "^6.12.6", diff --git a/package.json b/package.json index 1390110..63eb0c9 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "coverage": "c8 npm test" }, "dependencies": { - "@modelcontextprotocol/sdk": "^1.18.1", + "@modelcontextprotocol/sdk": "^1.20.2", "node-fetch": "^3.3.2", "zod": "^3.25.67" }, From 79314817d9d93b7077003e4e45d61c6682bc8d6f Mon Sep 17 00:00:00 2001 From: asafcohenpx <80626954+asafcohenpx@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:05:52 +0300 Subject: [PATCH 19/21] adjust to new routes (#124) * 1.0.4 (#75) * release: v1.0.1 with Docker marketplace support (#70) * release: v1.0.1 with Docker marketplace support - Upgrade docker/build-push-action from v4 to v6 for annotations support - Add required Google Cloud Marketplace annotation to manifest index - Update version from 1.1.0 to 1.0.1 for proper release sequence - Include Docker container support with multi-platform builds - Add graceful shutdown on SIGINT/SIGTERM signals * Update CHANGELOG for version 1.0.1 Updated release date for version 1.0.1 and added Docker support. * release: v1.0.2 with correct marketplace service name - Fix service name annotation to use full Google Cloud endpoints format - Update to services/human-mcp-server.endpoints.px-gcp-marketplace-prod.cloud.goog - This matches the exact format expected by Google Cloud Marketplace verification - Bump version to 1.0.2 * update package-lock.json for version 1.0.2 * Changed docker image registry location (#73) * Changed docker image registry location * Remove old Docker tags from cd.yaml Removed deprecated Docker tags from the workflow. * bump version to 1.0.4 to resolve NPM publish conflict - Update version from 1.0.3 to 1.0.4 - Update changelog with version bump note - Resolves NPM publish conflict for 1.0.3 * Fix API token links in README (#110) Updated API token links for Cyberfraud and Code Defender in the support section. * adjust to new routes --------- Co-authored-by: DorAshkenaziHuman Co-authored-by: Gilad Winterfeld <67740138+giladwpx@users.noreply.github.com> --- README.md | 45 +++- scripts/test_local.mjs | 250 +++++++++++++++++++++ src/services/cyberfraudService.ts | 131 +++++++---- src/tools/getTrafficData.ts | 89 +++----- src/types/cyberfraud/trafficData.ts | 286 ++++++++++-------------- src/utils/constants.ts | 8 +- src/utils/httpClient.ts | 3 + test/services/cyberfraudService.test.ts | 130 +++++++++++ test/tools/getTrafficData.test.ts | 24 ++ test/utils/httpClient.test.ts | 14 ++ 10 files changed, 709 insertions(+), 271 deletions(-) create mode 100644 scripts/test_local.mjs create mode 100644 test/tools/getTrafficData.test.ts diff --git a/README.md b/README.md index ab748e9..a6de32a 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,7 @@ To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), repl - **`HUMAN_API_HOST`**: Use a different API endpoint (default: `api.humansecurity.com`) - **`HUMAN_API_VERSION`**: Specify API version (default: `v1`) - **`HTTP_TIMEOUT_MS`**: Request timeout in milliseconds (default: `30000`) +- **`HUMAN_TRAFFIC_API_BASE`**: Override the base URL for traffic data endpoints. Useful for local development against a pxPortal instance (e.g. `http://localhost:3000/api/v1/botDefender/traffic`). When not set, defaults to the standard HUMAN API base. ## ๐Ÿ’ก Usage Examples @@ -113,7 +114,7 @@ To use Docker from your MCP client config (e.g., Cursor or Claude Desktop), repl ## ๐Ÿ“Š Available Tools ### Cyberfraud Protection -- **Traffic Data**: Comprehensive traffic analytics with security metrics +- **Traffic Data**: Comprehensive traffic analytics with overtime time-series, aggregated metrics, and ranked tops breakdowns - **Attack Reporting (Overtime)**: Time-series attack analytics and trend analysis - **Attack Reporting (Overview)**: Detailed attack cluster intelligence and forensics - **Account Information**: Individual account security analysis and incident tracking @@ -155,11 +156,51 @@ If you only need one service, you can configure just that token: } ``` +## ๐Ÿงช Local Development & Testing + +### Running against a local pxPortal instance + +To test the MCP server against a locally running pxPortal (default port `3000`), set `HUMAN_TRAFFIC_API_BASE` to override the traffic data endpoint: + +```json +{ + "mcpServers": { + "human-security": { + "command": "node", + "args": ["/path/to/human-mcp-server/dist/index.cjs"], + "env": { + "HUMAN_CYBERFRAUD_API_TOKEN": "your-token", + "HUMAN_TRAFFIC_API_BASE": "http://localhost:3000/api/v1/botDefender/traffic" + } + } + } +} +``` + +### End-to-end test script + +`scripts/test_local.mjs` spawns the MCP server and runs 25 scenarios against a live backend, covering all modes (`overtime`, `metrics`, `tops`), filters, combined calls, time ranges, and tops field coverage. + +```bash +# Build first +npm run build + +# Run all scenarios against localhost:3000 +HUMAN_CYBERFRAUD_API_TOKEN= node scripts/test_local.mjs + +# Run against a custom backend +HUMAN_CYBERFRAUD_API_TOKEN= \ +HUMAN_TRAFFIC_API_BASE=http://my-host/api/v1/botDefender/traffic \ +node scripts/test_local.mjs +``` + +Expected output: `RESULTS: 25 passed, 0 failed`. + ## ๐Ÿ†˜ Support - **Documentation**: [HUMAN Security Documentation](https://docs.humansecurity.com) - **API Tokens**: - - [Cyberfraud](https://docs.humansecurity.com/applications/reference/authentication) + - [Cyberfraud](https://docs.humansecurity.com/applications/reference/authentication#getting-a-token-for-the-account-defender-adaptive-feedback-bot-defender-or-credential-intelligence-api) - [Code Defender](https://docs.humansecurity.com/applications/reference/authentication#getting-a-token-for-the-code-defender-or-pci-dss-api) - **Technical Support**: Available through your HUMAN Security support channels diff --git a/scripts/test_local.mjs b/scripts/test_local.mjs new file mode 100644 index 0000000..9fe694b --- /dev/null +++ b/scripts/test_local.mjs @@ -0,0 +1,250 @@ +/** + * End-to-end test script: spawns the MCP server and exercises the + * human_get_traffic_data tool against localhost:3000. + * + * Usage: + * node scripts/test_local.mjs + */ + +import { spawn } from 'child_process'; +import { fileURLToPath } from 'url'; +import path from 'path'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const distPath = path.resolve(__dirname, '../dist/index.cjs'); + +const TOKEN = process.env.HUMAN_CYBERFRAUD_API_TOKEN; +if (!TOKEN) { + console.error('Error: HUMAN_CYBERFRAUD_API_TOKEN env var is required.'); + console.error(' Usage: HUMAN_CYBERFRAUD_API_TOKEN= node scripts/test_local.mjs'); + process.exit(1); +} +const TRAFFIC_BASE = + process.env.HUMAN_TRAFFIC_API_BASE ?? 'http://localhost:3000/api/v1/botDefender/traffic'; + +// โ”€โ”€ helpers โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +let _id = 1; +const nextId = () => _id++; + +let PASS = 0, FAIL = 0; + +function summarise(label, result) { + const d = result?.result?.structuredContent?.data; + const err = result?.result?.structuredContent?.error; + const isError = result?.result?.isError; + + if (isError || err) { + console.log(` โŒ FAIL ${label}`); + console.log(` error: ${err || JSON.stringify(result?.result)}`); + FAIL++; + return; + } + + const parts = []; + if (d?.metrics?.results) { + const r = d.metrics.results; + parts.push(`metrics: total=${r.total ?? '?'} blocked=${r.blocked ?? '?'} legitimate=${r.legitimate ?? '?'}`); + } + if (d?.overtime?.results) { + parts.push(`overtime: ${d.overtime.results.length} intervals, first=${d.overtime.results[0]?.timestamp}`); + } + if (d?.tops) { + for (const [field, rows] of Object.entries(d.tops)) { + parts.push(`tops.${field}: top="${rows[0]?.value}" (${rows[0]?.count}), ${rows.length} rows`); + } + } + console.log(` โœ… PASS ${label}`); + for (const p of parts) console.log(` ${p}`); + PASS++; +} + +function send(proc, msg) { + proc.stdin.write(JSON.stringify(msg) + '\n'); +} + +async function runTests() { + const proc = spawn('node', [distPath], { + env: { + ...process.env, + HUMAN_CYBERFRAUD_API_TOKEN: TOKEN, + HUMAN_TRAFFIC_API_BASE: TRAFFIC_BASE, + }, + stdio: ['pipe', 'pipe', 'inherit'], + }); + + const pending = []; + const queue = []; + let buf = ''; + + proc.stdout.on('data', (chunk) => { + buf += chunk.toString(); + const lines = buf.split('\n'); + buf = lines.pop(); + for (const line of lines) { + if (!line.trim()) continue; + let parsed; + try { parsed = JSON.parse(line); } catch { continue; } + if (pending.length > 0) pending.shift()(parsed); + else queue.push(parsed); + } + }); + + const waitForResponse = () => + new Promise((resolve) => { + if (queue.length > 0) { resolve(queue.shift()); return; } + pending.push(resolve); + }); + + const call = async (label, args) => { + send(proc, { jsonrpc: '2.0', id: nextId(), method: 'tools/call', + params: { name: 'human_get_traffic_data', arguments: args } }); + const res = await waitForResponse(); + summarise(label, res); + return res; + }; + + // โ”€โ”€ Initialize โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + send(proc, { jsonrpc: '2.0', id: nextId(), method: 'initialize', + params: { protocolVersion: '2024-11-05', capabilities: {}, + clientInfo: { name: 'test-script', version: '0.0.1' } } }); + await waitForResponse(); + send(proc, { jsonrpc: '2.0', method: 'notifications/initialized', params: {} }); + + const now = Math.floor(Date.now() / 1000); + const t = (offsetSec) => new Date((now + offsetSec) * 1000).toISOString(); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' BASIC MODES'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('metrics only โ€” last 1h', { + startTime: t(-3600), endTime: t(0), metrics: true }); + + await call('overtime only โ€” last 30min', { + startTime: t(-1800), endTime: t(0), overtime: true }); + + await call('tops/incidentTypes only โ€” last 3h', { + startTime: t(-10800), endTime: t(0), tops: ['incidentTypes'] }); + + await call('tops/path only โ€” last 3h, limit 5', { + startTime: t(-10800), endTime: t(0), tops: ['path'], limit: 5 }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' FILTERS'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('metrics โ€” blocked traffic only (trafficTags filter)', { + startTime: t(-3600), endTime: t(0), metrics: true, + filters: { trafficTags: ['blocked', 'potentialBlock'] } }); + + await call('metrics โ€” login pages only (pageType filter)', { + startTime: t(-3600), endTime: t(0), metrics: true, + filters: { pageType: ['login', 'login_attempt'] } }); + + await call('overtime โ€” goodKnownBots only', { + startTime: t(-3600), endTime: t(0), overtime: true, + filters: { trafficTags: ['goodKnownBots'] } }); + + await call('tops/country โ€” blocked traffic only', { + startTime: t(-10800), endTime: t(0), tops: ['country'], + filters: { trafficTags: ['blocked'] }, limit: 10 }); + + await call('tops/socketIpOrgName โ€” blocked+blacklist, limit 5', { + startTime: t(-10800), endTime: t(0), tops: ['socketIpOrgName'], + filters: { trafficTags: ['blocked', 'blacklist', 'potentialBlock'] }, limit: 5 }); + + await call('tops/knownBot โ€” goodKnownBots only, limit 10', { + startTime: t(-10800), endTime: t(0), tops: ['knownBot'], + filters: { trafficTags: ['goodKnownBots'] }, limit: 10 }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' PLATFORM'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('metrics โ€” web only', { + startTime: t(-3600), endTime: t(0), metrics: true, + trafficSource: ['web'] }); + + await call('metrics โ€” mobile only', { + startTime: t(-3600), endTime: t(0), metrics: true, + trafficSource: ['mobile'] }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' OVERTIME seriesFields'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('overtime โ€” split by knownBot', { + startTime: t(-3600), endTime: t(0), overtime: true, + filters: { trafficTags: ['goodKnownBots'] }, + seriesFields: ['knownBot'] }); + + await call('overtime โ€” split by customRule', { + startTime: t(-3600), endTime: t(0), overtime: true, + seriesFields: ['customRule'] }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' COMBINED CALLS (multiple modes in one)'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('metrics + tops/incidentTypes (executive security summary)', { + startTime: t(-10800), endTime: t(0), + metrics: true, + tops: ['incidentTypes'] }); + + await call('overtime + metrics (dashboard: KPIs + chart)', { + startTime: t(-3600), endTime: t(0), + overtime: true, metrics: true }); + + await call('metrics + tops/path + tops/country (full breakdown)', { + startTime: t(-10800), endTime: t(0), + metrics: true, + tops: ['path', 'country'], + filters: { trafficTags: ['blocked'] }, limit: 5 }); + + await call('overtime + tops/socketIpOrgName โ€” blocked focus', { + startTime: t(-3600), endTime: t(0), + overtime: true, + tops: ['socketIpOrgName'], + filters: { trafficTags: ['blocked', 'potentialBlock'] }, limit: 5 }); + + await call('metrics + overtime + tops/incidentTypes + tops/knownBot (full dashboard)', { + startTime: t(-10800), endTime: t(0), + metrics: true, overtime: true, + tops: ['incidentTypes', 'knownBot'], + trafficSource: ['web', 'mobile'] }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' TIME RANGES'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('metrics โ€” last 15 minutes', { + startTime: t(-900), endTime: t(0), metrics: true }); + + await call('metrics โ€” last 6 hours', { + startTime: t(-21600), endTime: t(0), metrics: true }); + + await call('overtime โ€” last 2 hours', { + startTime: t(-7200), endTime: t(0), overtime: true }); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(' TOPS FIELDS COVERAGE'); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + + await call('tops/domain', { + startTime: t(-10800), endTime: t(0), tops: ['domain'], limit: 5 }); + + await call('tops/uaServer (user agent)', { + startTime: t(-10800), endTime: t(0), tops: ['uaServer'], limit: 5 }); + + await call('tops/customRule', { + startTime: t(-10800), endTime: t(0), tops: ['customRule'], limit: 5 }); + + proc.kill(); + + console.log('\nโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•'); + console.log(` RESULTS: ${PASS} passed, ${FAIL} failed`); + console.log('โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•\n'); +} + +runTests().catch((err) => { console.error('Test failed:', err); process.exit(1); }); diff --git a/src/services/cyberfraudService.ts b/src/services/cyberfraudService.ts index 28104d1..cecdb62 100644 --- a/src/services/cyberfraudService.ts +++ b/src/services/cyberfraudService.ts @@ -1,6 +1,6 @@ import type { HttpClient } from '../utils/httpClient'; import { clampAttackReportingTimes } from '../utils/dateUtils'; -import { HUMAN_API_BASE } from '../utils/constants'; +import { HUMAN_API_BASE, HUMAN_TRAFFIC_API_BASE } from '../utils/constants'; import type { CyberfraudOvertimeParams, CyberfraudOverviewParams, @@ -14,6 +14,13 @@ import type { } from '../types/cyberfraud'; const API_BASE = `${HUMAN_API_BASE}/cyberfraud`; +const TRAFFIC_DATA_BASE = HUMAN_TRAFFIC_API_BASE; + +interface ApiEnvelope { + result: boolean; + message?: string; + content: T; +} function buildAttackReportingUrl(endpoint: string, params: Record) { const queryParams = new URLSearchParams(); @@ -27,43 +34,30 @@ function buildAttackReportingUrl(endpoint: string, params: Record) return `${API_BASE}/attack-reporting${endpoint}?${queryParams.toString()}`; } -function buildTrafficDataQuery(params: { - from: number; - to: number; - appId?: string[]; - source?: string[]; - overtime?: string[]; - tops?: string[]; - traffic?: string[]; - pageType?: string[]; - count?: string[]; - withoutTotals?: boolean; - metricsEnrichment?: any; -}) { +function buildTrafficDataUrl(endpoint: string, from: number, to: number) { const query = new URLSearchParams(); - query.append('from', params.from.toString()); - query.append('to', params.to.toString()); - const sources = params.source && params.source.length > 0 ? params.source : ['web', 'mobile']; - sources.forEach((s) => query.append('source[]', s)); - if (params.appId) params.appId.forEach((id) => query.append('appId[]', id)); - const allOvertime = [ - 'legitimate', - 'blocked', - 'potentialBlock', - 'whitelist', - 'blacklist', - 'goodKnownBots', - 'captchaSolved', - ]; - const overtime = params.overtime && params.overtime.length > 0 ? params.overtime : allOvertime; - overtime.forEach((o) => query.append('overtime[]', o)); - if (params.tops) params.tops.forEach((t) => query.append('tops[]', t)); - if (params.traffic) params.traffic.forEach((t) => query.append('traffic[]', t)); - if (params.pageType) params.pageType.forEach((p) => query.append('pageType[]', p)); - if (params.count) params.count.forEach((c) => query.append('count[]', c)); - if (params.withoutTotals) query.append('withoutTotals', 'true'); - if (params.metricsEnrichment) query.append('metricsEnrichment', JSON.stringify(params.metricsEnrichment)); - return `${API_BASE}/traffic-data?${query.toString()}`; + query.append('from', from.toString()); + query.append('to', to.toString()); + return `${TRAFFIC_DATA_BASE}${endpoint}?${query.toString()}`; +} + +function buildBaseBody(params: TrafficDataInput) { + const body: Record = { + trafficSource: + params.trafficSource && params.trafficSource.length > 0 ? params.trafficSource : ['web', 'mobile'], + }; + if (params.filters) { + body.filters = params.filters; + } + return body; +} + +async function parseApiResponse(res: { json: () => Promise }): Promise { + const json = (await res.json()) as ApiEnvelope; + if (!json.result) { + throw new Error(json.message || 'API request failed'); + } + return json.content; } export class CyberfraudService { @@ -102,12 +96,67 @@ export class CyberfraudService { } async getTrafficData(params: TrafficDataInput): Promise { - const { startTime, endTime, ...rest } = params; + const { startTime, endTime, overtime, metrics, tops, seriesFields, limit, includeNulls } = params; const clamped = clampAttackReportingTimes(startTime, endTime); const from = Math.floor(new Date(clamped.startTime).getTime() / 1000); const to = Math.floor(new Date(clamped.endTime).getTime() / 1000); - const url = buildTrafficDataQuery({ from, to, ...rest }); - const res = await this.http.request(url); - return (await res.json()) as TrafficDataResponse; + + type RequestTask = { kind: 'overtime' } | { kind: 'metrics' } | { kind: 'tops'; field: string }; + + const tasks: RequestTask[] = []; + if (overtime) tasks.push({ kind: 'overtime' }); + if (metrics) tasks.push({ kind: 'metrics' }); + if (tops) { + for (const field of tops) { + tasks.push({ kind: 'tops', field }); + } + } + + const results = await Promise.all( + tasks.map(async (task) => { + if (task.kind === 'overtime') { + const body = { ...buildBaseBody(params) }; + if (seriesFields && seriesFields.length > 0) { + body.seriesFields = seriesFields; + } + const url = buildTrafficDataUrl('/overtime', from, to); + const res = await this.http.request(url, { method: 'POST', body }); + const content = await parseApiResponse>(res); + return { kind: 'overtime' as const, content }; + } + + if (task.kind === 'metrics') { + const body = buildBaseBody(params); + const url = buildTrafficDataUrl('/metrics', from, to); + const res = await this.http.request(url, { method: 'POST', body }); + const content = await parseApiResponse>(res); + return { kind: 'metrics' as const, content }; + } + + const body: Record = { ...buildBaseBody(params) }; + if (limit !== undefined) body.limit = limit; + if (includeNulls !== undefined) body.includeNulls = includeNulls; + + const url = buildTrafficDataUrl(`/tops/${task.field}`, from, to); + const res = await this.http.request(url, { method: 'POST', body }); + const content = await parseApiResponse<{ results: Array<{ value: string; count: number }> }>(res); + return { kind: 'tops' as const, field: task.field, content }; + }), + ); + + const response: TrafficDataResponse = {}; + + for (const result of results) { + if (result.kind === 'overtime') { + response.overtime = result.content; + } else if (result.kind === 'metrics') { + response.metrics = result.content; + } else { + if (!response.tops) response.tops = {}; + response.tops[result.field] = result.content.results; + } + } + + return response; } } diff --git a/src/tools/getTrafficData.ts b/src/tools/getTrafficData.ts index 7f9c18a..acfed2c 100644 --- a/src/tools/getTrafficData.ts +++ b/src/tools/getTrafficData.ts @@ -1,5 +1,5 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp'; -import { TrafficDataInputSchema, TrafficDataInput, TrafficDataOutputSchema } from '../types/cyberfraud'; +import { TrafficDataInputBaseSchema, TrafficDataInput, TrafficDataOutputSchema } from '../types/cyberfraud'; import { mcpToolHandler } from '../utils/mcpToolHandler'; import { makeStructuredResponseSchema } from '../utils/makeStructuredResponseSchema'; import type { CyberfraudService } from '../services/cyberfraudService'; @@ -9,73 +9,50 @@ export function registerCyberfraudGetTrafficData(server: McpServer, cyberfraudSe server.registerTool( 'human_get_traffic_data', { - description: `Fetches comprehensive traffic analytics from HUMAN Security's Cyberfraud API. This powerful tool provides detailed insights into web and mobile traffic patterns, security metrics, and user behavior across your applications. + description: `Fetches traffic analytics from HUMAN Security's Cyberfraud Traffic Dashboard API. One tool call can request one or more views; the MCP decides which underlying endpoints to call and merges the results. ๐ŸŽฏ QUICK DECISION GUIDE: -โ”œโ”€โ”€ Need high-level totals without granular breakdowns? โ†’ Use "count" -โ”œโ”€โ”€ Need trends/charts? โ†’ Use "overtime" -โ”œโ”€โ”€ Need attack types? โ†’ Add "tops": ["incidents"] -โ”œโ”€โ”€ Need URL path information? โ†’ Add "tops": ["path"] -โ”œโ”€โ”€ Security focus only? โ†’ Add "traffic": ["blocked"] -โ””โ”€โ”€ Multi-platform analysis? โ†’ Include "source": ["web", "mobile"] +โ”œโ”€โ”€ Need trend charts / attack timeline? โ†’ overtime: true +โ”œโ”€โ”€ Need high-level totals / KPIs? โ†’ metrics: true +โ”œโ”€โ”€ Need attack types? โ†’ tops: ["incidentTypes"] +โ”œโ”€โ”€ Need URL path breakdown? โ†’ tops: ["path"] +โ”œโ”€โ”€ Need top blocked IP orgs? โ†’ tops: ["socketIpOrgName"] +โ”œโ”€โ”€ Security focus only? โ†’ filters: { trafficTags: ["blocked", "potentialBlock"] } +โ””โ”€โ”€ Multi-platform analysis? โ†’ trafficSource: ["web", "mobile"] -โŒ CRITICAL RULES: -โ€ข NEVER combine "count" + "overtime" (mutually exclusive) -โ€ข NEVER combine "overtime" + "tops" (creates misleading aggregation, see AGGREGATION WARNING below) -โ€ข "tops" completely transforms response structure -โ€ข "count" returns only high-level totals, no granularity -โ€ข Filters stack multiplicatively (can reduce data 87%+) +โœ… REQUEST MODES (combinable in one call): +โ€ข overtime: Per-minute time-series counts. Use seriesFields to break out by knownBot, customRule, or accessTokenName. +โ€ข metrics: Aggregated totals for the full time range (total, blocked, legitimate, goodKnownBots, etc.). +โ€ข tops: Top values for one or more fields, ranked by request count. Each field triggers a separate API call; results are merged keyed by field name. -๐Ÿšจ AGGREGATION WARNING - IMPORTANT API BEHAVIOR: -When combining "overtime" + "tops" parameters, the API exhibits unexpected aggregation: -โ€ข First interval: Contains ALL historical data aggregated (total counts) -โ€ข Subsequent intervals: All show 0 counts (creating false impression of no recent activity) -โ€ข Result: Appears as time-series but is actually front-loaded aggregate data - -CORRECT USAGE: -โ€ข "startTime" and "endTime" should be in ISO 8601 format, e.g. "${DATE_FORMAT_EXAMPLE_START}". -โ€ข Path analysis: Use "tops": ["path"] for path breakdowns (no "count") -โ€ข Time-series: Use "overtime" without "tops" -โ€ข Attack types: Use "count" + "tops": ["incidents"] for totals +๐Ÿ”ง FILTERS (optional, stack multiplicatively): +โ€ข filters.trafficTags: Security classification (blocked, legitimate, goodKnownBots, etc.) +โ€ข filters.pageType: User journey (login, checkout, carding_attempt, etc.) +โ€ข filters.browserFamily / osFamily / country: Device and geo filters โœ… HIGH-VALUE PATTERNS: -1. EXECUTIVE DASHBOARD: - {"count": ["legitimate", "blocked"]} - โ†’ Simple traffic health metrics without breakdowns - -2. PATH ANALYSIS: - {"tops": ["path"]} - โ†’ Most trafficked endpoints with accurate totals - -3. ATTACK TYPE ANALYSIS: - {"tops": ["incidents"]} - โ†’ Attack type breakdown with accurate totals +1. EXECUTIVE TRAFFIC SUMMARY: + {"startTime": "${DATE_FORMAT_EXAMPLE_START}", "endTime": "${DATE_FORMAT_EXAMPLE_END}", "metrics": true} -4. SECURITY TIMELINE: - {"overtime": ["blocked"]} - โ†’ Pure attack volume trends over time +2. ATTACK TIMELINE: + {"startTime": "${DATE_FORMAT_EXAMPLE_START}", "endTime": "${DATE_FORMAT_EXAMPLE_END}", "overtime": true, "filters": {"trafficTags": ["blocked", "potentialBlock"]}} -5. FOCUSED ANALYSIS: - {"count": ["blocked"], "pageType": ["login"], "source": ["web"]} - โ†’ Login-specific web security +3. ATTACK TYPE BREAKDOWN: + {"startTime": "${DATE_FORMAT_EXAMPLE_START}", "endTime": "${DATE_FORMAT_EXAMPLE_END}", "tops": ["incidentTypes"]} -โš ๏ธ ENVIRONMENT NOTES: -โ€ข Mobile traffic may be minimal/absent in some environments -โ€ข Page type filters dramatically reduce scope -โ€ข Incident classification reveals valuable attack taxonomy -โ€ข Time-series uses ~20-minute intervals +4. PATH ANALYSIS: + {"startTime": "${DATE_FORMAT_EXAMPLE_START}", "endTime": "${DATE_FORMAT_EXAMPLE_END}", "tops": ["path"]} -๐Ÿ”ง PARAMETER BEHAVIOR: -โ€ข "count": Aggregate totals across time range, should be used only when only total numbers are needed as the response will not include more granular breakdowns -โ€ข "overtime": Time-series with intervals (do NOT combine with "tops") -โ€ข "tops": Transforms aggregates to breakdowns (use with "count" only) -โ€ข "traffic": Security-only filter (excludes legitimate) -โ€ข "pageType": Journey-specific filter (very restrictive) -โ€ข "source": Platform filter (web/mobile) +5. FULL SECURITY INVESTIGATION (combined): + {"startTime": "${DATE_FORMAT_EXAMPLE_START}", "endTime": "${DATE_FORMAT_EXAMPLE_END}", "metrics": true, "overtime": true, "tops": ["incidentTypes", "socketIpOrgName"], "filters": {"trafficTags": ["blocked"]}} -Response provides structured data optimized for security dashboards, threat analysis, and executive reporting with quantifiable metrics and actionable intelligence.`, - inputSchema: TrafficDataInputSchema.shape, +โš ๏ธ NOTES: +โ€ข At least one of overtime, metrics, or tops must be specified. +โ€ข trafficSource defaults to ["web", "mobile"] when omitted. +โ€ข app_id is derived from the API token โ€” do not pass appIds. +โ€ข tops limit defaults to 10 (max 100). Use includeNulls to include null-valued rows.`, + inputSchema: TrafficDataInputBaseSchema.shape, outputSchema: makeStructuredResponseSchema(TrafficDataOutputSchema).shape, annotations: { title: 'HUMAN Get Traffic Data', diff --git a/src/types/cyberfraud/trafficData.ts b/src/types/cyberfraud/trafficData.ts index e98c146..c9dec62 100644 --- a/src/types/cyberfraud/trafficData.ts +++ b/src/types/cyberfraud/trafficData.ts @@ -1,201 +1,145 @@ import { z } from 'zod'; import { DATE_FORMAT_EXAMPLE_END, DATE_FORMAT_EXAMPLE_START } from '../../utils/constants'; -export const TrafficDataSourceEnum = z.enum(['web', 'mobile'], { - description: - 'Platform filter: ["web"], ["mobile"], or ["web","mobile"]. NOTE: Mobile traffic may be minimal/absent in some environments (observed 99.999% web dominance). Use both for complete coverage, individual for platform-specific analysis.', -}); -export const TrafficDataOvertimeEnum = z.enum( - ['legitimate', 'blocked', 'potentialBlock', 'whitelist', 'blacklist', 'goodKnownBots', 'captchaSolved'], - { - description: - 'TIME-SERIES ANALYSIS: Returns intervals with ~20min timestamps for trend visualization. โŒ MUTUALLY EXCLUSIVE with "count" parameter. ๐Ÿšจ CRITICAL: DO NOT combine with "tops" - causes misleading aggregation with all data front-loaded into first interval. โœ… BEST FOR: Attack timelines, trend charts, pattern detection. EXAMPLE: {"overtime": ["blocked"]} โ†’ Attack volume over time. COMBINE WITH: filters for focus, but NEVER with "tops".', - }, -); -export const TrafficDataTopsEnum = z.enum(['incidents', 'path'], { - description: - '๐Ÿ”„ RESPONSE TRANSFORMER: Completely changes response structure from aggregates to detailed breakdowns. ๐Ÿšจ CRITICAL: DO NOT combine with "overtime" - causes misleading aggregation where all historical data appears in first interval with zeros after. โš ๏ธ CRITICAL INSIGHTS: "incidents" reveals attack classification (Bot Behavior, Spoof, Bad Reputation, etc.), "path" shows URL-specific targeting. WITHOUT tops: Aggregate totals. WITH tops: Individual breakdowns per category. โœ… SAFE USAGE: Combine with "count" only.', -}); -export const TrafficDataTrafficEnum = z.enum(['blocked', 'blacklist', 'potentialBlock'], { - description: - 'SECURITY-ONLY FILTER: Shows EXCLUSIVELY blocked/suspicious traffic. COMPLEMENTS count/overtime metrics, does NOT replace them. โœ… USE CASE: Pure security analysis, threat-focused reporting. EXCLUDES: All legitimate traffic. COMBINE WITH: Any count/overtime metrics for security-centric view.', -}); -export const TrafficDataPageTypeEnum = z.enum( - [ - 'login', - 'login_attempt', - 'checkout', - 'purchase', - 'purchase_request', - 'productsAndSearch', - 'research', - 'apiCall', - 'resource', - 'mobileUserAgents', - ], - { - description: - 'PAGE TYPE FILTER: Focuses analysis on specific user journeys. โš ๏ธ SCOPE WARNING: Very restrictive (observed 87% data reduction). USE CASES: Login security analysis, checkout protection, API endpoint monitoring. COMBINE WITH: Security metrics for targeted threat analysis.', - }, -); -export const TrafficDataCountEnum = z.enum( - [ - 'legitimate', - 'potentialBlock', - 'blocked', - 'whitelist', - 'blacklist', - 'goodKnownBots', - 'captchaSolved', - 'mobile', - 'web', - ], - { - description: - 'AGGREGATE ANALYSIS: Returns total counts across entire time range. โŒ MUTUALLY EXCLUSIVE with "overtime" parameter. โš ๏ธ LIMITATION: Will NOT return path breakdowns even with tops=["path"] - returns aggregate totals only. โœ… BEST FOR: Dashboards, KPIs, executive summaries. EXAMPLE: {"count": ["legitimate", "blocked"]} โ†’ Simple totals.', - }, -); +export const TrafficDataSourceEnum = z.enum(['web', 'mobile']); + +export const TrafficDataTrafficTagsEnum = z.enum([ + 'legitimate', + 'blocked', + 'potentialBlock', + 'goodKnownBots', + 'whitelist', + 'blacklist', + 'compromisedLogin', + 'failedLogin', + 'successfulLogin', + 'successfulCompromised', + 'legitimateCompromised', + 'blockedCompromised', + 'captchaSolved', +]); + +export const TrafficDataPageTypeEnum = z.enum([ + 'login', + 'login_attempt', + 'checkout', + 'carding_attempt', + 'purchase', + 'purchase_request', + 'productsAndSearch', + 'research', + 'resource', + 'apiCall', + 'mobileUserAgents', +]); + +export const TrafficDataSeriesFieldsEnum = z.enum(['accessTokenName', 'customRule', 'knownBot']); -export const TrafficDataMetricsEnrichmentSchema = z +export const TrafficDataTopsFieldEnum = z.enum([ + 'socketIp', + 'domain', + 'headerReferer', + 'incidentTypes', + 'socketIpOrgName', + 'path', + 'knownBot', + 'uaServer', + 'providerCloud', + 'providerProxy', + 'providerVpn', + 'providerClassification', + 'country', + 'customRule', + 'accessTokenName', + 'customParam1', + 'customParam2', + 'customParam3', + 'customParam4', + 'customParam5', + 'customParam6', + 'customParam7', + 'customParam8', + 'customParam9', + 'utmSource', + 'utmMedium', + 'utmCampaign', + 'utmTerm', + 'graphqlOperationName', +]); + +export const TrafficDataFiltersSchema = z .object({ - accountName: z - .string() - .optional() - .describe( - '๐Ÿข ACCOUNT CONTEXT: Human-readable account name for dashboard labeling and report generation. ๐Ÿ’ก USE CASES: Multi-tenant environments, executive reporting, audit trails. ๐Ÿ“Š ENRICHMENT: Adds business context without affecting core metrics.', - ), - widgetTitle: z - .string() - .optional() - .describe( - '๐Ÿ“Š DASHBOARD LABELING: Custom title for UI widgets and chart displays. ๐Ÿ’ก USE CASES: Custom dashboards, executive summaries, operational monitoring. ๐ŸŽฏ EXAMPLES: "Login Security Overview", "Attack Timeline - Production".', - ), - uiContext: z - .string() - .optional() - .describe( - '๐Ÿ–ฅ๏ธ UI INTEGRATION: Context identifier for frontend integration and state management. ๐Ÿ’ก USE CASES: Multi-dashboard applications, widget state tracking, user interface coordination. ๐Ÿ“‹ EXAMPLES: "main-dashboard", "security-ops-center", "executive-summary".', - ), + trafficTags: z.array(TrafficDataTrafficTagsEnum).optional(), + pageType: z.array(TrafficDataPageTypeEnum).optional(), + browserFamily: z.array(z.string()).optional(), + osFamily: z.array(z.string()).optional(), + country: z.array(z.string()).optional(), }) - .passthrough(); + .optional(); -export const TrafficDataInputSchema = z.object({ +export const TrafficDataInputBaseSchema = z.object({ startTime: z .string() - .describe( - `โฐ TIME RANGE START: ISO 8601 datetime string defining analysis period beginning. ๐ŸŽฏ FORMAT: "${DATE_FORMAT_EXAMPLE_START}". โš ๏ธ CONSTRAINT: Must be within API limits for data retention. ๐Ÿ’ก STRATEGY: Use shorter windows for real-time monitoring, longer periods for trend analysis and pattern detection.`, - ), + .describe(`Start of the analysis time range in ISO 8601 format, e.g. "${DATE_FORMAT_EXAMPLE_START}".`), endTime: z .string() - .describe( - `๐Ÿ TIME RANGE END: ISO 8601 datetime string defining analysis period conclusion. ๐ŸŽฏ FORMAT: "${DATE_FORMAT_EXAMPLE_END}". โš ๏ธ CONSTRAINT: Must be after startTime. ๐Ÿ’ก STRATEGY: Use current time for live dashboards, specific timestamps for historical analysis and incident investigation.`, - ), - source: z + .describe(`End of the analysis time range in ISO 8601 format, e.g. "${DATE_FORMAT_EXAMPLE_END}".`), + trafficSource: z .array(TrafficDataSourceEnum) .optional() - .describe( - '๐ŸŒ PLATFORM FILTER: ["web"], ["mobile"], or both. NOTE: Mobile traffic often minimal (<0.001% observed). Use for platform-specific security analysis or complete coverage.', - ), - overtime: z - .array(TrafficDataOvertimeEnum) + .describe('Platform filter: ["web"], ["mobile"], or both. Defaults to ["web", "mobile"].'), + filters: TrafficDataFiltersSchema.describe( + 'Optional filters for trafficTags, pageType, browserFamily, osFamily, and country.', + ), + overtime: z.boolean().optional().describe('Fetch per-minute time-series traffic counts over the requested range.'), + seriesFields: z + .array(TrafficDataSeriesFieldsEnum) .optional() - .describe( - '๐Ÿ“ˆ TIME-SERIES DATA: Returns ~20min interval data for trends. โŒ CANNOT combine with "count". ๐Ÿšจ CRITICAL: DO NOT combine with "tops" - causes misleading aggregation with all data front-loaded into first interval. โœ… PERFECT FOR: Attack timelines, trend analysis, pattern detection. EXAMPLES: {"overtime": ["blocked"]} โ†’ Attack volume timeline.', - ), + .describe('Break out additional overtime series per value. Only applies when overtime is true.'), + metrics: z.boolean().optional().describe('Fetch aggregated traffic totals for the time range.'), tops: z - .array(TrafficDataTopsEnum) - .optional() - .describe( - '๐Ÿ”„ BREAKDOWN TRANSFORMER: Changes from totals to detailed categorization. ๐Ÿšจ CRITICAL: DO NOT combine with "overtime" - causes misleading front-loaded aggregation. โš ๏ธ INSIGHTS: "incidents" reveals attack types (Bot Behavior, Spoof, Bad Reputation), "path" shows URL targeting. โœ… SAFE USAGE: Combine with "count" only for accurate breakdowns.', - ), - traffic: z - .array(TrafficDataTrafficEnum) + .array(TrafficDataTopsFieldEnum) .optional() - .describe( - '๐Ÿšจ SECURITY-ONLY FILTER: Shows ONLY threats/blocks. Excludes all legitimate traffic. PERFECT FOR: Pure security analysis, threat hunting, incident investigation. COMBINES WITH: any count/overtime metrics.', - ), - pageType: z - .array(TrafficDataPageTypeEnum) - .optional() - .describe( - '๐ŸŽฏ PAGE JOURNEY FILTER: Focus on specific user flows. โš ๏ธ MAJOR SCOPE REDUCTION: Can eliminate 87%+ of data. BEST FOR: Login security, checkout protection, API monitoring. USE SPARINGLY for targeted analysis.', - ), - count: z - .array(TrafficDataCountEnum) - .optional() - .describe( - '๐Ÿ“Š AGGREGATE TOTALS: Returns summary counts across time range. โŒ CANNOT combine with "overtime". โœ… PERFECT FOR: Executive dashboards, KPI reporting, quick health checks. EXAMPLES: {"count": ["legitimate", "blocked"]} โ†’ Traffic health summary.', - ), - withoutTotals: z - .boolean() - .optional() - .describe( - 'Excludes summary totals from response. Use when only breakdown data is needed to reduce response size.', - ), - metricsEnrichment: TrafficDataMetricsEnrichmentSchema.optional().describe( - '๐Ÿท๏ธ CONTEXTUAL METADATA: Enrichment object for dashboard integration and reporting context. โš ๏ธ NO IMPACT: Does not affect core data or query performance. ๐Ÿ’ก USE CASES: Multi-tenant dashboards, executive reporting, UI state management. ๐Ÿ“Š BENEFITS: Enhanced labeling, audit trails, and business context for analysis.', - ), + .describe('Fetch top values for one or more fields, sorted by request count.'), + limit: z.number().min(1).max(100).optional().describe('Max tops results per field (1-100). Defaults to 10.'), + includeNulls: z.boolean().optional().describe('Include rows where the tops field is null. Defaults to false.'), }); -export type TrafficDataInput = z.infer; - -const TrafficDataIntervalSchema = z - .object({ - timestamp: z - .number() - .optional() - .describe( - 'โฑ๏ธ INTERVAL TIMESTAMP: Timestamp for the ~20-minute interval (milliseconds since epoch). Essential for time-series visualization and trend analysis.', - ), - count: z.number().optional().describe('Count for this interval.'), - }) - .passthrough(); -const TrafficDataSeriesOvertimeSchema = z - .object({ - value: z.string().optional().describe('Label or value for this series.'), - intervals: z.array(TrafficDataIntervalSchema).optional().describe('List of intervals for this series.'), - }) - .passthrough(); +export const TrafficDataInputSchema = TrafficDataInputBaseSchema.refine( + (data) => data.overtime === true || data.metrics === true || (data.tops !== undefined && data.tops.length > 0), + { message: 'At least one of overtime, metrics, or tops must be specified.' }, +); -const TrafficDataSeriesCountSchema = z - .object({ - value: z.string().optional().describe('Label or value for this series.'), - count: z.number().optional().describe('Count for this series.'), - }) - .passthrough(); +export type TrafficDataInput = z.infer; -const TrafficDataTotalsSchema = z +const TrafficDataOvertimeResultSchema = z .object({ - total: z.number().optional().describe('Total count.'), - totalBlocked: z.number().optional().describe('Total blocked count.'), + timestamp: z.string(), }) .passthrough(); -const TrafficDataContentSchema = z - .object({ - legitimate: z.array(TrafficDataSeriesOvertimeSchema).optional(), - blocked: z.array(TrafficDataSeriesOvertimeSchema).optional(), - blacklist: z.array(TrafficDataSeriesOvertimeSchema).optional(), - goodKnownBots: z.array(TrafficDataSeriesOvertimeSchema).optional(), - potentialBlock: z.array(TrafficDataSeriesOvertimeSchema).optional(), - whitelist: z.array(TrafficDataSeriesOvertimeSchema).optional(), - captchaSolved: z.array(TrafficDataSeriesOvertimeSchema).optional(), - incidents: z.array(TrafficDataSeriesCountSchema).optional(), - path: z.array(TrafficDataSeriesCountSchema).optional(), - mobile: z.array(TrafficDataSeriesCountSchema).optional(), - web: z.array(TrafficDataSeriesCountSchema).optional(), - totals: TrafficDataTotalsSchema.optional(), - dataLags: z.array(z.unknown()).optional(), - }) - .passthrough() - .optional() - .describe('Main content data, keyed by metric type.'); +const TrafficDataTopsResultSchema = z.object({ + value: z.string(), + count: z.number(), +}); export const TrafficDataOutputSchema = z .object({ - result: z.boolean().optional().describe('Whether the request was successful.'), - message: z.string().optional().describe('Response message.'), - content: TrafficDataContentSchema, + overtime: z + .object({ + results: z.array(TrafficDataOvertimeResultSchema), + }) + .passthrough() + .optional(), + metrics: z + .object({ + results: z.record(z.string(), z.number()), + labels: z.record(z.string(), z.string()).optional(), + }) + .passthrough() + .optional(), + tops: z.record(z.string(), z.array(TrafficDataTopsResultSchema)).optional(), }) .passthrough(); + export type TrafficDataResponse = z.infer; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 4655158..839f255 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -4,7 +4,13 @@ export const DATE_FORMAT_EXAMPLE_START = '2025-06-23T10:00:00Z'; export const DATE_FORMAT_EXAMPLE_END = '2025-06-23T16:00:00Z'; export const HUMAN_API_HOST = process.env.HUMAN_API_HOST || 'api.humansecurity.com'; export const HUMAN_API_VERSION = process.env.HUMAN_API_VERSION || 'v1'; -export const HUMAN_API_BASE = `https://${HUMAN_API_HOST}/${HUMAN_API_VERSION}`; +const isLocalhost = HUMAN_API_HOST.startsWith('localhost') || HUMAN_API_HOST.startsWith('127.0.0.1'); +export const HUMAN_API_BASE = `${isLocalhost ? 'http' : 'https'}://${HUMAN_API_HOST}/${HUMAN_API_VERSION}`; + +// Override the full traffic-data base URL (e.g. for local pxPortal testing). +// Default: /cyberfraud/traffic-data (production gateway path) +// Local: http://localhost:3000/api/v1/botDefender/traffic +export const HUMAN_TRAFFIC_API_BASE = process.env.HUMAN_TRAFFIC_API_BASE ?? `${HUMAN_API_BASE}/cyberfraud/traffic-data`; export const HTTP_TIMEOUT_MS = process.env.HTTP_TIMEOUT_MS ? parseInt(process.env.HTTP_TIMEOUT_MS, 10) : 30000; export const MCP_VERSION_HEADER = 'x-px-mcp-version'; export const MCP_VERSION = packageJson.version; diff --git a/src/utils/httpClient.ts b/src/utils/httpClient.ts index 17536bb..a86ed22 100644 --- a/src/utils/httpClient.ts +++ b/src/utils/httpClient.ts @@ -38,6 +38,9 @@ export class HttpClient { if (this.apiToken) { headers['Authorization'] = `Bearer ${this.apiToken}`; } + if (options.body !== undefined) { + headers['Content-Type'] = 'application/json'; + } headers[MCP_VERSION_HEADER] = MCP_VERSION; const res = await this.fetchImpl(url, { method: options.method || 'GET', diff --git a/test/services/cyberfraudService.test.ts b/test/services/cyberfraudService.test.ts index a236177..0a301f4 100644 --- a/test/services/cyberfraudService.test.ts +++ b/test/services/cyberfraudService.test.ts @@ -105,4 +105,134 @@ describe('CyberfraudService', () => { const url = httpClient.request.firstCall.args[0]; expect(url).to.include('/overview/cid123'); }); + + describe('getTrafficData', () => { + const now = new Date(); + const startTime = new Date(now.getTime() - 24 * 60 * 60 * 1000).toISOString(); + const endTime = now.toISOString(); + const baseParams = { startTime, endTime }; + + function mockApiResponse(content: unknown) { + return { json: async () => ({ result: true, message: 'success', content }), ok: true }; + } + + it('calls POST /overtime with correct URL, method, and body', async () => { + const overtimeContent = { results: [{ timestamp: '2026-06-23T05:57:00.000Z', blocked: 100 }] }; + httpClient.request.resolves(mockApiResponse(overtimeContent)); + + const result = await service.getTrafficData({ ...baseParams, overtime: true } as any); + + expect(httpClient.request.calledOnce).to.be.true; + const [url, options] = httpClient.request.firstCall.args; + expect(url).to.include('/cyberfraud/traffic-data/overtime'); + expect(url).to.include('from='); + expect(url).to.include('to='); + expect(options.method).to.equal('POST'); + expect(options.body.trafficSource).to.deep.equal(['web', 'mobile']); + expect(result.overtime).to.deep.equal(overtimeContent); + }); + + it('calls POST /metrics with filters in body', async () => { + const metricsContent = { + results: { total: 1000, blocked: 50 }, + labels: { total: 'Total Requests' }, + }; + httpClient.request.resolves(mockApiResponse(metricsContent)); + + const result = await service.getTrafficData({ + ...baseParams, + metrics: true, + trafficSource: ['web'], + filters: { trafficTags: ['blocked'] }, + } as any); + + expect(httpClient.request.calledOnce).to.be.true; + const [url, options] = httpClient.request.firstCall.args; + expect(url).to.include('/cyberfraud/traffic-data/metrics'); + expect(options.method).to.equal('POST'); + expect(options.body.trafficSource).to.deep.equal(['web']); + expect(options.body.filters).to.deep.equal({ trafficTags: ['blocked'] }); + expect(result.metrics).to.deep.equal(metricsContent); + }); + + it('calls POST /tops/:field for a single tops field', async () => { + const topsContent = { results: [{ value: '/login', count: 500 }] }; + httpClient.request.resolves(mockApiResponse(topsContent)); + + const result = await service.getTrafficData({ + ...baseParams, + tops: ['path'], + limit: 5, + } as any); + + expect(httpClient.request.calledOnce).to.be.true; + const [url, options] = httpClient.request.firstCall.args; + expect(url).to.include('/cyberfraud/traffic-data/tops/path'); + expect(options.method).to.equal('POST'); + expect(options.body.limit).to.equal(5); + expect(result.tops).to.deep.equal({ path: topsContent.results }); + }); + + it('issues parallel tops calls and merges results keyed by field', async () => { + httpClient.request + .onFirstCall() + .resolves(mockApiResponse({ results: [{ value: 'Bot Behavior', count: 100 }] })); + httpClient.request + .onSecondCall() + .resolves(mockApiResponse({ results: [{ value: '/checkout', count: 200 }] })); + + const result = await service.getTrafficData({ + ...baseParams, + tops: ['incidentTypes', 'path'], + } as any); + + expect(httpClient.request.calledTwice).to.be.true; + expect(httpClient.request.firstCall.args[0]).to.include('/tops/incidentTypes'); + expect(httpClient.request.secondCall.args[0]).to.include('/tops/path'); + expect(result.tops).to.deep.equal({ + incidentTypes: [{ value: 'Bot Behavior', count: 100 }], + path: [{ value: '/checkout', count: 200 }], + }); + }); + + it('combines overtime, metrics, and tops in one call', async () => { + httpClient.request + .onCall(0) + .resolves(mockApiResponse({ results: [{ timestamp: '2026-06-23T05:57:00.000Z' }] })); + httpClient.request.onCall(1).resolves(mockApiResponse({ results: { total: 1000 } })); + httpClient.request.onCall(2).resolves(mockApiResponse({ results: [{ value: 'US', count: 300 }] })); + + const result = await service.getTrafficData({ + ...baseParams, + overtime: true, + metrics: true, + tops: ['country'], + seriesFields: ['knownBot'], + } as any); + + expect(httpClient.request.calledThrice).to.be.true; + expect(result.overtime).to.exist; + expect(result.metrics).to.exist; + expect(result.tops?.country).to.deep.equal([{ value: 'US', count: 300 }]); + expect(httpClient.request.firstCall.args[1].body.seriesFields).to.deep.equal(['knownBot']); + }); + + it('throws when API returns result: false', async () => { + httpClient.request.resolves({ + json: async () => ({ result: false, message: 'Invalid time range' }), + ok: true, + }); + + await expect(service.getTrafficData({ ...baseParams, metrics: true } as any)).to.be.rejectedWith( + 'Invalid time range', + ); + }); + + it('propagates httpClient.request error', async () => { + httpClient.request.rejects(new Error('network fail')); + await expect(service.getTrafficData({ ...baseParams, metrics: true } as any)).to.be.rejectedWith( + 'network fail', + ); + }); + }); }); diff --git a/test/tools/getTrafficData.test.ts b/test/tools/getTrafficData.test.ts new file mode 100644 index 0000000..9cdf178 --- /dev/null +++ b/test/tools/getTrafficData.test.ts @@ -0,0 +1,24 @@ +import * as chai from 'chai'; +import sinon from 'sinon'; +import { registerCyberfraudGetTrafficData } from '../../src/tools/getTrafficData'; + +describe('registerCyberfraudGetTrafficData', () => { + const { expect } = chai; + + it('registers tool and handler calls service', async () => { + const server = { registerTool: sinon.stub() }; + const service = { getTrafficData: sinon.stub().resolves({ metrics: { results: { total: 100 } } }) }; + registerCyberfraudGetTrafficData(server as any, service as any); + expect(server.registerTool.calledOnce).to.be.true; + const [name, config, handler] = server.registerTool.firstCall.args; + expect(name).to.equal('human_get_traffic_data'); + expect(config).to.have.property('description'); + const params = { + startTime: '2025-06-23T10:00:00Z', + endTime: '2025-06-23T16:00:00Z', + metrics: true, + }; + await handler(params); + expect(service.getTrafficData.calledWith(params)).to.be.true; + }); +}); diff --git a/test/utils/httpClient.test.ts b/test/utils/httpClient.test.ts index 32f6e42..0a436dd 100644 --- a/test/utils/httpClient.test.ts +++ b/test/utils/httpClient.test.ts @@ -58,6 +58,20 @@ describe('HttpClient', () => { expect(args.body).to.equal(JSON.stringify({ foo: 'bar' })); }); + it('sets Content-Type application/json when body is present', async () => { + fetchStub.resolves(new MockResponse('{}', { status: 200 })); + await client.request(url, { method: 'POST', body: { foo: 'bar' } }); + const headers = fetchStub.firstCall.args[1].headers; + expect(headers['Content-Type']).to.equal('application/json'); + }); + + it('does not set Content-Type when body is absent', async () => { + fetchStub.resolves(new MockResponse('{}', { status: 200 })); + await client.request(url); + const headers = fetchStub.firstCall.args[1].headers; + expect(headers['Content-Type']).to.be.undefined; + }); + it('adds Authorization header if apiToken is set', async () => { fetchStub.resolves(new MockResponse('{}', { status: 200 })); await client.request(url); From 7a39a3475a3befb99cabb8a110dd5b3ea6c77ea8 Mon Sep 17 00:00:00 2001 From: asafcohenpx <80626954+asafcohenpx@users.noreply.github.com> Date: Wed, 1 Jul 2026 16:11:40 +0300 Subject: [PATCH 20/21] bump version to 1.0.5 (#125) Co-authored-by: Cursor --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6cdd29a..473dbbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.0.5] - 2026-07-01 + +### Changed + +* Adjusted traffic data tool to new backend routes + ## [1.0.4] - 2025-09-09 ### Fixed diff --git a/package-lock.json b/package-lock.json index 08b8f88..ea20748 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@humansecurity/human-mcp-server", - "version": "1.0.4", + "version": "1.0.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@humansecurity/human-mcp-server", - "version": "1.0.4", + "version": "1.0.5", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.20.2", diff --git a/package.json b/package.json index 63eb0c9..fbaf8e6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.0.4", + "version": "1.0.5", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs", From 0873bb2dbf740d8dbb79fa3a035aa54fe4f25c67 Mon Sep 17 00:00:00 2001 From: asafcohenpx <80626954+asafcohenpx@users.noreply.github.com> Date: Thu, 2 Jul 2026 13:19:55 +0300 Subject: [PATCH 21/21] version (#127) --- CHANGELOG.md | 6 ++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 473dbbb..2897f55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.1.1] - 2026-07-02 + +### Fixed + +* Corrected version numbering: `1.1.0` was inadvertently published to npm ahead of the `1.0.x` line and superseded by subsequent `1.0.x` releases, leaving the registry with out-of-order versions. Bumping to `1.1.1` restores strictly increasing semantic versioning going forward. + ## [1.0.5] - 2026-07-01 ### Changed diff --git a/package-lock.json b/package-lock.json index ea20748..56b964b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@humansecurity/human-mcp-server", - "version": "1.0.5", + "version": "1.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@humansecurity/human-mcp-server", - "version": "1.0.5", + "version": "1.1.1", "license": "MIT", "dependencies": { "@modelcontextprotocol/sdk": "^1.20.2", diff --git a/package.json b/package.json index fbaf8e6..e1624dc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@humansecurity/human-mcp-server", "description": "Model Context Protocol (MCP) server providing comprehensive cybersecurity intelligence from HUMAN Security. Offers real-time attack monitoring, threat detection, fraud prevention, PCI DSS compliance validation, and supply chain security for AI-powered applications.", - "version": "1.0.5", + "version": "1.1.1", "type": "module", "main": "./dist/index.cjs", "bin": "./dist/index.cjs",