Skip to content

Conversation

@adamoutler
Copy link
Collaborator

@adamoutler adamoutler commented Feb 2, 2026

Summary

This PR stabilizes the MCP (Model Context Protocol) bridge, automates development environment configuration for AI agents, and cleans up API documentation and schemas.

Key Changes

🛠️ Fixes

  • MCP Bridge (mcp_endpoint.py):
    • Fixed a critical crash where endpoints returning plain text (like /metrics) caused JSON parsing errors.
    • Added robust exception handling for ValueError alongside JSONDecodeError.
  • Schemas (schemas.py):
    • Enhanced CreateSessionRequest and CreateEventRequest with strict MAC address regex validation (pattern=MAC_PATTERN).
    • Added validation for create_device_event path parameters.

⚡ Enhancements

  • Devcontainer Automation (generate-configs.sh):
    • Added logic to automatically configure .gemini/settings.json and .vscode/mcp.json if an API_TOKEN is detected.
    • Enables seamless integration for Gemini CLI and VS Code users immediately after container creation.
  • Gitignore:
    • Added .gemini/settings.json and .vscode/mcp.json to prevent secret leakage.

📚 Documentation

  • API Docs (API_MCP.md):
    • Corrected tool endpoint paths (removed incorrect /mcp/sse/ prefixes).
    • Standardized path parameters to use curly braces {mac} matching OpenAPI standards.
    • Clarified tool relationships (e.g., run_nmap_scan populates get_open_ports).
  • OpenAPI:
    • Added links to run_nmap_scan and get_open_ports definitions to help agents discover related tools.

Testing

  • Verified get_metrics now returns plain text successfully.
  • Verified auto-configuration script correctly extracts tokens.
  • Ran comprehensive test suite (pytest test/api_endpoints/test_mcp_tools_endpoints.py passed).

Summary by CodeRabbit

  • New Features

    • Added a named device totals endpoint for enhanced reporting
    • Optional generation of Gemini and VS Code MCP configs when an API token is present
  • Documentation

    • Updated API docs to use streamlined endpoint paths
    • Expanded testing workflow with environment reset, token retrieval, and troubleshooting
  • Improvements

    • Stricter device identifier validation and narrowed NMAP mode options
    • Clearer, more actionable error messages and more tolerant response parsing

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

This PR removes /mcp/sse/ prefixes from many MCP routes, adds a new /devices/totals/named endpoint and schema, tightens MAC/NMAP validation, broadens MCP endpoint JSON parsing, adds devcontainer script support to generate Gemini and VS Code MCP configs from an API token, updates docs/tests, and ignores generated config files.

Changes

Cohort / File(s) Summary
Dev Container & Generated Configs
.devcontainer/scripts/generate-configs.sh, .gitignore
Adds conditional post-generation step that reads API_TOKEN from /data/config/app.conf to create/update .gemini/settings.json and .vscode/mcp.json with SSE server entries and Bearer header; new generated files are gitignored.
Developer Workflow & Docs
.gemini/skills/testing-workflow/SKILL.md, docs/API_MCP.md
Reworks testing skill to include container environment check, environment reset, and token retrieval steps; updates MCP docs to remove /mcp/sse/ prefixes and adjust tool endpoint examples and descriptions.
API Routes & Tests
server/api_server/api_server_start.py, test/api_endpoints/test_mcp_tools_endpoints.py
Removes /mcp/sse/ prefix from multiple routes, adds new endpoint /devices/totals/named, updates OpenAPI metadata/descriptions, and adjusts tests to use new flatter endpoint paths.
OpenAPI Schemas & Validation
server/api_server/openapi/schemas.py
Adds DeviceTotalsNamedResponse model (totals: Dict[str,int]); narrows ALLOWED_NMAP_MODES to ["fast","normal","detail","skipdiscovery"]; adds MAC pattern validation to CreateSessionRequest.mac.
MCP Endpoint Robustness
server/api_server/mcp_endpoint.py
Expands JSON parsing exception handling to catch both json.JSONDecodeError and ValueError, allowing fallback to raw text for non-JSON responses (e.g., /metrics).

Possibly related PRs

Poem

🐰 A token tucked beneath my paws,
I sketch config maps without a pause,
Paths shortened, schemas tight and neat,
Devcontainer hums a steady beat,
Hop on—new routes make code complete.

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the primary changes: MCP bridge fixes and dev environment automation. It directly relates to the main objectives of stabilizing the MCP endpoint, automating devcontainer configuration, and improving the development setup.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
server/api_server/openapi/schemas.py (1)

720-745: ⚠️ Potential issue | 🟠 Major

Remove pattern=MAC_PATTERN from the mac field—the field validator validate_mac() already handles regex validation.

The pattern constraint rejects "Internet" before the field validator runs (Pydantic validates JSON schema constraints before field validators). Since validate_mac() explicitly allows "Internet" as a special case for the WAN/gateway device, the regex pattern should not appear here.

-    mac: str = Field(..., description="Device MAC", pattern=MAC_PATTERN)
+    mac: str = Field(..., description="Device MAC")
docs/API_MCP.md (1)

45-52: ⚠️ Potential issue | 🟡 Minor

