Asi mcp-spec-checker

Predicate-level semantic diff for MCP protocol specs. Compares 0618 vs 1125 specs via Narya types, GF(3) evaluators, and Unison-style effects. Use for protocol verification, spec migration, or detecting breaking changes.

install
source · Clone the upstream repo
git clone https://github.com/plurigrid/asi
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/plurigrid/asi "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/asi/skills/mcp-spec-checker" ~/.claude/skills/plurigrid-asi-mcp-spec-checker && rm -rf "$T"
manifest: plugins/asi/skills/mcp-spec-checker/SKILL.md
source content

MCP Spec Checker

Semantic diff engine for MCP protocol specifications using three independent verification approaches with mandatory cross-validation.

Three Verification Approaches

ApproachFileTritRole
Narya Types
src/mcp_narya_types.py
-1 (MINUS)chk/syn/nosyn bidirectional typing
Agent-o-rama Evaluators
src/mcp_evaluators.py
0 (ERGODIC)GF(3) predicate evaluation
Unison Effects
src/mcp_effects.py
+1 (PLUS)Algebraic effect handlers

GF(3) Conservation:

(-1) + 0 + (+1) = 0 ✓

GF(3) Trit Assignments for Predicates

# From src/mcp_spec_predicates.py

PREDICATE_TRITS = {
    # MINUS (-1): Constraint/validation predicates
    "has_required_field": -1,
    "type_matches": -1,
    "schema_valid": -1,
    
    # ERGODIC (0): Coordination predicates
    "version_compatible": 0,
    "capability_negotiated": 0,
    "session_active": 0,
    
    # PLUS (+1): Generation/action predicates
    "tool_invoked": +1,
    "response_emitted": +1,
    "resource_created": +1,
}

Denotation

This skill compares MCP protocol specs at the predicate level, detecting semantic differences between versions and generating minimal counterexamples for incompatibilities via cross-validated triadic verification.

SemanticDiff = Inv_0618 △ Inv_1125 (symmetric difference)
Counterexample: min{msg : Inv_0618(msg) ≠ Inv_1125(msg)}
Consensus: ∀ approach ∈ {Narya, Evaluators, Effects}: result_agree

Invariant Set

InvariantDefinitionVerification
SpecVersionCompatibility
Old spec passing → new spec passing OR documented breaking changeDiff analysis
PredicateConsistency
Same predicate → same trit across versionsTrit comparison
CrossValidationConsensus
All 3 approaches agree on validityBisimulation game
CounterexampleMinimality
Generated counterexamples are minimal witnessesSize minimization

GF(3) Typed Effects

ApproachTritEffectDescription
Narya Types-1VALIDATORType-checks messages via chk/syn/nosyn
Evaluators0COORDINATORRuntime predicate evaluation
Unison Effects+1GENERATORGenerates effect traces and fixes

Narya Compatibility

FieldDefinition
before
Initial spec version (e.g., 0618)
after
Target spec version (e.g., 1125)
delta
Semantic diff (strengthened, relaxed, breaking)
birth
Null spec (no predicates)
impact
1 if breaking changes detected

Condensation Policy

Trigger: When 3 incompatible predicates are detected.

Action: Generate migration guide, emit counterexamples, mark as BREAKING.

Invariant Sets

Inv_0618 (June 2024 Spec)

Inv_0618 = {
    "initialize_required": True,
    "tools_list_before_invoke": True,
    "prompt_field_required": False,
    "result_or_error_exclusive": True,
    "capabilities_optional": True,
}

Inv_1125 (November 2025 Spec)

Inv_1125 = {
    "initialize_required": True,
    "tools_list_before_invoke": False,  # BREAKING CHANGE
    "prompt_field_required": True,       # BREAKING CHANGE
    "result_or_error_exclusive": True,
    "capabilities_optional": False,      # BREAKING CHANGE
}

Semantic Diff (Not Text Diff)

from mcp_spec_unified import semantic_diff

diff = semantic_diff(Inv_0618, Inv_1125)
# Output:
# {
#   "breaking": [
#     {"predicate": "tools_list_before_invoke", "0618": True, "1125": False},
#     {"predicate": "prompt_field_required", "0618": False, "1125": True},
#     {"predicate": "capabilities_optional", "0618": True, "1125": False},
#   ],
#   "compatible": [
#     {"predicate": "initialize_required", "value": True},
#     {"predicate": "result_or_error_exclusive", "value": True},
#   ],
#   "gf3_balance": 0  # Sum of predicate trits
# }

Counterexample Generation

When predicates disagree, generate minimal counterexamples:

from mcp_spec_unified import generate_counterexample

# Find minimal message that passes 0618 but fails 1125
counterex = generate_counterexample(
    spec_pass=Inv_0618,
    spec_fail=Inv_1125,
    predicate="prompt_field_required"
)
# Output:
# {
#   "message": {"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "example"}},
#   "0618_result": "PASS",
#   "1125_result": "FAIL: missing required field 'prompt'",
#   "fix": {"params": {"name": "example", "prompt": ""}}
# }

