Do this once. Every runtime builds on these steps.
- Python 3.11+ and uv (
which uv— note the path; some runtimes need it absolute). - A local model server exposing an OpenAI-compatible endpoint (vLLM or llama.cpp), or a runtime that bundles one (LM Studio). Use a tool-calling model — Qwen3, GPT-OSS, or Gemma 4.
- API credentials for the platform(s) you want to connect (see below).
git clone https://github.com/ubercylon8/f0_sectools.git
cd f0_sectools
uv sync --all-packages # installs core + every server (editable)Report generation (the generate-report skill / scripts/gen_report.py) always
writes Markdown out of the box. For PDF export, install the optional
[reports] extra, which pulls in WeasyPrint — it needs the system libraries
pango and cairo on the host (apt install libpango-1.0-0 libcairo2, or
the equivalent for your OS):
uv pip install 'f0-sectools-core[reports]'Each server reads its own .env.<platform> from the repo root. These are
gitignored — they never enter version control, logs, the model, or any config
file.
cp servers/defender-mcp/.env.defender.example .env.defender # fill in values
cp servers/entra-mcp/.env.entra.example .env.entra # fill in valuesThe .env.*.example files document the exact Microsoft Graph application
permissions each server needs (read-only, admin consent). A missing permission
or license doesn't crash anything — the tool returns a posture finding telling
you what to grant.
The smoke scripts call every tool once and print redacted findings:
uv run python scripts/live_smoke_defender.py
uv run python scripts/live_smoke_entra.pyYou should see real data (or graceful "permission not granted / rate limited" findings). Secrets are never printed.
Continue with your chosen agent platform:
- Hermes Agent (recommended)
- LM Studio
- Open WebUI
- Claude Code
Before trusting a given model to drive the tools, score it:
uv run python -m evals.run --server defender \
--base-url http://localhost:8000/v1 --model <model-id> --runs 3Pass --server all to test the combined registry — every server's tools
registered at once — the same shape a multi-platform agent actually sees:
uv run python -m evals.run --server all \
--base-url http://localhost:8000/v1 --model <model-id> --runs 3A low score means the tool's schema is too hard for that model — pick a stronger
model or simplify the tool. To sweep every model in evals/models.yaml against
every server at once, see the scorecard in evals/ (writes
evals/SCORECARD.md).