MCP-8 #4972 "Connect card, docs, and end-to-end integration test". - AI access page: a "Connect a client" card with the /mcp URL (from Settings → General → Public base URL, else the request host) and recipes for Claude Code, Claude Desktop (mcp-remote) and other Streamable HTTP clients, plus the reverse-proxy note. The token-created page shows the same recipes with the new token filled in, ready to paste. - docs/core/mcp.md: connecting, the reverse-proxy requirements, the security model (token ceiling, default deny, check-mode default, secrets, audit), tools by role, response conventions, adding tools. docs/architecture.md describes the /mcp dispatch outside the blueprint pipeline; docs/reference/code-map.md gains an MCP section. - tests/integration/test_mcp.py: over HTTP, a viewer token lists no write tools and is refused one by name; an operator token reads get_overview and its maintenance-window create/end land in the audit log as "<user> via MCP" with the token id. (Revoked → 401 was already covered.) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
7.1 KiB
7.1 KiB
Code Map
Quick reference for where key functions, models, and entry points live in the codebase.
Application Bootstrap
| What | File | Function / Class |
|---|---|---|
| App factory | steward/app.py |
create_app() |
| CLI entry point | steward/cli.py |
main() |
| Bootstrap config loading | steward/config.py |
load_bootstrap() |
| Secret key resolution | steward/config.py |
_resolve_secret_key() |
| DB engine init | steward/database.py |
init_db() |
| Core migrations | steward/core/migration_runner.py |
run_core_migrations() |
| Plugin migrations | steward/core/migration_runner.py |
run_plugin_migrations() |
| Core task registration | steward/app.py |
_register_core_tasks() |
| Scheduler loop | steward/core/scheduler.py |
start_scheduler() |
Settings System
| What | File | Function |
|---|---|---|
| All defaults | steward/core/settings.py |
DEFAULTS dict |
| Read a setting | steward/core/settings.py |
get_setting(session, key) |
| Write a setting | steward/core/settings.py |
set_setting(session, key, value) |
| Read all settings | steward/core/settings.py |
get_all_settings(session) |
| Sync load at startup | steward/core/settings.py |
load_settings_sync(db_url) |
| Extract SMTP dict | steward/core/settings.py |
to_smtp_cfg(settings) |
| Extract webhook dict | steward/core/settings.py |
to_webhook_cfg(settings) |
| Extract Ansible dict | steward/core/settings.py |
to_ansible_cfg(settings) |
| Extract plugins dict | steward/core/settings.py |
to_plugins_cfg(settings) |
Plugin System
| What | File | Function |
|---|---|---|
| Plugin loading | steward/core/plugin_manager.py |
load_plugins(app) |
| ScheduledTask dataclass | steward/core/scheduler.py |
ScheduledTask |
| Task runner | steward/core/scheduler.py |
start_scheduler(tasks) |
Alert Pipeline
| What | File | Function |
|---|---|---|
| Write metric + evaluate alerts | steward/core/alerts.py |
record_metric(session, source_module, resource_name, metric_name, value) |
| Init alert pipeline | steward/core/alerts.py |
init_alerts(app) |
| Rule evaluation | steward/core/alerts.py |
_evaluate_rule() (internal) |
| Notification dispatch | steward/core/alerts.py |
_dispatch_notification() (internal) |
| Email + webhook send | steward/core/notifications.py |
dispatch_notifications() |
Monitors
| What | File | Function |
|---|---|---|
| Ping a host | steward/monitors/ping.py |
ping_check(host, session) |
| DNS check a host | steward/monitors/dns.py |
dns_check(host, session) |
| Data cleanup | steward/core/cleanup.py |
run_cleanup(app) |
Auth
| What | File | Function / Class |
|---|---|---|
| Role-based access decorator | steward/auth/middleware.py |
@require_role(UserRole.X) |
| Login / session handling | steward/auth/middleware.py |
login_user(), logout_user() |
| User count (for first-run) | steward/auth/middleware.py |
get_user_count(app) |
Data Models
| Model | File | Table |
|---|---|---|
Host |
steward/models/hosts.py |
hosts |
PingResult |
steward/models/monitors.py |
ping_results |
DnsResult |
steward/models/monitors.py |
dns_results |
AlertRule |
steward/models/alerts.py |
alert_rules |
AlertState |
steward/models/alerts.py |
alert_states |
AlertEvent |
steward/models/alerts.py |
alert_events |
PluginMetric |
steward/models/metrics.py |
plugin_metrics |
AnsibleRun |
steward/models/ansible.py |
ansible_runs |
User |
steward/models/users.py |
users |
AppSetting |
steward/models/settings.py |
app_settings |
TraefikMetric |
plugins/traefik/models.py |
traefik_metrics |
SQLAlchemy Base |
steward/models/base.py |
(shared declarative base) |
HTTP Routes
| URL pattern | Blueprint | File |
|---|---|---|
/ (dashboard) |
dashboard_bp |
steward/dashboard/routes.py |
/auth/login, /auth/logout |
auth_bp |
steward/auth/routes.py |
/hosts/ |
hosts_bp |
steward/hosts/routes.py |
/ping/, /ping/rows, /ping/settings |
ping_bp |
steward/ping/routes.py |
/dns/, /dns/rows |
dns_bp |
steward/dns/routes.py |
/alerts/ |
alerts_bp |
steward/alerts/routes.py |
/ansible/ |
ansible_bp |
steward/ansible/routes.py |
/settings/ |
settings_bp |
steward/settings/routes.py |
/plugins/traefik/, /plugins/traefik/widget |
traefik_bp |
plugins/traefik/routes.py |
/health |
(inline) | steward/app.py |
Templates
| Template | Purpose |
|---|---|
steward/templates/base.html |
Layout, navigation, full CSS design system |
steward/templates/dashboard/index.html |
Dashboard with stat strip and widget grid |
steward/templates/ping/rows.html |
HTMX fragment: ping pill rows (shared by dashboard and /ping/) |
steward/templates/ping/index.html |
Full /ping/ page |
steward/templates/dns/rows.html |
HTMX fragment: DNS status rows |
steward/templates/dns/index.html |
Full /dns/ page |
plugins/traefik/templates/traefik/widget.html |
HTMX fragment: Traefik dashboard widget |
plugins/traefik/templates/traefik/index.html |
Full Traefik detail page |
Migrations
| Location | Covers |
|---|---|
steward/migrations/versions/ |
Core schema (hosts, users, monitors, alerts, app_settings) |
plugins/traefik/migrations/versions/ |
traefik_metrics table |
alembic.ini |
Alembic config; version_locations lists all migration directories |
MCP server and API tokens
| What | File | Function / Class |
|---|---|---|
Mount /mcp (ASGI dispatch, bearer auth, DB gate) |
steward/mcp/server.py |
mount_mcp(app) |
| Server, role registry, refusals | steward/mcp/server.py |
StewardMCPServer, register_tool(), refusal() |
| Plugin tools and overview findings | steward/mcp/server.py |
register_plugin(name, module) |
| Caller and app inside a tool | steward/mcp/_context.py |
current_caller(), mcp_app() |
| Core tool modules | steward/mcp/tools/ |
register_all(); one module per area |
| Response conventions | steward/mcp/tools/_shape.py |
iso, age_s, bounded, lookback, summarize, pick |
| Audit a write as " via MCP" | steward/mcp/tools/_audit.py |
audit_mcp() |
| "What is wrong now" | steward/mcp/tools/overview.py |
get_overview() |
| Playbooks, runs, schedules, alert actions | steward/mcp/tools/automation.py |
run_playbook(), wait_for_run(), … |
| Monitor validation (forms and tools) | steward/monitors/service.py |
monitor_fields(), build_config() |
| Alert rule / window validation | steward/alerts/service.py |
rule_fields(), window_fields(), acknowledge() |
| Docker and host-agent tools | plugins/docker/mcp_tools.py, plugins/host_agent/mcp_tools.py |
register_tools(), mcp_overview() |
| Token model | steward/models/api_tokens.py |
ApiToken |
| Mint, resolve, revoke tokens | steward/core/api_tokens.py |
create_token(), resolve_token(), revoke_token() |
| Token management page and connect card | steward/ai_access/routes.py, steward/templates/ai_access/ |
ai_access_bp |