Cross-Validation (All 3 Approaches Must Agree)

from mcp_spec_unified import cross_validate

result = cross_validate(
    message={"jsonrpc": "2.0", "method": "tools/call", ...},
    spec_version="1125"
)
# Output:
# {
#   "narya_types": {"result": "VALID", "trit": -1, "mode": "chk"},
#   "evaluators": {"result": "VALID", "trit": 0, "predicates_passed": 12},
#   "unison_effects": {"result": "VALID", "trit": +1, "effects_handled": ["IO", "Abort"]},
#   "consensus": True,
#   "gf3_sum": 0,
#   "confidence": 1.0
# }

Disagreement Handling

# If approaches disagree, report conflict
result = cross_validate(message, spec_version="1125")
if not result["consensus"]:
    print(f"CONFLICT: {result['conflicts']}")
    # Arbiter (ERGODIC) breaks ties
    final = result["evaluators"]["result"]

CLI Examples

# Compare two spec versions
just mcp-spec-diff 0618 1125

# Validate message against spec
just mcp-spec-check message.json --spec 1125

# Generate counterexamples for all breaking changes
just mcp-spec-counterex 0618 1125

# Cross-validate with all three approaches
just mcp-spec-validate message.json --cross-validate

# Run test trace
just mcp-spec-trace tests/protocol_trace.jsonl

Test Traces

Valid 1125 Trace

{"seq": 1, "direction": "client->server", "message": {"jsonrpc": "2.0", "method": "initialize", "params": {"capabilities": {"tools": true}}}}
{"seq": 2, "direction": "server->client", "message": {"jsonrpc": "2.0", "result": {"serverInfo": {"name": "test"}}}}
{"seq": 3, "direction": "client->server", "message": {"jsonrpc": "2.0", "method": "tools/call", "params": {"name": "example", "prompt": "test"}}}
{"seq": 4, "direction": "server->client", "message": {"jsonrpc": "2.0", "result": {"content": [{"type": "text", "text": "ok"}]}}}

Trace Validation Output

╔═══════════════════════════════════════════════════════════════════╗
║  MCP Spec Checker: Trace Validation                               ║
╚═══════════════════════════════════════════════════════════════════╝

Spec Version: 1125
Trace: tests/protocol_trace.jsonl (4 messages)

─── Narya Types (chk/syn) ───
  Message 1: ✓ chk(initialize) : Request
  Message 2: ✓ syn(result) : Response
  Message 3: ✓ chk(tools/call) : Request
  Message 4: ✓ syn(result) : Response
  Trit: -1

─── Evaluators (GF(3)) ───
  Predicates: 12/12 passed
  Breaking changes: 0
  Trit: 0

─── Unison Effects ───
  Effects handled: [IO, Abort, State]
  Unhandled: []
  Trit: +1

─── Cross-Validation ───
  Consensus: ✓ ALL AGREE
  GF(3) Sum: (-1) + 0 + (+1) = 0 ✓
  
RESULT: VALID

Source Files

FilePurpose
src/mcp_narya_types.pyBidirectional type checking (chk/syn/nosyn)
src/mcp_evaluators.pyGF(3) predicate evaluators
src/mcp_effects.pyUnison-style algebraic effects
src/mcp_spec_predicates.pyPredicate definitions with trit assignments
src/mcp_spec_unified.pyUnified cross-validation engine

Integration with Other Skills

SkillTritIntegration
sheaf-cohomology-1Local-to-global consistency for spec patches
ordered-locale0Directed spec evolution (0618 ≪ 1125)
bisimulation-game-1Verify spec equivalence via game semantics
gay-mcp+1Deterministic test case generation

Narya Type Modes

chk (checking mode):  Given type, check term has it
syn (synthesis mode): Given term, synthesize type
nosyn (no synthesis): Term cannot synthesize (must check)

Applied to MCP:

  • chk(Request)
    : Validate incoming message matches Request schema
  • syn(response)
    : Infer response type from message structure
  • nosyn(partial)
    : Partial messages require explicit type annotation

Skill Name: mcp-spec-checker
Type: Protocol Verification / Semantic Diff
Trit: 0 (ERGODIC - coordinates three approaches)
GF(3): Narya(-1) + Evaluators(0) + Unison(+1) = 0 ✓

Scientific Skill Interleaving

This skill connects to the K-Dense-AI/claude-scientific-skills ecosystem:

Graph Theory

  • networkx [○] via bicomodule
    • Universal graph hub

Bibliography References

  • general
    : 734 citations in bib.duckdb

Cat# Integration

This skill maps to Cat# = Comod(P) as a bicomodule in the equipment structure:

Trit: 0 (ERGODIC)
Home: Prof
Poly Op: ⊗
Kan Role: Adj
Color: #26D826

GF(3) Naturality

The skill participates in triads satisfying:

(-1) + (0) + (+1) ≡ 0 (mod 3)

This ensures compositional coherence in the Cat# equipment structure.