Announcing Beacon: Self-improving memory for coding agents
← All MCP servers
MCP server

jobwatch

mcp:vinayvobbili/jobwatch

Watch company job boards, rank new matches and track every application. Never auto-applies.

Verdict
Inconclusive

The analysis could not cover enough of the artifact to decide.

Analyzed Oct 26, 2026, 12:19 UTC at 087778d

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

0
findings
—
highest severity
0
threat classes
219
files scanned
2,776/2,776
checks satisfied
0
package advisories

Why this verdict

mcp-server . Inconclusive
  • inconclusive: gap no_dataflow_for_dynamic_code at jobwatch/score.py
skill skills/jobwatch No issues found
  • benign: 20 checks satisfied, no findings for skill:skills/jobwatch

Security findings 0

No individual findings recorded

The inconclusive verdict rests on the open questions and coverage gaps below; 4 candidate findings were refuted on review.

Open questions 2

What the analysis could not settle from the code alone.

[file request jobwatch/cli.py] What host does the `ui` subcommand (cmd_ui and its argparse definition) bind to by default, given service.install passes only --no-browser and --port? Is it localhost/127.0.0.1 only?
Persistence
[file request jobwatch/service.py] What does service.install write (launch agent plist path, command line, arguments)? Does it run only `jobwatch ui` bound to localhost, with a clean uninstall?
Persistence
Refuted findings 4

Candidates the review stage examined and rejected, kept for transparency.

Persistence

criticalRefutedmedium confidence

The `jobwatch service install` command writes and loads a macOS launchd agent that starts the UI at login and restarts it on exit; this is documented and opt-in, but it is persistence outside the MCP tool surface.

`jobwatch service install` writes ~/Library/LaunchAgents/<LABEL>.plist and loads it
Why it was refuted

The launchd agent is the module's stated purpose, is opt-in via an explicit CLI command, and has a documented uninstall. It is not reachable through any MCP tool or agent instruction.

Persistence

highRefutedlow confidence

The explicit `jobwatch service install` subcommand installs a login-start, auto-restart service (macOS launch agent) for the local web UI; it is user-invoked and disclosed, with an uninstall path.

jobwatch ui now starts when you log in and restarts if it stops
Why it was refuted

This is an explicit, user-invoked CLI subcommand, not an MCP tool, and its output states what it does and how to undo it. No agent instruction or undeclared concealment leads to it.

Credential access

highRefutedlow confidence

save_application_package reads any local path supplied by the agent and copies its bytes into the store, so a prompt-injected agent could pull in sensitive files such as keys; the tool does declare this, but nothing restricts it to resume or cover-letter files and there is no evidence the data leaves the host.

pkg.attach(path.name, path.read_bytes())
Why it was refuted

Reading local files is the tool's declared purpose: the parameter says it takes local paths and keeps copies. The bytes go into the local store, and no network sink is shown.

Code execution

highRefutedlow confidence

The undeclared scoring.key_command config value is split and run as an arbitrary subprocess to obtain an API key, so any command placed in the watchlist config executes with the user's privileges (documented, user-configured, no concealment).

r = subprocess.run(argv, capture_output=True, text=True, timeout=KEY_COMMAND_WAIT)
Why it was refuted

scoring.key_command is a documented, user-configured key helper, comparable to a credential helper. The code's docstring describes it, and no agent-reachable path for setting it is shown.

Coverage gaps 9

Parts of the artifact the static analysis could not fully examine.

context:unanalyzable_binary binary content is only byte-scanned
docs/jobwatch-demo.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-01-getting-started.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-02-daily-routine.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-03-where-the-ai-runs.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-04-applying.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-05-tracking.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-06-interview-prep.mp4
context:unanalyzable_binary binary content is only byte-scanned
docs/tutorials/jobwatch-07-comps-and-contacts.mp4
no_dataflow_for_dynamic_code line 230: invoked code is not structurally extracted
jobwatch/score.py