mcp

package
v0.167.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 11, 2026 License: AGPL-3.0 Imports: 19 Imported by: 0

README

PromptZero MCP Server

promptzero --mcp launches a Model Context Protocol (MCP) server over stdio that exposes the Flipper Zero (and optional ESP32 Marauder) tool surface to any MCP client — Claude Desktop, Claude Code, a custom LLM agent, or the standalone mcptest harness.

The server wraps every callable primitive in internal/flipper, the composite pentest workflows in internal/workflows, the structural internal/fileformat helpers, the Phase-5 internal/validator pre-flight, and (when the --wifi flag is active) the Marauder command surface.

Starting the server

# Over USB-serial to a local Flipper
promptzero --mcp

# With the Marauder devboard attached
promptzero --mcp --wifi

# Against a specific Flipper URL
promptzero --mcp --flipper serial:///dev/ttyACM0

The process holds stdin/stdout open for the MCP client and logs a single banner to stderr reminding the operator that, unlike the REPL, every tool call executes immediately — MCP has no shell to prompt on.

Adding to Claude Desktop

Edit your claude_desktop_config.json:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
  • Linux: ~/.config/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "promptzero": {
      "command": "/usr/local/bin/promptzero",
      "args": ["--mcp"]
    }
  }
}

For a Marauder-equipped setup, add "--wifi" to args. Restart Claude Desktop and the promptzero server appears in the MCP picker.

Adding to Claude Code

Use the built-in MCP management:

claude mcp add promptzero /usr/local/bin/promptzero --mcp

The same tool list and persona prompts then surface in Claude Code's /mcp menu.

What the server advertises

Each tool carries MCP annotations derived from PromptZero's risk classifier (internal/risk):

Annotation Meaning
readOnlyHint True for risk.Low tools (e.g. device_info, storage_list).
destructiveHint True for risk.High and risk.Critical (subghz_transmit, js_run).
openWorldHint True for anything beyond pure reads — the tool touches external state.
title <tool_name> (<level>) so the picker renders the risk at a glance.

Clients can gate destructive tools client-side (prompt the user, require a typed confirmation) using these hints. The server itself does not prompt — see the caveat below.

Tool categories

  • Flipper primitives. Sub-GHz, infrared, NFC, RFID, iButton, GPIO, BadUSB, loader/FAP shortcuts, storage, input, log streaming, JS runtime, flipper_raw_cli, etc.
  • File-format. fileformat_read / fileformat_edit / fileformat_diff for structural reads and edits of .sub, .nfc, .ir, .rfid.
  • Pre-flight validators. badusb_validate scans DuckyScript for destructive patterns without executing.
  • Workflows. Pure-Flipper composites: workflow_hw_recon_blackbox_device, workflow_garage_door_triage, workflow_phys_pentest_badge_walk. LLM-driven workflows (workflow_badusb_target_profile etc.) are not surfaced in MCP mode — they require the full agent context.
  • Marauder tools (only with --wifi). Scans, deauth, beacon spam, PMKID capture, evil portal, BLE spam, MAC manipulation, etc.

Persona prompts

The six built-in personas (default, rf-recon, badge-cloner, hw-recon, physical-pentest, read-only) are registered as MCP prompts under the persona_<name> naming scheme. Selecting one in an MCP client inserts the persona's system prompt as a user message, letting the downstream model adopt the operator mode without PromptZero having to stream the switch itself.

Limitations and caveats

  • All tool calls auto-execute. MCP servers do not have an interactive confirmation channel. Destructive tools execute as soon as the client issues tools/call. The risk annotations are the primary gating surface; clients that do not honour them should not be pointed at a live device.
  • BadUSB writes are not auto-approved in the REPL — they are here. If you want the REPL's confirmation gate for BadUSB drops, drive the Flipper through the REPL (promptzero) instead of MCP.
  • Audit logging is disabled in MCP mode. MCP doesn't carry the CLI's audit sink, so audit_query / audit_export / audit_stats are not advertised.
  • Generator + vision tools are not in MCP mode. Tools that need the Anthropic SDK client (generate_*, analyze_image) require the agent context and are not registered here.
  • JS runtime is fork-gated. js_run only works on Xtreme / Momentum / RogueMaster firmware. Stock / Unleashed / RogueMaster builds return a friendly-fork error.

Testing

go test -race -count=1 ./internal/mcp/...

