Skip to main content
Glama
mychaelconnolly

phishfort-mcp

██████╗ ██╗  ██╗██╗███████╗██╗  ██╗███████╗ ██████╗ ██████╗ ████████╗
██╔══██╗██║  ██║██║██╔════╝██║  ██║██╔════╝██╔═══██╗██╔══██╗╚══██╔══╝
██████╔╝███████║██║███████╗███████║█████╗  ██║   ██║██████╔╝   ██║
██╔═══╝ ██╔══██║██║╚════██║██╔══██║██╔══╝  ██║   ██║██╔══██╗   ██║
██║     ██║  ██║██║███████║██║  ██║██║     ╚██████╔╝██║  ██║   ██║
╚═╝     ╚═╝  ╚═╝╚═╝╚══════╝╚═╝  ╚═╝╚═╝      ╚═════╝ ╚═╝  ╚═╝   ╚═╝

                         ███╗   ███╗ ██████╗██████╗
                         ████╗ ████║██╔════╝██╔══██╗
                         ██╔████╔██║██║     ██████╔╝
                         ██║╚██╔╝██║██║     ██╔═══╝
                         ██║ ╚═╝ ██║╚██████╗██║
                         ╚═╝     ╚═╝ ╚═════╝╚═╝

        MCP server + paired agent skill for PhishFort workflows
        approval-gated writes | secret-safe defaults | no URL fetching

phishfort-mcp

security: reviewed & hardened tests: 130 passing python: 3.11+ license: MIT

A security-first MCP server and paired agent skill for the PhishFort Unified Client API.

Security-reviewed and hardened — 2026-07-29. Approval-gated writes · secret-safe by default · no incident-URL fetching · every security claim verified against the code.

Bring PhishFort incident review, reporting, attachments, comments, and webhook management into your MCP client, then give your agent the workflow playbook for using those tools safely.

Paired skill | Official PhishFort API docs | Security review | Local reference

Unofficial project. Not affiliated with, endorsed by, or maintained by PhishFort.

Security, reviewed in the open

This is a security tool, so the security work is the headline — not a disclaimer at the bottom. Every control is implemented in code, covered by tests, and was put through a review-and-harden pass whose results are public.

  • 2026-06-02 — v0.1.0. Local stdio MCP server and paired agent skill, security-first by default: approval-gated writes, API host pinning, redirects disabled, and no fetching of incident URLs.

  • 2026-06-05 — Posture mapped to evidence. Every security feature documented against MCP, OpenAI, and Anthropic guidance, each row tied to the exact code and test behind it.

  • 2026-06-10 — Review and hardening pass. A security review conducted by Claude Fable 5 Ultracode (initial pass), Opus 4.8 xhigh, rubber-ducked with Codex 5.5 xhigh via plugin drove a hardening pass:

    • destructive confirmation is now enforced on incident-action requests — the annotation and the approval gate agree,

    • secret-named fields are scrubbed recursively, and one-time webhook secrets are written through O_NOFOLLOW 0600 files,

    • reads retry bounded transport failures; writes retry only proven pre-send connection/pool failures; secret-named fields are redacted from errors,

    • the approval salt is random and process-stable, and the retry count is bounded,

    • the webhook URL preflight rejects legacy numeric-IP encodings,

    • the final attachment descriptor is held through upload, narrowing the validate→upload replacement window.

    The same pass reworded every security claim to match what the code enforces — the approval gate is described as in-process integrity and confirmation, not independent authorization, and the webhook URL check as a pre-submit sanity check. Tests went from 26 to 36.

  • 2026-07-30 — v0.1.1. Packages reference resources into wheels, adds current Users, Clients, Documents, and total-count reads, distinguishes safe read retries from mutation outcomes needing manual review, binds immutable attachment snapshots to approval, validates webhook timestamp freshness, requires file-backed verifier secrets, hardens one-time secret persistence beneath an owned 0700 root, and uses documented attachment MIME types. Distribution uses a versioned Git tag and GitHub Release assets; this project is not published to PyPI.

The table below is the evidence: each control maps to the code and the test that backs it.

