Stable — breaking changes only with a major version
Rule identifiers
Every check has arule_id (e.g. tools_description_present_in_all). A
rule_id is never renamed and never reused for a different check. Rules
may be added in any release; a rule may be retired (stops running) but
its identifier is never given a new meaning.
Integrations should key on rule_id — not on rule names, messages, or
positions, which may be reworded or reordered in any release.
Report schema
The--json report carries schema_version (currently 1). Within a
schema version:
- Existing fields keep their names, types, and meanings.
- New fields may be added in any release — consumers must ignore unknown fields.
- Field removals or type changes bump
schema_version.
schema_version, mcpscore_version,
generated_at, target, transport, score, max_score,
authenticated, partial, partial_reason, summary, results[],
skipped_rules[], spec, readiness.
CLI interface
- The invocation shape —
mcpscore <target>with--json,--header,--token(and theMCPSCORE_TOKENenvironment variable) — is stable. New flags may be added; existing flags keep their meaning. - Exit codes are a contract: 0 audit completed (regardless of score);
1 the audit was never attempted — a usage error or a failed
--oauthflow (timeout, refusal, registration or token-exchange failure); 2 connection failure to the target server with no fallback available. --jsonwrites exactly one JSON document to stdout; all logs go to stderr. Pipelines may rely on stdout being clean JSON.
Credential handling
Header and token values are never logged and never written to the report — only the booleanauthenticated flag is recorded. This is a permanent
commitment, not a default.
Evolving by design — expect movement between releases
The score
The score is ruleset-dependent and the ruleset grows.score and
max_score are severity-weighted sums over the rules that ran: adding
rules (most releases) changes both, so a score is comparable only
within the same mcpscore version against the same server. Track
mcpscore_version alongside any score you store. We would rather grow
the checks than freeze the number early; a calibrated scoring frame is
planned to revisit this once the ruleset stabilizes.
Two flags qualify a score further:
partial: true— only the observable surface of an auth-gated server was scored; not comparable to a full audit.readiness.counted_in_main: true— a modern-lifecycle server’s readiness points are included in the main score (see methodology); a CImin-scorethreshold means something slightly different on either side of this flag.
Messages, details, and rule metadata
Human-readablemessage strings, details contents (including the
basis citations), severities, and category groupings may be improved in
any release. They are for humans and for context — not for keying logic.
Readiness rules
Readiness rules target the next spec revision, so the readiness rule set turns over at each revision: rules for a now-current revision migrate into the main axis and new readiness rules appear for the next draft. Theirrule_ids still follow the never-reused rule.
Versioning
mcpscore follows SemVer: breaking changes to anything in the “Stable” section require a major version; rule additions and score movement are minor-version territory; pre-releases (bN) may
change anything and exact-pin their dependencies.