Skip to main content
ClaudeWave
Pendnt avatar
Pendnt

pendnt-plugin

Ver en GitHub
PluginsRegistry oficial0 estrellas0 forksJavaScriptMITActualizado today
ClaudeWave Trust Score
69/100
· OK
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Documented (README)
Flags
  • !No description
  • !Install pipes a remote script into a shell (curl | sh)
Last scanned: 9/11/2026
Install as a Claude Code plugin
Method: Clone
Claude Code
/plugin marketplace add Pendnt/pendnt-plugin
/plugin install pendnt-plugin
1. Inside Claude Code, add the marketplace and install the plugin with the commands above.
2. Follow any post-install configuration from the README.
3. Restart the session if commands or hooks do not show up immediately.
Casos de uso

Resumen de Plugins

# pendnt (Claude Code plugin)

Wires a [Claude Code](https://code.claude.com) session — interactive or headless (`claude -p`) — up
to a [pendnt](../app) workspace: durable human approvals, notifications, and a "run finished" ping,
without the agent needing a terminal.

"pendnt" is a placeholder product name. It's kept in exactly one place — `PRODUCT_NAME` in
[`lib/config.mjs`](lib/config.mjs) — plus the `name` fields in
[`plugin.json`](.claude-plugin/plugin.json), [`marketplace.json`](.claude-plugin/marketplace.json) and
[`.mcp.json`](.mcp.json), and the matching MCP server name registered in
[`/app/src/routes/mcp.ts`](../app/src/routes/mcp.ts). Rename all of those together and it's renamed
everywhere that matters.

This plugin ships two independent ways to answer permission prompts headlessly — pick one (or both;
`--permission-prompt-tool` takes priority when both are wired up, see §1a below):

1. **A `PermissionRequest` hook** (`hooks/permission-request.mjs`) — works with plain `claude -p`, no
   extra flags. Runs automatically before every tool-use prompt.
2. **The `permission_prompt` MCP tool**, via `--permission-prompt-tool mcp__pendnt__permission_prompt` —
   Claude Code's own dedicated mechanism for headless permission prompts (see
   [`INTEGRATIONS.md` §1a](../product/INTEGRATIONS.md)).