Related MCP server: Security Copilot MCP Server

Standards-Backed Security Posture

This server was designed against the Official Model Context Protocol security guidance, Anthropic connector guidance, OpenAI MCP guidance, OpenAI agent safety guidance, and PhishFort's official API docs. The table below lists only security features that are implemented in code, with local evidence.

Local evidence:

Security feature

What it prevents

Confirmed implementation

Local stdio transport only

Avoids exposing a public HTTP MCP surface in v1

server.main() rejects non-stdio transport

Two-step approval gate for writes

Forces an explicit plan→confirm step with a tamper-evident digest before any mutation. This is in-process integrity/confirmation, not independent human authorization — the host UI provides the human prompt via the destructive hints below

Write tools require approval_id, approval_phrase, expires_at, request_digest; _validate_approval() recomputes the digest from the actual params

Tamper-resistant approval digest

Blocks changing params after approval planning

approval.py canonicalizes params and verifies request_digest; covered by test_approval_rejects_tampered_params

Destructive confirmation

Adds explicit friction for delete/rotate operations

Destructive specs require destructive_confirmed=true; covered by test_destructive_operation_requires_confirmed

Read/write MCP annotations

Gives MCP hosts correct safety hints

_read_annotations() and _write_annotations() set read-only/destructive/idempotent hints

API keys never passed as tool args

Reduces credential leakage through prompts/tool logs

Settings reads PHISHFORT_API_KEY or PHISHFORT_API_KEY_FILE; tool signatures do not accept API keys

Default API host pinning

Avoids accidental credential use against arbitrary hosts

Settings.validate_base_url() requires https://capi.phishfort.com/v1 unless explicit override is enabled

Redirects disabled

Avoids following API responses to unexpected locations

httpx.AsyncClient(..., follow_redirects=False)

Error redaction

Prevents API keys, secret-named fields, and echoed secret values from leaking through raised API errors

PhishFortClient._error() applies two-pass redact() masking; covered by API-key, sensitive-key, and echoed-value tests

Untrusted data warnings

Reminds agents not to treat remote content as instructions

response_envelope() adds untrusted_data_warning to PhishFort API outputs

No generic URL fetching

Avoids browsing hostile or sensitive URLs returned by the API

Server exposes PhishFort API tools only; no tool fetches incident or document URLs

Attachment file restrictions

Reduces local file exfiltration and approval-time file swaps

snapshot_attachments() reads bytes during planning and execution; attachment_manifest() binds planned path, size, SHA-256, and MIME; execution must match that manifest, then uploads the exact execution snapshot using the documented MIME map, including application/vnd.ms-outlook for .msg

Webhook URL preflight (defense-in-depth)

Rejects localhost/private/reserved targets — including legacy decimal/octal/hex IP forms — before a webhook is registered. The server never fetches the URL itself (PhishFort delivers webhooks), so backend egress controls remain the real boundary

validate_webhook_url() and is_private_host(); covered by webhook URL tests

Webhook secret containment

Keeps one-time secrets out of tool output and avoids post-mutation sink setup

_handle_secret_response() strips sensitive fields and echoes; prepare_secret_write() opens a bound sink beneath an owned 0700 root before mutation and PreparedSecretWrite.persist() installs the 0600 secret or reports a verified recovery path

Webhook signature verification

Enables receiver-side HMAC verification and rejects stale timestamps

verify_signature() signs the exact raw body, requires a numeric timestamp within ±300 seconds, and uses hmac.compare_digest(); receivers reject duplicate attempt delivery IDs and make logical-event processing idempotent

Limit-aware behavior

Avoids known API limit failures where possible

phishfort_get_limits, reference_limits, incident limit clamp, webhook 5-subscription preflight; covered by tests/test_limits.py

Bounded retry behavior

Avoids unsafe retry storms and duplicate writes

Reads may retry 429/5xx with capped backoff and Retry-After; mutations retry only proven pre-send connection/pool failures and never status responses or ambiguous read/protocol failures; covered by read/write retry tests

About