The integration test wires the server to an in-process mcp-go client via io.Pipe and exercises initializetools/listtools/callprompts/listprompts/get, backed by the shared internal/testmocks Flipper and Marauder fakes.

Documentation

Overview

Package mcp exposes PromptZero's tool surface over the Model Context Protocol (stdio transport). Started by `promptzero --mcp` and intended to be plugged into MCP clients like Claude Desktop or Claude Code as a local tool server.

Every registered tool carries risk metadata derived from internal/risk.Classify, surfaced to the client as MCP annotations (readOnlyHint, destructiveHint, openWorldHint). Operators can use those hints to gate destructive calls in their MCP client.

Tools at risk.High or risk.Critical are refused by default. Set the following environment variables to opt in:

  • PROMPTZERO_MCP_ALLOW_HIGH=1 — permits risk.High tool calls.
  • PROMPTZERO_MCP_ALLOW_CRITICAL=1 — permits risk.Critical tool calls (implies High is also permitted).

Denied calls are still recorded in the audit log (if wired) so the operator has a full record of attempted MCP tool invocations.

MCP resources

Built-in wordlists are exposed as static MCP resources so clients can introspect their contents before invoking hash_crack_dictionary or http_enum_common:

  • promptzero://wordlists/common.txt — ~500-entry HTTP common-paths list
  • promptzero://wordlists/passwords.txt — ~100-entry common-password list

_confirmed ↔ Risk-tier equivalence (for MCP client integrations)

Some reference MCPs (e.g. pm3-mcp) require a `{"_confirmed": true}` arg on every destructive tool call. PromptZero uses a different mechanism: the Spec.Risk field and the corresponding MCP tool annotations. The equivalence table is:

pm3-mcp tier    →  PromptZero Risk      →  MCP annotations
read-only       →  Low                  →  readOnlyHint:true,   destructiveHint:false
allowed-write   →  Medium               →  readOnlyHint:false,  destructiveHint:false
approval-write  →  High / Critical      →  readOnlyHint:false,  destructiveHint:true

MCP clients (Claude Desktop, Claude Code) can gate Critical-tier calls using their built-in auto-approve settings keyed on destructiveHint:true. No `_confirmed` arg is added to PromptZero schemas — enforcement is at the client layer via annotations, not schema validation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the stdio MCP server wrapping a connected Flipper and optional Marauder sidecar.

func NewServer

func NewServer(f *flipper.Flipper, m *marauder.Marauder) *Server

NewServer builds the MCP server and registers every tool compatible with the connected devices. The Marauder parameter may be nil; when absent, WiFi tools are not advertised.

func (*Server) MCPServer added in v0.2.0

func (s *Server) MCPServer() *mcpserver.MCPServer

MCPServer returns the underlying mcp-go server. Exposed so tests can attach alternate transports (e.g. in-process pipes) without going through the stdio wiring.

func (*Server) PromptNames added in v0.2.0

func (s *Server) PromptNames() []string

PromptNames returns the list of registered prompt names.

func (*Server) ResourceNames added in v0.5.0

func (s *Server) ResourceNames() []string

ResourceNames returns the list of registered MCP resource URIs.

func (*Server) ServeStdio

func (s *Server) ServeStdio() error

ServeStdio starts the server on the process's stdin/stdout pair. Blocks until the client disconnects or the process is signalled.

func (*Server) SetAuditLog added in v0.17.0

func (s *Server) SetAuditLog(l *audit.Log)

SetAuditLog wires an audit log so every MCP tool call (including consent-denied ones) is recorded. Call before ServeStdio.

func (*Server) SetBruce added in v0.17.0

func (s *Server) SetBruce(b *bruce.Client)

SetBruce wires an optional Bruce devboard so bruce_* handlers do not short-circuit with "not connected" in MCP mode.

func (*Server) SetBusPirate added in v0.17.0

func (s *Server) SetBusPirate(bp *buspirate.Client)

SetBusPirate wires an optional Bus Pirate 5 so buspirate_* handlers do not short-circuit with "not connected" in MCP mode.

func (*Server) SetFaultier added in v0.17.0

func (s *Server) SetFaultier(f *faultier.Client)

SetFaultier wires an optional Faultier glitcher so faultier_* handlers do not short-circuit with "not connected" in MCP mode.

func (*Server) ToolNames added in v0.2.0

func (s *Server) ToolNames() []string

ToolNames returns the list of registered tool names in registration order.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL