The GitHub Copilot CLI skill
Public repository documentation · View source on GitHub
On this page
A skill is how this tool reaches an AI agent. Without one, an agent asked "review my threat model" has to work out on its own that a reviewer exists, where it lives, which verb to call and what the exit codes mean — and when we tested that, it read the source and built the CLI from a repository nobody outside the team can clone. It got the right answer after nine minutes and 354 AI credits. With the skill, it runs one command.
Download ThreatModelReviewer-vX.Y.Z-skill.zip from the
Threat Model Reviewer releases.
The v2.6.0 skill and CLI include restricted MCP context and captured-revision/ evidence safeguards. Keep the bundles matched; do not run unsupported commands against an older CLI or silently replace the engine with AI reasoning.
For optional developer context, MCP is the tool protocol, the GitHub Copilot
SDK hosts the sessions, and each tool is a named operation with an input schema
backed by a service API. The OpenAI-compatible and Offline providers do not
attach these MCP profiles. The skill must route to the existing CLI/manager
instead of configuring another connector or implying universal SDK support.
Use mcp show <id> for configured names/capabilities and explicitly consented
mcp test <server-id> for one server, mcp test <id> <id> ... for an explicit
selection, or plain mcp test for all enabled servers. Selection is per server,
not per tool, and never enables a source or the master implicitly. Any invalid
or unconsented requested source rejects the whole probe before startup.
Probes close before reporting discovered names and SDK/schema readiness;
historical probe success is not live AI-session connectivity or authenticated
resource access. Saved consent still controls the next MCP-enabled AI request.
Preserve the command's source/stage diagnostics. A generic timeout is not
proof of an npm policy block, and a disabled GitHub profile's missing PAT
does not explain Azure bootstrap. An explicit managed-security block requires
IT approval, never a mirror/download fallback or disabled security controls.
What it does
The skill teaches an agent five jobs, each mapped to what a developer actually asks rather than to our verb names:
| Ask | What the agent runs |
|---|---|
| "review this threat model", "is it ready for sign-off" | the default review verb, then reports verdict, score and gating findings |
| "why is it NOT READY" | ask, which answers from the model's own numbers with no AI call |
| "fix what you can" | fix, previewed first, then written to a new .tm7 |
| "did the posture regress" | compare, including per-check regressions |
| "build me a model from this API / IaC / diagram" | ingest then generate --evidence, or openapi |
It also carries the CI recipes, the spec schemas, and the full rubric so an agent can explain a check id instead of inventing one.
The invariant it protects
The verdict and the 0–100 score are 100% deterministic. They come from 72 rubric checks in
ThreatModelReviewer.Core, which has no AI dependency and runs offline.
The skill says so in its own first section, and then states the consequence in the imperative:
- Never state a verdict, score or gating count you did not read out of the tool's output.
- Never imply that you, or any AI, can change a verdict.
- If the tool cannot be run, say so and stop.
That last rule matters most. An agent that cannot find the CLI has every incentive to reason its way to a plausible-looking verdict, and a plausible-looking verdict is worse than no answer, because somebody will quote it in a sign-off.
Install
You need two downloads: the skill, and the CLI it drives.
# 1. The skill bundle
Expand-Archive ThreatModelReviewer-vX.Y.Z-skill.zip -DestinationPath C:\tools\tmr-skill
# 2. The CLI, which does the actual work
Expand-Archive ThreatModelReviewer-vX.Y.Z-cli-win-x64.zip -DestinationPath C:\tools\tmr-cli
$env:THREAT_MODEL_REVIEWER_CLI = 'C:\tools\tmr-cli' # or put the folder on PATH
# 3. Register the skill
copilot skill add C:\tools\tmr-skill\skills
copilot skill list # 'threat-model-reviewer' should be listed
Register the skills directory, not the single SKILL.md. copilot skill add <file> copies
only that one file, which leaves the reference guides and the resolver script behind.
For one repository rather than your user account, copy skills/threat-model-reviewer/ into that
repository's .github/skills/. It can also be loaded as a plugin, which suits a pipeline:
copilot --plugin-dir C:\tools\tmr-skill -p "review docs/threat-model.tm7"
Use it
> review docs/threat-model.tm7
> why is this threat model NOT READY?
> fix what you can in Model.tm7 and write a corrected copy
> did the security posture regress between these two revisions?
> generate a threat model from openapi.yaml, with an evidence file
Non-interactively:
copilot -p "review docs/threat-model.tm7 and list the gating findings" --allow-all-tools
What is in the bundle
| Path | Purpose |
|---|---|
skills/threat-model-reviewer/SKILL.md |
The skill: routing, the determinism invariant, the five jobs, exit codes |
references/cli-reference.md |
Every verb and flag, and what authentication each needs |
references/rubric-and-verdict.md |
How the verdict is decided, the 8 gating checks, all 72 check ids |
references/spec-schemas.md |
The generate and create spec schemas, which differ |
references/ci-recipes.md |
GitHub Actions, Azure DevOps, pre-commit, batch review |
references/developer-context.md |
MCP consent/credentials, saved-revision identity, and evidence recovery limits |
scripts/Invoke-ThreatModelReviewer.ps1 |
Finds the CLI and forwards the exit code unchanged |
plugin.json |
Plugin manifest |
The references exist so SKILL.md can stay short. An agent loads the description first and reads
only the reference it needs, which keeps the common case cheap.
Finding the CLI
Invoke-ThreatModelReviewer.ps1 searches, in order: THREAT_MODEL_REVIEWER_CLI, then PATH, then
its own folder and the usual install locations, capped at three directories deep so it cannot appear
to hang on a large Downloads folder.
pwsh -NoProfile -File .\scripts\Invoke-ThreatModelReviewer.ps1 -WhereIs
It forwards the CLI's exit code verbatim, and returns 1 itself only when the executable cannot be
found — which is correctly a run that failed. A wrapper that rewrote the exit code would turn a
failing CI gate into a passing one, so it deliberately adds nothing.
Exit codes
0 READY WITH NOTES · 2 NOT READY · 1 the run failed. The skill spells out that 1 is not a
verdict, because "the command was wrong" and "the model is bad" look identical to an agent that has
only a non-zero number to go on.
What is guarded
ThreatModelReviewer.Tests/SkillPackagingTests.cs guards the bundle, because nothing
compiles it and a wrong sentence in a skill becomes a wrong command. They assert, among other
things, that:
- every verb and flag the skill tells an agent to run is one the CLI actually parses;
- the two documented spec examples deserialize and generate a real model, so the
generateandcreateschemas cannot drift apart from the docs that describe them; - every gating check the engine gates on is named in the rubric reference;
- every relative link resolves, so progressive disclosure does not dead-end;
- the description stays inside the loader's 1024-character limit;
- the resolver still forwards
$LASTEXITCODE; - the release script still packages the bundle.
Each guard was checked by breaking the thing it protects and confirming the test failed.
The 1024-character limit is in there because the first draft of the description was 1199 characters
and copilot skill add refused it outright. Nothing in the build would have caught that.
Limits
- Windows x64 only. The CLI has no Linux or macOS build, so this cannot run on a Linux runner.
- The engine reads the model, not the system. It cannot verify that a claimed mitigation is actually deployed.
- Generation enumerates; it does not analyse. Every generated threat is Needs Investigation.
- AI operations need provider access. Deterministic review and built-in fixes work offline.
The
azureverb is also deterministic, but requires Azure network access and sign-in. MCP testing/context adds separate network and credential paths; MCP explains consent and the restricted profiles. Read-only is not nonsensitive. - Model fixes are not code fixes. The owning team implements and verifies mitigations.
- Skill selection is not guaranteed. An agent chooses a skill from its description. On a machine with hundreds of skills installed the list an agent sees can be truncated, and the skill may not be offered at all. Naming it — "use the threat-model-reviewer skill" — always works.
See also
- CLI reference — the tool the skill drives
- Install guide
- Data handling — exactly what the AI verbs send, and when