Update the OpenAPI spec endpoint path in the sequence diagram to match the canonical route.
The diagram shows GET /mcp/sse/openapi.json, but the actual Flask route registered is /openapi.json (api_server_start.py:1171). Update the diagram to use the canonical path for consistency.

🤖 Fix all issues with AI agents
In @.gemini/skills/testing-workflow/SKILL.md:
- Around line 54-57: In the "Authentication & Environment Reset" section fix the
missing space by changing the contiguous token "APIs.After" to "APIs. After" so
the sentence reads correctly; update the paragraph that mentions `API_TOKEN`
under the "Authentication & Environment Reset" heading to include the space
after the period.
- Around line 11-23: Add a new pre-run step that invokes testFailure() before
running the test suite: insert a "0.5 Pre-run: Capture current failures" section
immediately after the "## 0. Pre-requisites: Environment Check" block in
.gemini/skills/testing-workflow/SKILL.md and include the single-line invocation
testFailure() so the workflow captures current failures before executing tests.
🧹 Nitpick comments (2)
.devcontainer/scripts/generate-configs.sh (1)

34-45: Harden permissions for generated token configs.
These files store bearer tokens; set restrictive permissions after writing to reduce accidental exposure in shared volumes.

🔒 Suggested hardening
     jq --arg t "$TOKEN" '.mcpServers["netalertx-devcontainer"] = {url: "http://127.0.0.1:20212/mcp/sse", headers: {Authorization: ("Bearer " + $t)}}' "${ROOT_DIR}/.gemini/settings.json" > "${ROOT_DIR}/.gemini/settings.json.tmp" && mv "${ROOT_DIR}/.gemini/settings.json.tmp" "${ROOT_DIR}/.gemini/settings.json"
+    chmod 600 "${ROOT_DIR}/.gemini/settings.json"

     # VS Code MCP config
     mkdir -p "${ROOT_DIR}/.vscode"
     [ -f "${ROOT_DIR}/.vscode/mcp.json" ] || echo "{}" > "${ROOT_DIR}/.vscode/mcp.json"
     jq --arg t "$TOKEN" '.servers["netalertx-devcontainer"] = {type: "sse", url: "http://127.0.0.1:20212/mcp/sse", headers: {Authorization: ("Bearer " + $t)}}' "${ROOT_DIR}/.vscode/mcp.json" > "${ROOT_DIR}/.vscode/mcp.json.tmp" && mv "${ROOT_DIR}/.vscode/mcp.json.tmp" "${ROOT_DIR}/.vscode/mcp.json"
+    chmod 600 "${ROOT_DIR}/.vscode/mcp.json"
server/api_server/api_server_start.py (1)

769-791: Consider adding a constant or validation for the totals list structure.

The index-based extraction with defensive bounds checking is reasonable, but the mapping relies on an implicit contract with getTotals() that returns [devices, connected, favorites, new, down, archived]. If the order changes or items are added/removed, this will silently return incorrect data or zeros.

The static analysis warning about unused payload (line 778) can be safely ignored—it follows the pattern used by other endpoints where the @validate_request decorator may inject validated payload.

💡 Optional: Document or validate the structure
 def api_devices_totals_named(payload=None):
     device_handler = DeviceInstance()
     totals_list = device_handler.getTotals()
-    # totals_list order: [devices, connected, favorites, new, down, archived]
+    # Expected totals_list order: [devices, connected, favorites, new, down, archived]
+    EXPECTED_TOTALS_LENGTH = 6
+    if len(totals_list) != EXPECTED_TOTALS_LENGTH:
+        mylog("verbose", [f"[api_devices_totals_named] Unexpected totals length: {len(totals_list)}, expected {EXPECTED_TOTALS_LENGTH}"])
     totals_dict = {

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.gemini/skills/testing-workflow/SKILL.md (1)

78-78: ⚠️ Potential issue | 🟡 Minor

Add working directory to troubleshooting command.

Same issue as the token retrieval step above: the python command needs to be run from the project root directory.

📂 Proposed fix to add working directory
-3. Verify Python can read it: `python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"`
+3. Verify Python can read it: `cd /workspaces/NetAlertX; python3 -c "from helper import get_setting_value; print(get_setting_value('API_TOKEN'))"`
🤖 Fix all issues with AI agents
In @.gemini/skills/testing-workflow/SKILL.md:
- Around line 66-69: The token-retrieval example uses a relative import (from
helper import get_setting_value) which can fail if not run from project root;
update the command in SKILL.md to change to the project working directory first
(e.g., cd /workspaces/NetAlertX) before running the python3 -c invocation so
helper.get_setting_value is importable; ensure the modified line mirrors other
examples that explicitly switch to /workspaces/NetAlertX.

@adamoutler
Copy link
Collaborator Author

adamoutler commented Feb 3, 2026

@jokob-sk you can run the generate container configs task now to give AI agents such as Copilot or Gemini access to the NetAlertX API. it will generate a project settings for Gemini and a mcp.json for Copilot. This will allow testing, manipulating, and helping with UI work.

@jokob-sk jokob-sk merged commit 22bb936 into netalertx:main Feb 3, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants