Add dev stacks

This commit is contained in:
2025-12-31 20:11:44 -05:00
parent 0bcfed8fb8
commit 13989e2b59
49 changed files with 4948 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# Network MCP - Project Summary
## Overview
This project is a long-running Network MCP service that merges OPNsense discovery data, Nmap scans, and static inventory into Elasticsearch, then exposes both a minimal web UI and a full MCP JSON-RPC interface for LLM agents. It runs via Docker Compose and is now located at `/var/core/network-mcp`.
## What We Built
- **Collectors**
- OPNsense collector ingests DHCP/ARP/DNS and overlays inventory targets.
- Nmap collector performs discovery and port scans.
- Data lands in Elasticsearch: `network-hosts` (current state) and `network-events-*` (historical events).
- **Inventory merge**
- Inventory data from `inventory_targets.yml` is merged onto live hosts by IP when a MAC is known (so live MAC-based records carry inventory notes/expected ports).
- **Frontend**
- Flask UI + JSON API, containerized with Gunicorn and exposed on port `5001` for LAN access.
- **MCP server**
- JSON-RPC endpoint at `/.well-known/mcp.json` (and `/api/mcp`) supports:
- `initialize`, `ping`, `tools/list`, `tools/call`
- `resources/list`, `resources/read`, `resources/templates/list`
- Tool schemas include titles, descriptions, input/output schemas, and annotations (read-only hints).
- Resource templates provide snapshot + query access (e.g. `network://hosts?q=...`).
- **Search behavior**
- Host search is case-insensitive across name/hostname/IP/MAC.
- **Tests**
- Unit tests for REST and MCP search by hostname/IP/MAC, MCP resource reads, and MCP notifications.
## Key Endpoints
- UI: `http://<host>:5001/`
- REST:
- `GET /api/hosts` (supports `q`, `source`, `limit`)
- `GET /api/hosts/<host_id>`
- `GET /api/events`
- `GET /api/hosts/<host_id>/events`
- `GET /api/map`
- MCP JSON-RPC: `POST /.well-known/mcp.json`
## MCP Tools (JSON-RPC)
- `list_hosts` (search by hostname/IP/MAC; case-insensitive)
- `get_host` (optional events)
- `list_events`
- `host_events`
- `network_map`
## MCP Resources
- `resources/list` -> `network://hosts`, `network://map`, `network://events`
- `resources/templates/list` -> query templates such as:
- `network://hosts{?q,source,limit}`
- `network://host/{host_id}{?include_events,events_limit}`
- `network://events{?host_id,type,since,limit}`
## Docker & Repo State
- Repo path: `/var/core/network-mcp`
- `inventory_targets.yml` lives in the repo and is mounted via compose.
- Services run via `docker-compose up -d`.
- Git repo initialized and initial commit created.
## Gotchas / Pitfalls We Hit
- **MCP handshake**: Codex sent `notifications/initialized` without `id` (notification). Returning a response caused the transport to close. Fixed by treating notifications as no-response.
- **Case-sensitive search**: Elasticsearch wildcard on `.keyword` fields was case-sensitive, so `seele` didnt match `SEELE`. Fixed via `case_insensitive: true` in wildcard queries.
- **Inventory merge duplication**: Initial inventory-only docs were `ip:*` and live docs were `mac:*`, so both existed. Merge now attaches inventory to live MAC records by IP. Legacy `ip:*` docs may remain stale unless cleaned.
- **MCP errors**: Tool errors are now returned as `CallToolResult` with `isError: true` (instead of JSON-RPC errors), so LLMs can see and correct issues.
- **Service move**: Repo moved from `/var/core/ansible/network-mcp` to `/var/core/network-mcp`. Compose mount paths updated.
## Verification Performed
- REST search works for hostname/IP/MAC.
- MCP `initialize`, `tools/list`, `tools/call` work.
- MCP resource list/templates/read work.
- Services verified running via `docker-compose up -d`.
## Future Work Ideas
- **Cleanup**: Add a cleanup job to remove stale `ip:*` docs after successful MAC merge.
- **Resource subscriptions**: Implement `resources/subscribe` if clients need push updates.
- **Auth**: Optional token on the MCP endpoint for shared LAN exposure.
- **More UI**: Add filters/alerts for stale hosts or missing expected ports.
- **Metrics**: Export collector stats to detect scan/ingest failures.
- **Schema mapping**: Improve Elasticsearch mappings for search (e.g., lowercase normalizers for names/hostnames).