phishfort-mcp is a public, unofficial MCP integration for teams and operators who want PhishFort incident workflows available inside agentic tools without giving up basic operational control. The MCP server provides live API access; the paired skill gives compatible agents the workflow memory needed to use that access consistently.

It is built for local-first use, explicit approvals, and careful handling of phishing data. The goal is not to make incident response fully autonomous. The goal is to make the repetitive parts faster while keeping sensitive actions, secrets, and untrusted content under control.

Why This Exists

PhishFort has a focused REST API for phishing incident workflows. MCP makes that API usable from agentic tools, and the paired skill teaches those agents the operating procedure: what to read first, how to plan writes, what data is untrusted, and when to stop for explicit approval.

That pairing matters because security workflows are not just API calls. Incident data can contain hostile text, URLs should not be fetched casually, and takedown or webhook operations should not happen from a loose prompt.

phishfort-mcp ships two pieces that work together:

  • a local stdio MCP server for live PhishFort API access

  • an agent-agnostic skill that turns raw tool access into repeatable, safer workflows

  • approval-gated writes for reporting, actions, evidence, comments, and webhooks

  • secret-safe handling for API keys and one-time webhook secrets

  • untrusted-data guardrails for incident text, URLs, and webhook payloads

What You Can Do

Workflow

Tools

Give agents the PhishFort operating playbook

skills/phishfort-mcp/SKILL.md

Check documented API limits

phishfort_get_limits

Check identity and client scope

phishfort_whoami

List users and clients in authorized scope

phishfort_list_users, phishfort_list_clients

Search and inspect incidents

phishfort_list_incidents, phishfort_get_incident, phishfort_find_incident_by_subject

List document metadata and obtain short-lived signed URLs

phishfort_list_documents, phishfort_get_document, phishfort_get_document_signed_url

Report URLs, domains, emails, phones, and IPv4 subjects

phishfort_report_incident

Request takedown, monitoring, or safe review

phishfort_request_incident_action

Add evidence and analyst context

phishfort_add_attachments, phishfort_add_comment

Manage webhook subscriptions

phishfort_list_webhooks, phishfort_create_webhook, phishfort_update_webhook, phishfort_delete_webhook, phishfort_test_webhook, phishfort_rotate_webhook_secret

Verify incoming webhook deliveries

phishfort_verify_webhook_signature

The server also exposes MCP resources for the distilled API reference, source manifest, and security review:

  • phishfort://reference/summary

  • phishfort://reference/limits

  • phishfort://reference/source-manifest

  • phishfort://reference/security-review

Paired Skill

This repo ships an agent-agnostic skill in skills/phishfort-mcp/SKILL.md. Use it with any skill-capable MCP host to teach the agent the safe operating pattern for this server: read before write, treat all remote API data as untrusted, never fetch returned URLs by default, and use phishfort_plan_change before mutating calls.

The skill keeps detailed workflows in references/workflows.md, exact tool parameters in references/tool-map.md, and points agents to phishfort_get_limits before workflows where limits change the right next step.

The GitHub Release wheel installs the MCP server and its embedded reference resources. The paired skill is a repository asset; download it from the matching Git tag when your host supports skills. This project is not published to PyPI.

Safety Built In

The standards-backed table above is the detailed proof. Operationally, the server stays local-first, keeps credentials out of tool arguments, treats PhishFort data as untrusted, gates writes through phishfort_plan_change, stores webhook secrets outside tool output, and constrains attachments, webhook URLs, limits, and retries.

See MCP security review for the reasoning behind these choices.

Quick Start

uvx --from git+https://github.com/mychaelconnolly/phishfort-mcp.git@v0.1.1 phishfort-mcp --help

For source development or the paired skill:

git clone --branch v0.1.1 --depth 1 https://github.com/mychaelconnolly/phishfort-mcp.git
cd phishfort-mcp
uv sync --frozen --extra dev
uv run phishfort-mcp --help

Create a local key file:

mkdir -p ~/.config/phishfort-mcp
chmod 700 ~/.config/phishfort-mcp
$EDITOR ~/.config/phishfort-mcp/phishfort-api-key.txt
chmod 600 ~/.config/phishfort-mcp/phishfort-api-key.txt

