---
name: pensec
description: Manage Pensec organizations and websites through its MCP server or schema-driven API. Use when connecting an agent to Pensec, creating security/remediation tasks, requesting assessments, recording external test runs, reading findings or statistics, configuring email notifications, or requesting retests.
---

# Pensec agent

Connect to `https://mcp.pensec.app/mcp` with browser OAuth, or use an organization/website API key through your host's secure credential mechanism. REST base: `https://api.pensec.app/v1`. Load the live contract at `https://api.pensec.app/openapi.json` when constructing REST requests; use MCP tool discovery for tool inputs.

MCP tool names are `pensec_` plus the operation ID. Arguments are **flat**: path parameters and body fields go in the same object, not under a `body` property. For example, `pensec_createTask` takes `{ "websiteId": "<website UUID>", "title": "Investigate tenant permissions", "priority": "high" }`. Discover the live tool schema before supplying optional fields. Paginated tools take `limit` and `cursor`; pass the returned `nextCursor` as the next `cursor`.

## Connect and select context

1. Prefer the host's remote MCP OAuth flow. Let the user sign in and choose account, organization, or website access. Local stdio tooling also supports `pensec_login` followed by `pensec_completeLogin`; credentials are stored in the OS keychain using Seal.
2. If a key is provided, keep it in the host secret manager. Do not put it in source, a URL, or a conversation. Authenticate with `Authorization: Bearer`.
3. Call `pensec_getIdentity`, then `pensec_listOrganizations`. Websites live directly under an organization; there is no project layer.
4. Select the intended organization and call `pensec_listWebsites`. Resolve ambiguity before writing to another website. Follow pagination until `nextCursor` is null when a complete list is needed.

## Create tasks and request assessments

- Use `pensec_createTask` with the selected website ID. Include a clear title, actionable description and priority. Link report findings with report ID, immutable version and finding ID when relevant.
- To select the latest finding, use `pensec_listReports`, `pensec_getReport` for the latest-version pointer, then `pensec_getReportVersion` and `pensec_getFinding` with that exact numeric version. Do not infer latest from an unspecified listing order.
- Read a task before updating it and supply its `expectedVersion`. On a conflict, reread rather than overwriting concurrent work.
- Use `pensec_deleteTask` to remove a task from active views when requested. Its comments and audit history remain retained; deleting a task does not delete or close linked report findings.
- Use `pensec_requestAssessment` for an expert-led investigation. A request waits for scope agreement; it does not launch testing.
- For ownership, create a challenge and use the existing website verification skill/workflow to publish the DNS TXT or well-known file. Provider credentials stay with the agent/provider. Verify the result through Pensec.
- Read ownership, scope and actual run status before describing any test as executed. Current managed automated runs are mocked; expert review on planned recurring coverage is once weekly on either cadence.

## Add test runs to the dashboard

Use `pensec_requestTestRun` for a managed run. Reuse its idempotency key when recovering an ambiguous network result.

For your own tools, use `pensec_importTestRun`. Record:
- Stable external run ID, tool and tool version.
- Website/environment and tested deployment identity.
- Actual start/finish timestamps and execution outcome.
- Reached coverage, explicit gaps, findings and supporting evidence.

Upload redacted plain-text evidence with `pensec_uploadEvidence` and reference only returned evidence IDs belonging to the same website. Imports are immutable and idempotent by website/tool/external ID; corrections need a new external ID. Imported findings remain candidates and are labeled externally reported, not expert-reviewed. Completing a task or observing a code change does not establish deployed-fix closure.

## Read and notify

- Use website or organization statistics according to the credential scope. Separate mocked runs, external results, preliminary observations and actually reviewed published findings.
- Read reports using a pinned version. Evidence, review and deployed-fix retest status are distinct.
- Configure email/webhook subscriptions only for the intended organization and recipients. Use the saved subscription's test operation and inspect delivery history. A queued notification is not a sent email.
- For completion emails, inspect `pensec_listSubscriptions`, create a website-filtered `pensec_createSubscription` with `channel: "email"`, the configured destination and `events: ["run.completed"]`, then `pensec_testSubscription` and `pensec_listDeliveries`. External imports emit `run.imported`, which is a separate event. Read complete statistics with `pensec_getWebsiteStats` or `pensec_getOrganizationStats` and preserve the returned definitions.
- With a website-scoped grant, use `pensec_listWebsiteSubscriptions`, `pensec_createWebsiteSubscription` and `pensec_listWebsiteDeliveries`; do not request organization-wide notification data.
- General mutations accept a `requestKey` (or REST `Idempotency-Key` header). Reuse it with exactly the same request; do not replay a mutation under a fresh key after an ambiguous timeout without first inspecting the resource.

## Finish with an inspectable result

Return the organization/website, created resource IDs and dashboard links, actual persisted statuses, and any blocked step. Never include API keys, access/refresh tokens, auth headers, or unredacted evidence. Use only granted roles; a tool cannot grant itself reviewer or publisher authority.