Plus a `Notification` hook and a `Stop` hook that both relay to `POST /v1/notify` — see
[What's included](#whats-included) below.

## Install

### Local marketplace (for trying this out before publishing anywhere)

This repo doubles as its own local marketplace — [`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json)
lists this plugin with `source: "./"`, pointing at the same directory `plugin.json` lives in. From
Claude Code:

```
/plugin marketplace add Pendnt/pendnt-plugin
/plugin install pendnt@pendnt
```

(or non-interactively: `claude plugin marketplace add Pendnt/pendnt-plugin && claude plugin install pendnt@pendnt`)

To publish for real later, split `marketplace.json` out into its own repo with `source` pointing at
this plugin's repo (see [`INTEGRATIONS.md` §1d](../product/INTEGRATIONS.md) for the marketplace
manifest shape and `github`/`git-subdir`/`npm`/`archive` source types), then
`claude plugin marketplace add <owner>/<repo>` from anywhere.

### Env vars

| Variable | Required | Default | Meaning |
|---|---|---|---|
| `PENDNT_API_KEY` | yes | — | `Authorization: Bearer <key>` for every call to the API (`aio_...`, from `POST /dev/bootstrap` locally, or your real workspace's API key in production). Without it, the `PermissionRequest`/`Notification`/`Stop` hooks all fail closed (deny / no-op) rather than erroring the session. |
| `PENDNT_URL` | no | `https://api.pendnt.dev` | Base URL of the pendnt REST API — **not** including `/mcp` or `/v1`. Point this at `http://localhost:8787` for local dev against `wrangler dev` (see [below](#running-the-hook-locally-against-wrangler-dev)). |
| `PENDNT_APPROVAL_TIMEOUT_S` | no | `600` (10 min) | Total wall-clock budget the `PermissionRequest` hook spends re-polling before it gives up and denies. Each individual poll is capped server-side at 25s (`wait_s`), so the hook loops `GET /v1/requests/:id?wait_s=25` until this budget runs out. |

Set them in your shell, or in `.claude/settings.json` under `env` — see
[settings.json docs](https://code.claude.com/docs/en/settings). `.mcp.json`'s `${PENDNT_URL:-...}` /
`${PENDNT_API_KEY}` syntax is Claude Code's own env-var expansion for `.mcp.json` values (headers
*and* URLs) — see [`INTEGRATIONS.md` §1e](../product/INTEGRATIONS.md).

## What's included

- **`.mcp.json`** — registers the `pendnt` remote MCP server (`${PENDNT_URL:-https://api.pendnt.dev}/mcp`,
  `Authorization: Bearer ${PENDNT_API_KEY}`) so all 14 tools (`request_approval`, `check_request`,
  `permission_prompt`, `notify`, `create_endpoint`, `list_endpoints`, `wait_for_event`, `schedule_wakeup`,
  `list_wakeups`, `cancel_wakeup`, `kv_get`, `kv_set`, `kv_delete`, `whoami`) are available to the model
  directly, under `mcp__pendnt__<tool>` — except `permission_prompt`, which Claude Code removes from its
  own visible tool list once named by `--permission-prompt-tool` (see below), since it's meant to be
  called by the CLI itself, not by the model.
- **`hooks/hooks.json`** — wires three hooks (shape matches `settings.json`'s `hooks` key, see
  [`INTEGRATIONS.md` §1d](../product/INTEGRATIONS.md)):
  - **`PermissionRequest`** → `hooks/permission-request.mjs`. Fires before every tool-use prompt. POSTs
    a summary of the tool call to `POST /v1/requests` (`kind: "approval"`, `wait_s: 25`,
    `timeout_s: $PENDNT_APPROVAL_TIMEOUT_S`), then re-polls `GET /v1/requests/:id?wait_s=25` until it's
    answered or the total `PENDNT_APPROVAL_TIMEOUT_S` budget elapses. Prints exactly one JSON object per
    [`INTEGRATIONS.md` §1b](../product/INTEGRATIONS.md)'s `PermissionRequest` contract:
    ```json
    { "hookSpecificOutput": { "hookEventName": "PermissionRequest", "decision": { "behavior": "allow", "updatedInput": {} } } }
    ```
    or `{"behavior": "deny", "message": "..."}`. **Fails closed** on every error path (missing API key,
    network failure, operator denies, request expires, timeout) — the only way to get `allow` is an
    explicit approval. An operator using the answer page's free-text box (always shown, even for
    `kind: "approval"` requests) is treated as approval only if the text starts with
    yes/y/allow/approve/ok — anything else denies with that text as the reason.
  - **`Notification`** → `hooks/notify.mjs`. Relays `notification_type`/`message` to `POST /v1/notify`.
    Cannot block Claude Code (per the hook's own semantics) and never tries to — always exits 0.
  - **`Stop`** → `hooks/stop.mjs`. Relays a `"run finished"` message to `POST /v1/notify` at the end of
    every turn. Never returns `{"decision":"block"}` — it only notifies, it doesn't keep the agent going.
- **`lib/`** — the three hook scripts' shared bits: `config.mjs` (env vars + the `PRODUCT_NAME`
  constant), `client.mjs` (thin `fetch` wrappers for `/v1/requests` and `/v1/notify`), `stdin.mjs` (hook
  stdin JSON parsing). No npm dependencies — plain Node 18+ (`fetch`, `AbortController`) is enough.

## The `--permission-prompt-tool` path (§1a)

Instead of (or in addition to — Claude Code prefers `--permission-prompt-tool` over hooks when both
apply) the `PermissionRequest` hook, you can point Claude Code's dedicated permission-prompt mechanism
directly at the `permission_prompt` MCP tool this plugin's `.mcp.json` registers — the one tool in this
server purpose-built for this flag (see `/app/README.md`'s `permission_prompt` section for the full
contract):

```bash
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev   # or http://localhost:8787 for local dev
export MCP_TOOL_TIMEOUT=600000              # ms — must exceed PERMISSION_PROMPT_WAIT_S (default 540s)

claude -p --permission-prompt-tool mcp__pendnt__permission_prompt "deploy to prod"
```

Three things worth knowing before you rely on this path:

- Claude Code blocks the first turn until the `pendnt` MCP server connects, capped by `MCP_TIMEOUT`
  (default 30s, env var, milliseconds) — bump it if your network is slow: `export MCP_TIMEOUT=60000`
  (from [`INTEGRATIONS.md` §1a](../product/INTEGRATIONS.md)).
- As of CLI ≥2.1.199, an `allow` from a `--permission-prompt-tool` is converted to `deny` for any MCP
  tool call flagged `_meta["anthropic/requiresUserInteraction"]` — this prompt tool can't rubber-stamp
  those regardless of what the operator answers (also from `INTEGRATIONS.md` §1a).
- **`permission_prompt` holds the MCP tool call open server-side** for up to `PERMISSION_PROMPT_WAIT_S`
  (env var on `/app`, default 540s = 9 min) waiting for the operator, unlike every other tool's ≤25s
  `wait_s`. Claude Code's own `MCP_TOOL_TIMEOUT` (its per-tool-call timeout, ms, default 30000) must be
  set higher than that or the CLI gives up first — hence `export MCP_TOOL_TIMEOUT=600000` above.

Unlike `request_approval`, `permission_prompt` *does* return Claude Code's exact `{behavior, updatedInput,
updatedPermissions, interrupt}` / `{behavior:"deny", message, interrupt}` contract natively — an `allow`
echoes the original `input` back as `updatedInput`, a `deny` (or an unanswered timeout) carries a
human-readable `message`. That's the same translation the `PermissionRequest` hook below does by hand for
its own hook-shaped contract; `permission_prompt` does it as the MCP tool result directly, which is what
`--permission-prompt-tool` actually reads.

## Headless example

```bash
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev
export MCP_TOOL_TIMEOUT=600000