Codex MCP Registration

codex mcp add phishfort \
  --env PHISHFORT_API_KEY_FILE=$HOME/.config/phishfort-mcp/phishfort-api-key.txt \
  -- uvx --from git+https://github.com/mychaelconnolly/phishfort-mcp.git@v0.1.1 phishfort-mcp

Then verify:

codex mcp list

A fresh Codex session may be required before new MCP tools are discoverable.

Configuration

Variable

Default

Notes

PHISHFORT_API_BASE_URL

https://capi.phishfort.com/v1

Pinned to official API host unless override is enabled.

PHISHFORT_API_KEY

unset

Useful for short-lived local shells.

PHISHFORT_API_KEY_FILE

unset

Preferred for MCP registration.

PHISHFORT_SECRET_DIR

~/.config/phishfort-mcp/secrets

Effective-user-owned 0700 root; webhook secrets are written with 0600 permissions.

PHISHFORT_ATTACHMENT_ROOTS

.

Comma-separated roots allowed for attachment uploads.

PHISHFORT_TIMEOUT_SECONDS

30

HTTP request timeout.

PHISHFORT_MAX_RETRIES

3

Caps read-side 429/5xx retries and mutation retries for proven pre-send connection/pool failures at 5. Mutation status responses and ambiguous read/protocol failures are not retried; read-side Retry-After is capped locally.

PHISHFORT_ALLOW_CUSTOM_BASE_URL

false

Test-only escape hatch for non-production API hosts.

PHISHFORT_ALLOW_UNSAFE_WEBHOOK_URL

false

Test-only escape hatch for localhost/private webhook targets.

phishfort_verify_webhook_signature accepts secret_file only. The file must remain beneath PHISHFORT_SECRET_DIR; the root and any subdirectories must be owned by the effective user with mode 0700. Symlinked components, root rebinding, and platforms without required descriptor-relative no-follow primitives fail closed.

Approval-Gated Writes

Read tools can be called directly. Writes are two-step on purpose:

  1. Call phishfort_plan_change with operation and exact params.

  2. Review warnings, risk, request_digest, and approval_phrase.

  3. Call the intended mutating tool with the same params plus approval_id, approval_phrase, expires_at, and request_digest.

If anything changes, rerun phishfort_plan_change.

This gate is in-process integrity and confirmation: it proves the executed params match the planned params (tamper-evident digest), enforces expiry, and requires destructive_confirmed=true for destructive operations. It is not an independent authorization boundary — the same agent can plan and confirm. The human-in-the-loop checkpoint is the MCP host's own tool-confirmation UI, driven by the destructive annotations the server sets.

Mutating API calls are not automatically replayed after HTTP status responses or ambiguous read/protocol failures. PhishFort documents no idempotency key for incident reports. A report 409 means duplicate. Any 2xx with a nonempty incident id confirms creation, even when dashboard url is null or absent; a 2xx without a nonempty id stops for manual review with no automatic retry.

Verification

uv run ruff check .
uv run pytest

Optional live smoke when a valid key exists:

  • phishfort_whoami

  • phishfort_list_incidents(limit=1)

Do not run live mutating smoke unless you intend to change PhishFort state.

Document signed URLs are short-lived download grants. Treat them as sensitive, untrusted API output: do not persist or share them, and do not fetch them automatically.

API Reference

Official PhishFort docs:

PhishFort's docs MCP serves documentation, not account API operations. This project remains the local account-workflow MCP server.

This repo includes a distilled reference in docs/reference/phishfort-unified-client-api.md and a source URL manifest in docs/reference/source-manifest.json. Fetched raw PhishFort docs are intentionally not tracked.

License

MIT. See LICENSE.

Install Server
A
license - permissive license
B
quality
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for Pentest-Tools.com: run scans, manage findings and reports via your preffered LLM.

  • Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.

  • A paid remote MCP for ClawManager, built to return verdicts, receipts, usage logs, and audit-ready J

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/mychaelconnolly/phishfort-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server