mcpcap v2.14.7 returns isError:false for all application-level failures — file-not-found, empty file, corrupt PCAP, wrong extension all look like success
Repro environment
uvx mcpcap→ v2.14.7 (FastMCP 2.x, pypi)- Protocol: MCP JSON-RPC over stdio
The bug
mcpcap has 9 tools (analyzednspackets, analyzedhcppackets, analyzeicmppackets, analyzecapinfos, analyzetcpconnections, analyzetcpanomalies, analyzetcpretransmissions, analyzetrafficflow, analyzesippackets). All take `pcapfile` (string, path or URL).
Framework-level errors correctly set `isError: true`:
- Wrong type (integer instead of string for pcap_file):
isError: true— Pydantic catches it - Missing required argument (omit serverip for analyzetraffic_flow):
isError: true - Unknown tool name:
isError: true
Application-level errors silently return `isError: false`:
| Input | Error message in content | isError |
|---|---|---|
Non-existent path /tmp/does_not_exist.pcap | "PCAP file not found: /tmp/does_not_exist.pcap" | false |
| Empty 0-byte file | "Error reading PCAP file: No data could be read!" | false |
| Non-PCAP text file (.txt) | "File is not a supported PCAP file (.pcap/.pcapng/.cap)" | false |
| Random 64-byte garbage with .pcap extension | "Error reading PCAP file: Not a supported capture file" | false |
| Symlink to /etc/passwd renamed to .pcap | "Error reading PCAP file: Not a supported capture file" | false |
Empty string "" | "PCAP file not found: " | false |
Root cause
FastMCP translates Python exceptions into isError: true automatically. But mcpcap's tool functions catch all runtime errors internally and return error dicts as normal results (e.g. {"error": "PCAP file not found: ..."}) rather than raising exceptions. This means FastMCP never sees a failure and returns the error as a successful result.
Impact on agents
An agent that checks isError to branch on success/failure (the MCP-standard pattern) will treat every one of these failures as a successful tool call. It will then try to interpret the error dict as PCAP analysis results, potentially hallucinating conclusions from error messages, or retrying in an infinite loop without understanding it failed.
Positive note
The extension-check on non-.pcap files works correctly (rejects /tmp/not_a_pcap.txt), and the symlink-to-/etc/passwd was correctly rejected (scapy's parser failed it, not a security bypass). The error messages themselves are clear and descriptive — the only problem is the signaling channel.