# Dependency Vulnerability Scanner (OSV) (`cliqtomedia/osv-dependency-vulnerability-scanner`) Actor

Check npm, PyPI, Maven, Go, Cargo and 9 more ecosystems for known vulnerabilities via OSV.dev. Paste a list, package.json, package-lock.json or requirements.txt; get one deduplicated row per CVE/GHSA with severity, CVSS and the fix for your version.

- **URL**: https://apify.com/cliqtomedia/osv-dependency-vulnerability-scanner.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.52 / 1,000 vulnerability founds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Dependency Vulnerability Scanner checks your npm, PyPI, Maven, Go, Cargo and other packages for known vulnerabilities in the free [OSV.dev](https://osv.dev) database. Paste a list such as `npm:lodash@4.17.15`, a `package.json`, a `package-lock.json` or a `requirements.txt`. You get one row per vulnerability with the CVE and GHSA ids, severity, CVSS score, CWE and the version that fixes it on **your** version branch.

It is made for developers, security reviews and CI checks. No login and no API key are needed. The form example (6 packages) finishes in a few seconds and costs $0.0572.

![Dependency Vulnerability Scanner: a manifest goes in, one row per known vulnerability comes out with severity and the fix version](https://api.apify.com/v2/key-value-stores/qNQFuhfh3eibTX0T4/records/README-BANNER-20261013.png)

### Contents

- [What it does](#what-it-does)
- [Quick start](#quick-start)
- [Use cases](#use-cases)
- [Input](#input)
- [Output](#output)
- [Pricing](#pricing)
- [Limits](#limits)
- [API and integrations](#api-and-integrations)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Data source and licence](#data-source-and-licence)
- [Support](#support)

### What it does

The Actor asks the public [OSV API](https://google.github.io/osv.dev/api/) live at run time. OSV collects advisories from the GitHub Advisory Database, PyPA, RustSec, the Go vulnerability database and other sources.

For each package version the Actor:

1. **Reads your input.** A list, a manifest or a lockfile. Duplicates are checked once. A line it cannot check (no version, a git URL, an unsupported ecosystem) gets a `skipped` row with the reason.
2. **Finds known vulnerabilities** for that exact version in OSV.
3. **Merges duplicates.** One issue often has several ids (for example GHSA, PYSEC and CVE). They become one row, and all ids are kept in `osvIds` and `aliases`.
4. **Picks the severity.** The GitHub reviewed label comes first, then the highest CVSS score (v4, v3 or v2), then the ecosystem's own rating. With no score at all the row says `UNKNOWN`. When aliases are merged into one row, the highest level among them counts; on a tie the GitHub label wins.
5. **Finds the fix for your branch.** `fixedIn` is the lowest version that fixes every merged advisory on the branch of your version. For `django 3.2.0` it is a 3.2.x version, not an older 2.2.x fix.

Supported ecosystems: npm, PyPI, Maven, Go, crates.io, RubyGems, NuGet, Packagist, Pub, Hex, Hackage, CRAN, SwiftURL and GitHub Actions.

#### Good fit

- Check a project's `package-lock.json` or `requirements.txt` before a release.
- Get a list of packages to upgrade, with the target version for each.
- Add CVE, CVSS and CWE data to an SBOM or a dependency inventory.
- Run the same check on a schedule and export the rows to a spreadsheet or a ticket system.

#### Not a fit

- Proof that a package is safe. **An empty result means OSV has no known advisory for that exact version.** It does not prove the package is safe.
- Typos and unknown packages. OSV answers the same way for an unknown name and for a clean package, so both get a `no_known_vulnerabilities` row.
- Your code. The Actor checks package versions only. It does not scan source code, containers or OS packages (Debian, Alpine and similar are not supported).
- Version ranges. A range like `^4.17.15` is checked at its lowest version. For the versions you really install, paste the lockfile.

### Quick start

1. Open the **Input** tab. The form already has six packages: `npm:lodash@4.17.15`, `npm:minimist@1.2.0`, `npm:express@4.17.1`, `PyPI:requests@2.19.1`, `PyPI:pyyaml@5.3` and `npm:chalk@5.3.0`.
2. Click **Start**.
3. Open the **Overview** view in the Output tab. Check `severity`, `vulnerabilityId` and `fixedIn`.
4. Replace the list with your own packages, or paste a whole file into **package.json**, **package-lock.json** or **requirements.txt**.

Expected result: 16 rows in a few seconds. On 2026-10-13 they were 15 vulnerabilities (3 critical, 3 high, 8 medium, 1 low) in 5 packages and one `no_known_vulnerabilities` row for `chalk 5.3.0`.

### Use cases

| Buyer job | Input | Key fields |
| --- | --- | --- |
| Check a Node.js project | `packageLockJson` | `packageName`, `version`, `severity`, `fixedIn`, `dependencyType` |
| Check a Python project | `requirementsTxt` | `severity`, `cveIds`, `fixedIn`, `versionSource` |
| Only urgent issues | any input + `minSeverity: "HIGH"` | rows with `HIGH` or `CRITICAL` only |
| Enrich an SBOM or inventory | `dependencies` list | `cveIds`, `ghsaIds`, `cvssScore`, `cweIds`, `advisoryUrl` |

### Input

You can combine the list and the files in one run. At least one of `dependencies`, `packageJson`, `packageLockJson` or `requirementsTxt` is needed.

| Field | Type | Default | What it does |
| --- | --- | --- | --- |
| `dependencies` | list of strings | form example: 6 packages | One package per line: `ecosystem:name@version`, e.g. `npm:lodash@4.17.15`, `PyPI:django==3.2.0`, `Maven:org.apache.logging.log4j:log4j-core@2.14.1`, `Go:github.com/gin-gonic/gin@v1.6.0`. Package URLs (`pkg:npm/lodash@4.17.15`) work too. Through the API you can also pass objects `{"ecosystem": "npm", "name": "lodash", "version": "4.17.15"}`. Max 5,000 lines. |
| `packageJson` | text | empty | The whole `package.json` (max 1 MB). `dependencies`, `devDependencies`, `optionalDependencies` and `peerDependencies` are read. A range is checked at its lowest version. |
| `packageLockJson` | text | empty | The whole `package-lock.json`, lockfile v1, v2 or v3 (max 8 MB). Every installed package with its exact version is checked, transitive ones too. |
| `requirementsTxt` | text | empty | The whole `requirements.txt` (max 1 MB). `name==1.2.3` is checked exactly. `>=` and `~=` are checked at the lower bound. |
| `defaultEcosystem` | one of 14 ecosystems | `npm` | Used for list lines without a prefix, e.g. `lodash@4.17.15`. |
| `minSeverity` | `LOW`, `MEDIUM`, `HIGH`, `CRITICAL` | `LOW` | Hide vulnerabilities below this level. GitHub's `MODERATE` counts as `MEDIUM`. |
| `includeUnknownSeverity` | boolean | `true` | Keep vulnerabilities without any score (often PYSEC and Go) as `UNKNOWN`, whatever `minSeverity` is. |
| `includeCleanDependencies` | boolean | `true` | Add one `no_known_vulnerabilities` row for each package with no advisory, so you can see what was checked. |
| `includeDevDependencies` | boolean | `true` | Check dev dependencies from `package.json` and `package-lock.json`. |
| `maxDependencies` | integer 1–2000 | 500 | The most unique packages checked in one run. The rest are counted in `RUN_SUMMARY` as `notCheckedOverLimit`, not checked and not charged. |

The same package and version from several sources is checked once and counted in `duplicatesMerged`. If nothing in the input can be read, the run fails with `INVALID_INPUT` and the status message says why.

#### Interacting settings

- `minSeverity` + `includeUnknownSeverity`: with `minSeverity: "HIGH"` and the default `includeUnknownSeverity: true`, you get `HIGH`, `CRITICAL` and `UNKNOWN` rows. Set it to `false` to drop `UNKNOWN`.
- `minSeverity` never makes a package look clean. If all its vulnerabilities are below the level, it gets one `below_severity_filter` row with the highest hidden severity.
- `includeCleanDependencies: false` removes clean rows only. `skipped`, `error` and `below_severity_filter` rows are always written.

#### Input examples

Check a Python project and keep only urgent issues:

```json
{
  "requirementsTxt": "Django==3.2.0\nrequests>=2.19.1\npyyaml==5.3\nnumpy\n",
  "minSeverity": "HIGH",
  "includeUnknownSeverity": false
}
```

Expected result: `HIGH` and `CRITICAL` rows for Django, requests and PyYAML (`requests` is checked at 2.19.1, `versionSource: "lower_bound"`). `numpy` has no version, so it gets a `skipped` row with `MISSING_VERSION`.

Check a lockfile without dev packages:

```json
{
  "packageLockJson": "{\"lockfileVersion\": 3, \"packages\": {\"\": {}, \"node_modules/minimist\": {\"version\": \"1.2.0\"}}}",
  "includeDevDependencies": false,
  "maxDependencies": 2000
}
```

### Output

One Dataset row per vulnerability, plus one row per clean, filtered, skipped or failed package. The **Overview** view shows the main fields, **Details** shows the advisory text and links, **Inputs** shows where each package came from.

#### Row types

| `resultType` | Meaning |
| --- | --- |
| `vulnerable` | One known vulnerability of this package version. |
| `below_severity_filter` | OSV lists vulnerabilities for this version, but all are below `minSeverity`. `message` names the highest one. |
| `no_known_vulnerabilities` | OSV has no advisory for this exact version. Not a guarantee of safety. |
| `skipped` | Not checked: no version, a range or URL that cannot be resolved, an unsupported ecosystem or an include line. See `errorCode` and `message`. |
| `error` | OSV did not answer for this package (outage or the run's time limit). Run it again later. |

#### Main fields

| Field | Meaning |
| --- | --- |
| `ecosystem`, `packageName`, `version` | The package version that was checked. |
| `requestedVersionSpec`, `versionSource` | Your original version text and how the version was chosen: `exact`, `range_minimum`, `lower_bound` or `lockfile`. |
| `inputSource`, `dependencyType` | Where the package came from (`dependencies`, `packageJson`, `packageLockJson`, `requirementsTxt`) and `prod`, `dev`, `optional` or `peer`. |
| `vulnerabilityId` | The main id: GHSA first, then PYSEC, RUSTSEC, GO and others, then CVE. |
| `osvIds`, `aliases`, `cveIds`, `ghsaIds` | All ids of the same issue. Use them to match rows with other tools. |
| `severity`, `severitySource` | `CRITICAL`, `HIGH`, `MEDIUM`, `LOW` or `UNKNOWN`, and where it came from: `ghsa_database`, `cvss_v4`, `cvss_v3`, `cvss_v2` or `ecosystem_specific`. |
| `cvssScore`, `cvssVector`, `cvssVersion` | The highest CVSS base score in the group and its vector. |
| `cweIds` | Weakness types, e.g. `CWE-1321`. |
| `fixedIn` | The lowest version that fixes every merged advisory on your version's branch. `null` when no fix is published for that branch. |
| `fixedVersions`, `affectedRanges` | All fixed versions across branches and the affected intervals. |
| `summary`, `details`, `references`, `advisoryUrl` | Advisory text (up to 4,000 characters) and links. |
| `published`, `modified` | Earliest publication and latest change in the group. |
| `withdrawnAliases` | Aliases withdrawn by their database. They are listed but do not change the severity. |
| `errorCode`, `message` | Reason for `skipped` and `error` rows, explanation for clean and filtered rows. |

#### How severity and fixedIn are read

- The severity follows GitHub when GitHub has reviewed the advisory. So a row can say `MEDIUM` while `cvssScore` is 7.9: GitHub rated it lower than the raw CVSS score. This is the same label you see on GitHub.
- `fixedIn` stays on your branch. For `minimist 1.2.0` the fix is `1.2.6`, not `0.2.4` from the old 0.x branch. When merged advisories need different fixes, the highest one is used, so upgrading to `fixedIn` closes them all.
- An advisory can have no fix yet. Then `fixedIn` is `null`.

#### Output example

```json
{
  "resultType": "vulnerable",
  "ecosystem": "npm",
  "packageName": "minimist",
  "version": "1.2.0",
  "requestedVersionSpec": "1.2.0",
  "versionSource": "exact",
  "inputSource": "dependencies",
  "vulnerabilityId": "GHSA-xvch-5gv4-984h",
  "osvIds": ["GHSA-xvch-5gv4-984h"],
  "aliases": ["CVE-2021-44906"],
  "cveIds": ["CVE-2021-44906"],
  "ghsaIds": ["GHSA-xvch-5gv4-984h"],
  "summary": "Prototype Pollution in minimist",
  "severity": "CRITICAL",
  "severitySource": "ghsa_database",
  "cvssScore": 9.8,
  "cweIds": ["CWE-1321"],
  "fixedIn": "1.2.6",
  "advisoryUrl": "https://osv.dev/vulnerability/GHSA-xvch-5gv4-984h",
  "provider": "OSV.dev"
}
```

This example is trimmed. It comes from the form example run on 2026-10-13.

#### Run summary

The `RUN_SUMMARY` record in the Key-value store has `status`, a plain `message`, counts (checked, vulnerable, clean, skipped, failed, by severity), charged events and the data licence. `status` is one of:

- `SUCCEEDED`: every package was checked;
- `PARTIAL`: OSV failed during the run; packages not checked have `error` rows;
- `CAPPED`: the run stopped at your maximum cost or at the internal time limit, or more unique packages than `maxDependencies` were found;
- `ERROR`: OSV could not be reached, no package was checked;
- `INVALID_INPUT`: the input is wrong or nothing in it can be checked (the run fails and the message says why);
- `CANCELLED`: you stopped the run; rows written before that are kept.

#### Coming from another OSV scanner

Many scanners write one row per OSV record. This Actor merges records of the same issue, so you get fewer rows with the same set of ids (`osvIds` + `aliases`). Field names differ too: look for `packageName`, `vulnerabilityId`, `cveIds`, `fixedIn` and `resultType`.

### Pricing

Pay per event. Platform usage is included.

| Event | Price | When |
| --- | ---: | --- |
| Actor start | $0.002 | Once per run (per GB of memory; the default 256 MB counts once) |
| Vulnerability found | $0.0036 (Free plan), $0.0034 (Bronze), $0.0032 (Silver), $0.0030 (Gold and higher) | Each `vulnerable` row saved to the Dataset |
| Dependency checked | $0.0002 | Each unique package version that OSV answered for, clean or not |

`skipped` and `error` rows are free. Vulnerabilities hidden by `minSeverity` are free, but the package still counts as checked.

| Run (Free plan prices) | Example cost |
| --- | ---: |
| Form example: 6 packages, 15 vulnerabilities | $0.0572 |
| 100 packages, none vulnerable | $0.022 |
| 100 packages, 20 vulnerabilities | $0.094 |
| 500 packages, 50 vulnerabilities | $0.282 |
| Nothing can be checked (only `skipped` rows, run fails with `INVALID_INPUT`) | $0.002 |

Set a maximum cost per run in the run options to cap your spend. The Actor stops before a package whose rows do not fit and reports `CAPPED`.

### Limits

- Up to 2,000 unique packages per run (`maxDependencies`, default 500). A lockfile can be up to 8 MB; `package.json` and `requirements.txt` up to 1 MB each.
- A full run of 2,000 vulnerable packages took about 5.5 minutes in our test. The internal time budget is 10 minutes. Packages not reached in time get `error` rows and the run is `CAPPED`. Keep the run timeout at 900 seconds or more for large inputs.
- Only exact versions are checked. Ranges are checked at their lowest version, and lines without a version are skipped.
- The data is only as complete as OSV. A new advisory can take time to appear, and some advisories have no score or no fix yet.

### API and integrations

Start a run with the same JSON input through the Apify API (`POST /v2/acts/cliqtomedia~osv-dependency-vulnerability-scanner/runs`), then read the Dataset. Export to CSV, Excel or JSON from the Dataset, or connect the run to other tools with the usual Apify integrations.

To check a project regularly, save the input as a task and add an Apify schedule. The Actor keeps no state between runs, so each run reports all known vulnerabilities again.

#### Use with AI agents (MCP)

AI agents can call this Actor through the Apify MCP server: add `https://mcp.apify.com?tools=cliqtomedia/osv-dependency-vulnerability-scanner` to your MCP client (Claude, Cursor, VS Code and others). The MCP server needs your Apify account (OAuth sign-in or an Apify API token); OSV itself needs no key. The smallest useful input:

```json
{ "dependencies": ["npm:lodash@4.17.15", "npm:minimist@1.2.0", "npm:express@4.17.1", "PyPI:requests@2.19.1", "PyPI:pyyaml@5.3", "npm:chalk@5.3.0"] }
```

Key output fields for an agent: `resultType`, `packageName`, `version`, `severity`, `vulnerabilityId`, `cveIds` and `fixedIn`. A call with up to about 100 packages usually finishes in under 30 seconds. `skipped` rows carry an `errorCode` and a `message` that the agent can use to fix the input.

### Troubleshooting

| Symptom | Check | Action |
| --- | --- | --- |
| A package you know is vulnerable shows `no_known_vulnerabilities` | `packageName`, `ecosystem`, `version` | Check the spelling and the ecosystem. OSV treats an unknown name like a clean one. Some advisories are filed under another package name (for example Rails issues under `actionpack`). |
| `skipped` with `MISSING_VERSION` or `UNRESOLVABLE_VERSION` | `requestedVersionSpec` | Give an exact version, or paste the lockfile instead of `package.json`. |
| `skipped` with `UNSUPPORTED_ECOSYSTEM` | `ecosystem` | Use one of the 14 supported ecosystems. OS packages are not supported. |
| `error` rows or `PARTIAL` | `RUN_SUMMARY.message` | OSV did not answer. Run again later. |
| `CAPPED` | `RUN_SUMMARY.message`, `counts.notCheckedOverLimit` | Raise `maxDependencies` (up to 2,000) or your maximum cost per run, or split a very large input into two runs. |
| Run failed with `INVALID_INPUT` | the run status message | Typical causes: empty input, a file that is not valid JSON, a file over the size limit. |

### FAQ

#### Does an empty result mean my project is safe?

No. It means OSV has no known advisory for those exact versions today. New advisories appear every day, and an unknown package name is reported the same way as a clean one.

#### Why do I get fewer rows than other scanners?

Records of the same issue (for example a GHSA and a PYSEC record of one Django bug) are merged into one row. All their ids are in `osvIds` and `aliases`.

#### Why is the severity MEDIUM when the CVSS score is high?

GitHub has reviewed the advisory and set that label. The reviewed label comes first; `cvssScore` still shows the raw score.

#### How fresh is the data?

Each run asks OSV live. Each row has `modified` (last change of the advisory) and `fetchedAt` (our read time).

### Data source and licence

Data: [OSV.dev](https://osv.dev), which aggregates the GitHub Advisory Database, PyPA, RustSec, Go and other databases under their own licences (mostly [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/)). Each row links to its source in `databaseSource` and `advisoryUrl`. This Actor is independent and not affiliated with or endorsed by OSV.dev, Google or GitHub.

### Support

Use the **Issues** tab of this Actor. Add the run ID, the input mode and the row you did not expect. Do not send API tokens or private code.

# Changelog

This Actor's version history is a separate document: https://apify.com/cliqtomedia/osv-dependency-vulnerability-scanner/changelog.md

# Actor input Schema

## `dependencies` (type: `array`):

One per line: ecosystem:name@version, e.g. npm:lodash@4.17.15, PyPI:django==3.2.0, Maven:org.apache.logging.log4j:log4j-core@2.14.1, Go:github.com/gin-gonic/gin@v1.6.0. Package URLs (pkg:npm/lodash@4.17.15) work too. Without a prefix the default ecosystem is used. Via API you can also pass objects {"ecosystem": "npm", "name": "lodash", "version": "4.17.15"}. npm ranges like ^4.17.15 are checked at their lowest version.

## `packageJson` (type: `string`):

Paste the whole package.json (max 1 MB). dependencies, devDependencies, optionalDependencies and peerDependencies are read; a range such as ^4.17.15 is checked at its lowest version (versionSource = range_minimum). For exact installed versions paste package-lock.json instead.

## `packageLockJson` (type: `string`):

Paste package-lock.json (lockfile v1, v2 or v3, max 8 MB). Every installed package with its exact version is checked, transitive ones included. Linked and git/file dependencies are reported as skipped.

## `requirementsTxt` (type: `string`):

Paste requirements.txt (max 1 MB). name==1.2.3 is checked exactly; >= and ~= are checked at the lower bound (versionSource = lower_bound); lines without a version, URLs and -r includes are reported as skipped.

## `defaultEcosystem` (type: `string`):

Used for list lines without an ecosystem prefix, e.g. lodash@4.17.15.

## `minSeverity` (type: `string`):

Hide vulnerabilities below this level (GHSA MODERATE counts as MEDIUM). Hidden vulnerabilities are not charged. A dependency whose vulnerabilities are all below the level gets one below_severity_filter row, so it never looks clean.

## `includeUnknownSeverity` (type: `boolean`):

Some advisories (often PYSEC and Go) have no severity score. Keep them as severity UNKNOWN regardless of the minimum severity.

## `includeCleanDependencies` (type: `boolean`):

Add one no_known_vulnerabilities row per dependency with no matching advisory, so you can see what was checked. Every checked dependency is charged either way.

## `includeDevDependencies` (type: `boolean`):

Check devDependencies from package.json and dev packages from package-lock.json.

## `maxDependencies` (type: `integer`):

Upper limit of unique dependencies checked in one run (after duplicates are merged). The rest are counted in RUN_SUMMARY as notCheckedOverLimit and not charged.

## Actor input object example

```json
{
  "dependencies": [
    "npm:lodash@4.17.15",
    "npm:minimist@1.2.0",
    "npm:express@4.17.1",
    "PyPI:requests@2.19.1",
    "PyPI:pyyaml@5.3",
    "npm:chalk@5.3.0"
  ],
  "defaultEcosystem": "npm",
  "minSeverity": "LOW",
  "includeUnknownSeverity": true,
  "includeCleanDependencies": true,
  "includeDevDependencies": true,
  "maxDependencies": 500
}
```

# Actor output Schema

## `results` (type: `string`):

Vulnerabilities per dependency, most severe first.

## `runSummary` (type: `string`):

Status, counts per severity, charged events, OSV attribution and request statistics.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "dependencies": [
        "npm:lodash@4.17.15",
        "npm:minimist@1.2.0",
        "npm:express@4.17.1",
        "PyPI:requests@2.19.1",
        "PyPI:pyyaml@5.3",
        "npm:chalk@5.3.0"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/osv-dependency-vulnerability-scanner").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "dependencies": [
        "npm:lodash@4.17.15",
        "npm:minimist@1.2.0",
        "npm:express@4.17.1",
        "PyPI:requests@2.19.1",
        "PyPI:pyyaml@5.3",
        "npm:chalk@5.3.0",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/osv-dependency-vulnerability-scanner").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "dependencies": [
    "npm:lodash@4.17.15",
    "npm:minimist@1.2.0",
    "npm:express@4.17.1",
    "PyPI:requests@2.19.1",
    "PyPI:pyyaml@5.3",
    "npm:chalk@5.3.0"
  ]
}' |
apify call cliqtomedia/osv-dependency-vulnerability-scanner --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/osv-dependency-vulnerability-scanner"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/BR9FUOoNQiY8uvjLk/builds/TM8Jf8ihE97DgrxqM/openapi.json
