Atlas / MCP servers / plumpslabs / fennec

fennecBLOCK

mcp/plumpslabs/fennec

AI-native developer observability MCP (Model Context Protocol) server that gives AI agents full-stack visibility into your development environment — browser, terminal, and processes — all in one unified interface.

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
19 17r · 1w · 1d
Transport
sse · stdio
License
MIT
Stars
1
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Fennec 🦊

Ears everywhere in your stack.

AI-native developer observability MCP — browser, terminal, and processes, all in one.

What is Fennec?

Fennec is an MCP (Model Context Protocol) server that bridges the gap between AI agents and your development environment. Instead of you copy-pasting errors between terminal, browser, and AI, Fennec gives your AI agent direct access to all three simultaneously — and lets it run and supervise your apps, not just observe them.

The Problem It Solves

When a developer asks an AI agent "why is my login broken?", the agent is essentially blind:

What agent sees:          What developer sees:
─────────────────         ──────────────────────────────────
"I can't access           Browser 
Read from source at commit 9e176011f7e9OBSERVED · 2026-10-11
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add fennec-core --env FENNEC_VAULT_KEY=${FENNEC_VAULT_KEY} -- npx -y @plumpslabs/[email protected]
claude-desktop
{
  "mcpServers": {
    "fennec-core": {
      "command": "npx",
      "args": [
        "-y",
        "@plumpslabs/[email protected]"
      ],
      "env": {
        "FENNEC_VAULT_KEY": "${FENNEC_VAULT_KEY}"
      }
    }
  }
}
03

Exposed tools (19)

17 read · 1 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
Contextread
Debugread
Disabledread
Execwrite
Failingread
Otherread
Retryread
Simpleread
Skipread
Testread
WF1read
WF2read
browserreadBrowser automation and DevTools — navigation, interaction, DOM, console, network, storage, auth, tabs, diagnostic
mobilereadMobile device management via ADB — device detection, tap, type, swipe, pinch, logcat, screenshot, UI hierarchy dump, app management. Integrated with EventBus for cross-layer correlation.
processdestructiveProcess management and terminal monitoring — spawn, kill, attach, pipe watching, log filtering
testread
test_emptyreadAn empty tool
test_helloreadA test tool
test_toolreadTest tool
04

Trust audit

BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
declared (7 observation(s))
Shell
declared (6 observation(s))
Dependencies
not all pinned
Secrets in source
none-found

Findings (21)

HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
packages/cli/src/commands/dev.ts:82
const parsed = yaml.load(raw) as DevConfig;
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/src/utils/system-process.ts:702
return `http://127.0.0.1:${port}${healthCheck}`;
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
process
Why it matters. 1 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/cli/src/commands/ps.ts:316
readFileSync(new URL('../../package.json', import.meta.url), 'utf-8'),
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/cli/tests/e2e/cli-workflow.test.ts:26
const CLI = resolve(__dirname, '../../dist/index.js');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/cli/tests/unit/assistant.test.ts:16
} from '../../src/commands/assistant.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/cli/tests/unit/store.test.ts:5
import { VERSION } from '../../src/utils/banner.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/cli/tests/unit/store.test.ts:8
const CLI = resolve(__dirname, '../../dist/index.js');
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/README.md:170
With `--sse`, Fennec starts an HTTP+SSE endpoint (default `http://127.0.0.1:3333/sse`).
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/tests/e2e/cli-workflow.test.ts:206
`require('http').get('http://127.0.0.1:${port}',r=>process.exit(0)).on('error',()=>process.exit(1))`,
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/tests/e2e/cli-workflow.test.ts:346
`require('http').get('http://127.0.0.1:${extPort}',r=>process.exit(0)).on('error',()=>process.exit(1))`,
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/cli/tests/e2e/cli-workflow.test.ts:390
`require('http').get('http://127.0.0.1:${extPort}',r=>process.exit(0)).on('error',()=>process.exit(1))`,
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
prettier, typescript
Why it matters. 2 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
packages/cli/package.json
js-yaml, cli-table3, picocolors, @types/js-yaml, @types/node, tsup, typescript, vitest
Why it matters. 8 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
packages/core/package.json
@modelcontextprotocol/sdk, js-yaml, zod, zod-to-json-schema, @types/js-yaml, @types/node, playwright, tsup
Why it matters. 10 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/getting-started.md:290
smart_fill_form({ fields: { "email": "[email protected]", "password": "secret" }, submitAfter: true })
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
examples/debug-api-error/README.md:103
"text": "{\"success\":true,\"data\":{\"page\":{\"url\":\"http://localhost:3000/login\",\"title\":\"Login Page\",\"readyState\":\"complete\"},\"consoleErrors\":[\"TypeError: Cannot read properties of u
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
examples/debug-api-error/README.md:136
"text": "{\"success\":true,\"data\":{\"browser\":{\"url\":\"http://localhost:3000/login\",\"title\":\"Login Page\",\"consoleErrors\":[\"TypeError: Cannot read properties of undefined (reading 'token')
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
examples/login-flow/README.md:96
"text": "{\"success\":true,\"data\":{\"request\":{\"url\":\"https://api.example.com/api/auth/token\",\"method\":\"POST\",\"headers\":{\"content-type\":\"application/json\"},\"postData\":\"{\\\"email\\
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
INFOPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/ARCHITECTURE.md:266
| **🗄️ Database**    | dbTui sidecar (Go binary)           | Database observation: PostgreSQL, MySQL, SQLite — schema inspection, read-only queries, health checks, credential management via OS keychai
Why it matters. asks the agent to read credentials

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 9e176011f7e9full audit observations/trust-audit/mcp-server/plumpslabs__fennec.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-119e176011f7e9BLOCKD69first audit
06

Questions

What is the fennec MCP server?

AI-native developer observability MCP (Model Context Protocol) server that gives AI agents full-stack visibility into your development environment — browser, terminal, and processes — all in one unified interface.

What tools does fennec expose?

19 in total: 17 read-only, 1 that write, and 1 that can delete or overwrite (process). Every one is listed on this page with its risk.

Is fennec safe to connect to an agent?

No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does fennec need?

It reads FENNEC_VAULT_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does fennec run?

It speaks sse and stdio, so it runs as a local process your client starts. It is published on npm as @plumpslabs/fennec-core at 1.17.1.

How current is this page?

The grade is for one exact copy of the source (9e176011f7e9), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement