# What Are Unpinned Auto‑exec Runtimes in Claude Plugins?

> Discover unpinned auto-exec runtimes in Claude plugins. Learn how floating package specifications enable runtime code changes without new plugin versions. Understand MCP servers and their dynamic execution.

- Repository: [Anthropic/claude-plugins-community](https://github.com/anthropics/claude-plugins-community)
- Tags: deep-dive
- Published: 2026-08-31

---

**Unpinned auto‑exec runtimes are MCP servers declared in a Claude plugin manifest that execute code from floating package specifications—such as `@latest` or version ranges—allowing runtime code to change without a new plugin version.**

Every Claude plugin in the `anthropics/claude-plugins-community` repository declares external executable services through [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) or [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json) files. When these services use unpinned auto‑exec runtimes, the code that runs at session start is resolved dynamically from package registries, creating a potential security gap between the plugin's pinned source code and its actual runtime behavior.

## How Unpinned Auto‑exec Runtimes Are Detected

The `scan-plugins` GitHub Action identifies these conditions through a dedicated classifier script.

### The Pin‑Check Classifier

In [`lib/pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/lib/pin-check.sh) (lines 8‑14), the deterministic launcher‑pin classifier scans MCP server declarations for package‑manager runners invoked with floating specifications:

```bash

# From .github/actions/scan-plugins/lib/pin-check.sh

# Detects: npx, bunx, uvx, pipx with @latest, ^, >=, or bare names

```

The script flags launchers like `npx my-tool@latest`, `bunx my-tool@^1.2`, or `uvx my-tool` where the package specification is not locked to an exact version.

### Detection Outputs

When the scan completes, it adds two fields to the JSON output as documented in the action's README (lines 28‑33):

| Field | Type | Meaning |
|-------|------|---------|
| `unpinned_autoexec_runtime` | boolean | Whether any floating spec was detected |
| `unpinned_autoexec_specs` | array | List of offending package specifications |

These values appear in the step summary table and in the `scanned`/`pin-scanned` action outputs.

## What Triggers an Unpinned Auto‑exec Runtime

A runtime becomes "unpinned" when the launcher command uses any of these floating specifications:

- **Dist‑tags**: `my-tool@latest`
- **Version ranges**: `my-tool@^1.2.0`, `my-tool@>=2.0.0`
- **Bare names**: `my-tool` (implicitly latest)

Conversely, an **exact version** like `my-tool@1.2.3` is considered pinned and does not trigger the warning.

### Example: Floating Spec (Unpinned)

```json
{
  "myServer": {
    "command": "npx",
    "args": ["my-tool@latest"]
  }
}

```

Scan result:

```json
{
  "name": "my-plugin",
  "unpinned_autoexec_runtime": true,
  "unpinned_autoexec_specs": ["my-tool@latest"]
}

```

### Example: Exact Version (Pinned)

```json
{
  "myServer": {
    "command": "npx",
    "args": ["my-tool@1.2.3"]
  }
}

```

Scan result:

```json
{
  "name": "my-plugin",
  "unpinned_autoexec_runtime": false,
  "unpinned_autoexec_specs": []
}

```

## Security Implications of Unpinned Auto‑exec Runtimes

The core risk stems from a **version mismatch**: the plugin's marketplace entry pins the source code to a specific `source.sha`, but a floating package specification can fetch different code each time the plugin launches. According to the `anthropics/claude-plugins-community` source code, this creates a supply‑chain exposure where untrusted code could be introduced at runtime without any change to the plugin itself.

The detection specifically targets **auto‑executing** code—MCP servers declared in the plugin manifest that run automatically at session start. Package invocations inside `skills/`, `commands/`, or `agents/` markdown files are **out of scope** because they are agent‑invoked and permission‑gated, as noted in the scan‑plugins README (lines 39‑42).

## Controlling Unpinned Auto‑exec Runtime Detection

### Default Behavior: Warning Only

By default, the `scan-plugins` action reports unpinned auto‑exec runtimes as warnings without failing the workflow.

### Enforcing Hard Failures

Set the workflow input `fail-on-unpinned-autoexec: true` to convert any detection into a hard failure:

```yaml
- uses: ./.github/actions/scan-plugins
  with:
    fail-on-unpinned-autoexec: true

```

### Waiving Specific Packages

Repository maintainers can suppress detections per‑package using a local waiver file named `launch-shape-waivers`. Each line follows the format:

```

<plugin-name> <package-prefix>/

```

For example, with this waiver:

```

my-plugin my-tool/

```

The floating spec `my-tool@latest` will be considered waived, and `unpinned_autoexec_runtime` will report `false`.

## Key Source Files

| File | Role |
|------|------|
| [`.github/actions/scan-plugins/lib/pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/lib/pin-check.sh) | Core classifier identifying floating specs |
| [`.github/actions/scan-plugins/README.md`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/README.md) | Detection documentation and output schema |
| [`.github/actions/scan-plugins/policy/schema.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.github/actions/scan-plugins/policy/schema.json) | JSON schema defining `unpinned_autoexec_*` properties |
| Plugin manifests ([`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json), [`plugin.json`](https://github.com/anthropics/claude-plugins-community/blob/main/plugin.json)) | Declarations scanned for floating specifications |

## Summary

- **Unpinned auto‑exec runtimes** occur when Claude plugin MCP servers use floating package specifications that resolve to different code at runtime.
- The `scan-plugins` action detects these via [`lib/pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/lib/pin-check.sh), outputting `unpinned_autoexec_runtime` and `unpinned_autoexec_specs` fields.
- Floating specs include `@latest`, semver ranges (`^`, `>=`), and bare package names; exact versions are pinned and safe.
- By default, detection produces warnings; enable `fail-on-unpinned-autoexec: true` for enforcement.
- Use `launch-shape-waivers` to exclude specific packages from detection when necessary.

## Frequently Asked Questions

### What package managers trigger unpinned auto‑exec runtime detection?

The [`pin-check.sh`](https://github.com/anthropics/claude-plugins-community/blob/main/pin-check.sh) classifier monitors `npx`, `bunx`, `uvx`, and `pipx` launchers. Any of these invoked with a floating specification will flag the runtime as unpinned.

### Why are skills and commands excluded from this check?

Package invocations inside `skills/`, `commands/`, or `agents/` markdown are **agent‑invoked and permission‑gated**, meaning they require explicit user action rather than auto‑executing at session start. Only manifest‑declared MCP servers run automatically.

### Can I use `@latest` in my plugin without failing the scan?

Yes, by adding a waiver to your repository's `launch-shape-waivers` file. Format the entry as `plugin-name package-prefix/` to suppress detection for that specific package while keeping other enforcement active.

### Does pinned source code protect against unpinned auto‑exec runtimes?

No. The `source.sha` in a plugin's marketplace entry pins the **plugin's own code**, not its external dependencies. A floating spec in [`.mcp.json`](https://github.com/anthropics/claude-plugins-community/blob/main/.mcp.json) can still fetch different runtime code on each launch, creating a reproducibility and security gap.