Commit Graph

7 Commits

Author SHA1 Message Date
Jacob Magar
252ec520d1 fix(lint): remove __future__ annotations from new tools, fix 4 failing tests
- Remove `from __future__ import annotations` from array.py, live.py,
  oidc.py, plugins.py to match existing tool pattern and resolve TC002
  ruff errors (fastmcp imports only needed in annotations under PEP 563)
- Add `# noqa: ASYNC109` to live.py timeout parameter (asyncio.timeout
  already used internally)
- Fix test_network_sends_correct_query: query name is GetNetworkInfo
- Fix test_delete_requires_confirm: match "not confirmed" not "destructive"
- Fix test_destructive_set_matches_audit[settings]: add setup_remote_access
  and enable_dynamic_remote_access to KNOWN_DESTRUCTIVE
- Fix test_logs: update mock to dict format {lines: [{timestamp, message}]}

742 tests passing, ruff clean
2026-03-15 19:57:46 -04:00
Jacob Magar
ebba60c095 fix(types): suppress ty union-attr false positives on elicitation result.data access 2026-03-15 19:27:43 -04:00
Jacob Magar
2b4b1f0395 feat(plugins): add unraid_plugins tool with list, add, remove actions
Implements the unraid_plugins MCP tool (3 actions, 1 destructive) and adds
elicit_destructive_confirmation() to core/setup to support all tools that
gate dangerous mutations behind confirm=True with optional MCP elicitation.
2026-03-15 19:26:42 -04:00
Jacob Magar
e930b868e4 feat(creds): write to ~/.unraid-mcp/.env with 700/600 permissions, seed from .env.example
- _write_env now creates CREDENTIALS_DIR (mode 700) and writes credentials
  to CREDENTIALS_ENV_PATH (mode 600) instead of PROJECT_ROOT/.env
- On first run (no .env yet), seeds file content from .env.example to
  preserve comments and structure
- elicit_and_configure catches NotImplementedError from ctx.elicit() so
  clients that don't support elicitation return False gracefully instead
  of propagating the exception
- Updated test_elicit_and_configure_writes_env_file to patch CREDENTIALS_DIR
  and CREDENTIALS_ENV_PATH instead of PROJECT_ROOT
- Added 5 new tests covering dir/file permissions, .env.example seeding,
  in-place credential update, and NotImplementedError guard
2026-03-14 14:00:57 -04:00
Jacob Magar
85cd173449 fix(elicitation): guard ctx=None in elicit_and_configure, cover all settings/docker/notifications actions
- setup.py: elicit_and_configure now accepts Context | None; returns False
  immediately when ctx is None instead of crashing with AttributeError
- settings.py: added CredentialsNotConfiguredError try/except guard around
  make_graphql_request calls in all 8 previously-unguarded actions
  (update_temperature, update_time, configure_ups, update_api, connect_sign_in,
  connect_sign_out, setup_remote_access, enable_dynamic_remote_access)
- docker.py: added guards to all 20 previously-unguarded make_graphql_request
  calls (details, logs, networks, network_details, port_conflicts, check_updates,
  restart, update_all, all 11 organizer mutations, and single-container fallback)
- notifications.py: added guards to all 11 previously-unguarded calls
  (list, warnings, create, archive/unread, delete, delete_archived, archive_all,
  archive_many, create_unique, unarchive_many, unarchive_all, recalculate)
2026-03-14 04:28:34 -04:00
Jacob Magar
02e61b4290 refactor(elicitation): use PROJECT_ROOT directly (already a Path) 2026-03-14 03:50:45 -04:00
Jacob Magar
e73f791fd3 feat(elicitation): add elicit_and_configure() with .env persistence 2026-03-14 03:49:11 -04:00