Mostly safe โ a couple of notes worth reading.
Scanned 5/3/2026, 6:45:11 PMยทCached resultยทFast Scanยท45 rulesยทHow we decide โ
AIVSS Score
Low
Severity Breakdown
0
critical
0
high
16
medium
0
low
MCP Server Information
Findings
This package receives a B grade with a safety score of 77/100 and carries moderate risk from 16 medium-severity findings, primarily involving ANSI escape injection vulnerabilities (4 instances) and server configuration issues (12 instances). The AIVSS score of 2.8/10 indicates notable security concerns that should be addressed before deployment. You should review the specific configuration and injection issues to determine if they affect your intended use case.
No known CVEs found for this package or its dependencies.
Scan Details
Want deeper analysis?
Fast scan found 16 findings using rule-based analysis. Upgrade for LLM consensus across 5 judges, AI-generated remediation, and cross-file taint analysis.
Building your own MCP server?
Same rules, same LLM judges, same grade. Private scans stay isolated to your account and never appear in the public registry. Required for code your team hasnโt shipped yet.
16 of 16 findings
16 findings
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 70 | projectName, |
| 71 | ); |
| 72 | } catch (error) { |
| 73 | console.error('Error cleaning up test pull request:', error); |
| 74 | } |
| 75 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 397 | projectId, |
| 398 | ); |
| 399 | } catch (error) { |
| 400 | console.log( |
| 401 | `Error adding reviewer ${reviewer} to pull request ${pullRequestId}: ${ |
| 402 | error instanceof Error ? error.message : String(error) |
| 403 | }`, |
| 404 | ); |
| 405 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 417 | projectId, |
| 418 | ); |
| 419 | } catch (error) { |
| 420 | console.log( |
| 421 | `Error removing reviewer ${reviewer} from pull request ${pullRequestId}: ${ |
| 422 | error instanceof Error ? error.message : String(error) |
| 423 | }`, |
| 424 | ); |
| 425 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
User-controlled value printed to terminal without ANSI escape sanitization. Malicious input can inject cursor-control sequences, rewrite earlier output, or hide shell commands from the operator.
Evidence
| 339 | } |
| 340 | } |
| 341 | } catch (error) { |
| 342 | console.log( |
| 343 | `Error removing work item ${workItemId} from pull request ${pullRequestId}: ${ |
| 344 | error instanceof Error ? error.message : String(error) |
| 345 | }`, |
| 346 | ); |
| 347 | } |
Remediation
Strip C0/C1 control codes before printing user-controlled values. Python: re.sub(r"[\x00-\x08\x0b-\x1f\x7f]", "", s). Prefer a structured logger (json/logfmt) over raw print to stdout.
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 27 | .optional() |
| 28 | .describe(`The ID or name of the organization (Default: ${defaultOrg})`), |
| 29 | teamId: z.string().optional().describe('The ID of the team'), |
| 30 | queryId: z.string().optional().describe('ID of a saved work item query'), |
| 31 | wiql: z.string().optional().describe('Work Item Query Language (WIQL) query'), |
| 32 | top: z.number().optional().describe('Maximum number of work items to return'), |
| 33 | skip: z.number().optional().describe('Number of work items to skip'), |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
MCP tool input schema exposes an unconstrained string/any field with a risky name (command/query/sql/code/script/url/path/expr/ eval). Any caller can pass arbitrary values, which typically widens the tool's blast radius well beyond its intent. Narrow the schema with `.enum()`, `.regex()`, `.max()`, `Literal[...]`, Pydantic `Field(max_length=..., pattern=...)`, or a JSON Schema `enum` / `pattern` / `maxLength`.
Evidence
| 282 | }); |
| 283 | |
| 284 | export const PullRequestFileChangeSchema = z.object({ |
| 285 | path: z.string().describe('Path of the changed file'), |
| 286 | patch: z.string().describe('Unified diff of the file'), |
| 287 | }); |
Remediation
Shape the schema to the tool's actual intent: - Zod: chain `.enum([...])`, `.regex(/.../)`, or `.max(n)`; prefer `z.enum([...])` or `z.literal(...)` when the value set is small. - Pydantic: use `Literal["a", "b"]` or `Field(max_length=..., pattern=r"...")`. - JSON Schema: add `"enum"`, `"pattern"`, or `"maxLength"` to the property. An overbroad schema is an "overpowered tool" โ the model has nothing to prevent it from calling the tool with input far beyond what the tool's prose contract
Package declares an install-time hook (npm postinstall/preinstall/prepare, setup.py cmdclass override, custom setuptools install class, or non-default pyproject build-backend). Anyone installing this package runs the hook. Confirm the hook is necessary and review its contents; prefer shipping a plain library without install-time execution.
Evidence
| 80 | "lint": "eslint . --ext .ts", |
| 81 | "lint:fix": "eslint . --ext .ts --fix", |
| 82 | "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"", |
| 83 | "prepare": "husky install", |
| 84 | "commit": "cz" |
| 85 | }, |
| 86 | "keywords": [ |
Remediation
Prefer libraries that do not require install-time code execution: - Drop `postinstall`/`preinstall`/`prepare` scripts if the work can happen at runtime or build-time instead. - Ship pre-built native binaries rather than compiling via a custom `cmdclass` or `build_ext` override. - For Dockerfiles: replace `RUN curl โฆ | sh` with a pinned download + checksum verification + explicit `RUN` of a named script. - If the hook is unavoidable, document exactly what it does so downstream reviewers
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 15 | runs-on: ubuntu-latest |
| 16 | steps: |
| 17 | - name: Checkout repository |
| 18 | uses: actions/checkout@v4 |
| 19 | |
| 20 | - name: Clone anthropics/skills repository |
| 21 | run: | |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 51 | - name: Create Pull Request |
| 52 | if: steps.check_changes.outputs.changes == 'true' |
| 53 | uses: peter-evans/create-pull-request@v5 |
| 54 | with: |
| 55 | token: ${{ secrets.GITHUB_TOKEN }} |
| 56 | commit-message: 'chore(skills): update skill-creator from anthropics/skills' |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 32 | # The following steps only run if a new release is created |
| 33 | - name: Checkout code |
| 34 | if: ${{ steps.release.outputs.release_created }} |
| 35 | uses: actions/checkout@v4 |
| 36 | with: |
| 37 | ref: ${{ steps.release.outputs.tag_name }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 18 | with: |
| 19 | ref: ${{ github.event.pull_request.head.sha }} |
| 20 | - name: Use latest Node LTS |
| 21 | uses: actions/setup-node@v4 |
| 22 | with: |
| 23 | node-version: 'lts/*' |
| 24 | - name: Install Dependencies |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 14 | environment: external-pr-check |
| 15 | |
| 16 | steps: |
| 17 | - uses: actions/checkout@v4 |
| 18 | with: |
| 19 | ref: ${{ github.event.pull_request.head.sha }} |
| 20 | - name: Use latest Node LTS |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 62 | if: ${{ github.event.inputs.tag != '' && github.event.inputs.tag != null }} |
| 63 | steps: |
| 64 | - name: Checkout code |
| 65 | uses: actions/checkout@v4 |
| 66 | with: |
| 67 | ref: ${{ github.event.inputs.tag }} |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 67 | ref: ${{ github.event.inputs.tag }} |
| 68 | |
| 69 | - name: Setup Node.js |
| 70 | uses: actions/setup-node@v4 |
| 71 | with: |
| 72 | node-version: 'lts/*' |
| 73 | registry-url: 'https://registry.npmjs.org/' |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 23 | # Only run release-please if no tag was specified (normal automated flow) |
| 24 | if: ${{ github.event.inputs.tag == '' || github.event.inputs.tag == null }} |
| 25 | steps: |
| 26 | - uses: google-github-actions/release-please-action@v4 |
| 27 | id: release |
| 28 | with: |
| 29 | config-file: .github/release-please-config.json |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc
GitHub Actions `uses:` reference is not pinned to a 40-character commit SHA. Tags (`@v4`) and branches (`@main`) are mutable โ a compromised maintainer or a tag rewrite can substitute malicious code into your CI pipeline silently. Pin to a SHA: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab`. For readability, include the version as a trailing comment: `# v4.1.1`. Tools like `pinact` / `ratchet` automate this. Allowed unpinned forms (excluded by the rule): - Local actions `.
Evidence
| 38 | - name: Setup Node.js |
| 39 | if: ${{ steps.release.outputs.release_created }} |
| 40 | uses: actions/setup-node@v4 |
| 41 | with: |
| 42 | node-version: 'lts/*' |
| 43 | registry-url: 'https://registry.npmjs.org/' |
Remediation
Pin every `uses:` to a 40-character commit SHA. Trailing comment with the version helps reviewers: `uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v4.1.1` Automate the migration with `pinact` (https://github.com/suzuki-shunsuke/pinact) or `ratchet` (https://github.com/sethvargo/ratchet). Add a `pinact run --check` pre-commit hook so future PRs stay pinned. Re-pin when the action releases a new version โ Dependabot can do this automatically with `version-update-strategy: inc