claude -p --permission-prompt-tool mcp__pendnt__permission_prompt \
  "review open PRs and merge the ones that pass CI"
```

Or, with the `PermissionRequest` hook doing the work instead (no extra flag needed once the plugin is
installed):

```bash
export PENDNT_API_KEY=aio_...
export PENDNT_URL=https://api.pendnt.dev

claude -p "review open PRs and merge the ones that pass CI"
```

Either way, every tool-use prompt now creates a durable approval request instead of blocking on a
terminal that doesn't exist — check your configured channels (email/web inbox — see `/app/README.md`'s
"Channels" section for what's actually implemented today), answer from your phone, and the agent
resumes.

## Running the hook locally against `wrangler dev`

From `/app`:

```bash
cd ../app
npm install
npm run db:migrate:local
npm run dev   # http://localhost:8787
```

In another terminal, bootstrap a workspace + API key (see `/app/README.md`) and point the plugin's env
vars at it:

```bash
BOOT=$(curl -s -X POST http://localhost:8787/dev/bootstrap -d '{}')
export PENDNT_API_KEY=$(echo "$BOOT" | jq -r .api_key)
export PENDNT_URL=http://localhost:8787
```

Then either run a hook script directly, feeding it the JSON a real Claude Code hook invocation would
send on 

Lo que la gente pregunta sobre pendnt-plugin

¿Qué es Pendnt/pendnt-plugin?

+

Pendnt/pendnt-plugin es plugins para el ecosistema de Claude AI con 0 estrellas en GitHub.

¿Cómo se instala pendnt-plugin?

+

Puedes instalar pendnt-plugin clonando el repositorio (https://github.com/Pendnt/pendnt-plugin) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar Pendnt/pendnt-plugin?

+

Nuestro agente de seguridad ha analizado Pendnt/pendnt-plugin y le ha asignado un Trust Score de 69/100 (tier: OK). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene Pendnt/pendnt-plugin?

+

Pendnt/pendnt-plugin es mantenido por Pendnt. La última actividad registrada en GitHub es del 2026-09-10, con 0 issues abiertos.

¿Hay alternativas a pendnt-plugin?

+

Sí. En ClaudeWave puedes explorar plugins similares en /categories/plugins, ordenados por popularidad o actividad reciente.

Despliega pendnt-plugin en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: Pendnt/pendnt-plugin
[![Featured on ClaudeWave](https://claudewave.com/api/badge/pendnt-pendnt-plugin)](https://claudewave.com/repo/pendnt-pendnt-plugin)
<a href="https://claudewave.com/repo/pendnt-pendnt-plugin"><img src="https://claudewave.com/api/badge/pendnt-pendnt-plugin" alt="Featured on ClaudeWave: Pendnt/pendnt-plugin" width="320" height="64" /></a>

Más Plugins

Alternativas a pendnt-plugin