Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
name: CI

on:
workflow_dispatch:
push:
branches: [main, master]
pull_request:
Expand Down
83 changes: 83 additions & 0 deletions docs/contracts/scp_antigen_mcp_v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# SCP Antigen MCP contract v1

**Version:** 1.0
**Purpose:** Public specification for the SCP mesh extension MCP server (`antigen_mcp.py`) — antigen transport, shared registry fetch/contribute/apply. Separate from core [scp_mcp_v1.md](scp_mcp_v1.md) to preserve frozen v1.0 core contract.

**Normative:** Tool names and human-gate semantics below. Network I/O tools live here only — not on core `scp_mcp`.

---

## Transport

- MCP over **stdio** (typical `mcp.json` entry `scp-antigen`).
- Server name identifier: `SCP-Antigen` (FastMCP) or equivalent.

---

## Tool groups

### Antigen bundle (P0)

| Tool | Parameters | Human gate | Notes |
|------|------------|------------|-------|
| `scp_antigen_export` | `patterns_json`, `antigen_id`, optional sign fields | — | Build bundle |
| `scp_antigen_verify` | `bundle_json`, `allowlist?`, `require_signature?` | — | No side effects |
| `scp_antigen_import` | `bundle_json`, `allowlist?`, `require_signature?` | Never auto-merges | Quarantine only |
| `scp_antigen_merge` | `bundle_json`, `approve?` default **false** | **`approve=true` required** | Registry merge |
| `scp_antigen_publish` | `bundle_json`, `seckey_hex?`, `relays?`, `dry_run?` | Operator credentials | Nostr kind 30078 |
| `scp_antigen_discover` | `allowlist?`, `relays?`, filters | Empty allowlist fails closed | Metadata only |
| `scp_antigen_fetch` | `url`, `expected_hash`, `allowlist?`, `l402_token?` | No auto-pay on 402 | HTTPS fetch + verify |

### Registry mycelium (R3/R4)

| Tool | Parameters | Human gate | Notes |
|------|------------|------------|-------|
| `scp_fetch_registry` | `source`, `allowlist`, `if_none_match?`, `tls_verify?`, `relays?` | Stages to quarantine only; **`merged` always false** | HTTPS or nostr |
| `scp_contribute_pattern` | `transport`, `patterns_json?`, `raw_content?`, `approve?` default **false**, … | **`approve=true` for publish**; `approve=false` → zero network I/O | R3 contribute |
| `scp_apply_registry_quarantine` | `quarantine_path`, `approve?` default **false** | **`approve=true` for production merge**; dev auto via `SCP_REGISTRY_MERGE_DEV_AUTO=1` | R4 SSOT + projection |

---

## End-to-end mycelium flow (informative)

```text
scp_fetch_registry (antigen_mcp) → quarantine_path
scp_apply_registry_quarantine approve=true (antigen_mcp) → SSOT + ~/.scp/threat_registry_projection.json
scp_registry_summary / scp_inspect (scp_mcp v1.0 + v1.1) → uses updated projection per load order
```

Core inspect load order documented in [scp_mcp_v1.1.md](scp_mcp_v1.1.md).

---

## Environment variables (informative)

| Variable | Purpose |
|----------|---------|
| `SCP_PATTERN_SSOT_PATH` | pattern_record SSOT store |
| `SCP_THREAT_REGISTRY_PATH` | Override registry/projection path |
| `SCP_REGISTRY_MERGE_DEV_AUTO` | Dev-only auto-merge low-risk patterns |
| `SCP_ANTIGEN_RELAYS` | Default nostr relays |
| `NOSTR_SECKEY` | Publish/discover credentials (operator-gated) |

---

## Security invariants

- Fetch stages only; merge is separate apply step
- Contribute two-phase consent: proposal (`approve=false`) then publish (`approve=true`)
- No network tools on core `scp_mcp` v1.0 required set
- Allowlists fail closed when empty where specified

---

## Verification

- **CONTRACT_HASH:** SHA-256 of this file (UTF-8, LF). Vendored in SCP `docs/contracts/`.
- Implementations SHOULD document tool list parity in release notes.

---

## Changelog

- **v1.0** — Initial antigen mesh contract (SCP-R5 dual-server).
62 changes: 62 additions & 0 deletions docs/contracts/scp_mcp_v1.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# SCP MCP contract v1.1 (optional add-ons)

**Version:** 1.1
**Purpose:** Optional read-only registry introspection tools for the SCP core MCP server (`scp_mcp.py`).
**Requires:** [scp_mcp_v1.md](scp_mcp_v1.md) v1.0 tool surface (all nine required tools MUST remain present).

**Normative:** Tool names, parameters, and JSON shapes below. v1.0-only hosts remain conformant without implementing v1.1.

---

## Transport

Same as v1.0 — MCP over stdio; server identifier `SCP`.

---

## Tools (optional)

| Tool | Parameters | Success return | Error return |
|------|------------|----------------|--------------|
| `scp_registry_summary` | none | JSON `{registry_path, sections}` where `sections` maps top-level registry keys to counts; `registry_path` MAY be redacted unless debug env enabled | JSON `{"error": {"code", "message", "details"?}}` |
| `scp_registry_section` | `section: string`, `max_chars?: int` default 2048 | JSON `{section, excerpt, truncated}` — JSON text excerpt of one allowlisted section | JSON error object |

### Registry resolution (normative)

Threat registry JSON load order for v1.1 tools and inspect:

1. `SCP_THREAT_REGISTRY_PATH` — if set and file exists
2. `~/.scp/threat_registry_projection.json` — if exists (post-merge projection)
3. Packaged `scp_threat_registry.json` — ship default

### `scp_registry_section` constraints

- Section names MUST match `^[a-z_][a-z0-9_]{0,63}$`
- Section MUST be in allowlist (default: packaged registry top-level keys; override via `SCP_REGISTRY_SECTION_ALLOWLIST` comma-separated)
- Effective excerpt cap: `min(max_chars, 4096)`; `max_chars` MUST be ≥ 1
- MUST NOT dump full registry in one call

### Debug metadata

When `SCP_DEBUG_META=1`, `registry_path` in summary responses MAY include resolved filesystem path.

---

## Security invariants

- Read-only — no network I/O, no merge, no publish
- No auto-merge or auto-publish on core pipeline
- v1.0 contract unchanged for existing consumers

---

## Verification

- **CONTRACT_HASH:** SHA-256 of this file (UTF-8, LF). Vendored copy in SCP `docs/contracts/` with hash test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add hash coverage for new contracts

For consumers following the repo's verify-not-trust flow for docs/contracts, this newly added contract is not actually hash-pinned: the existing canonical manifest/generator still list only docs/contracts/scp_mcp_v1.md, and no scp_mcp_v1.1.sha256 check is added. That means verify_canonical_bundle.ps1/release checks can pass while this v1.1 contract drifts, despite this line advertising a CONTRACT_HASH; please add this file to the manifest/generator or provide a dedicated hash file/check, and do the same for the antigen contract added in this commit.

Useful? React with 👍 / 👎.

- v1.0 conformance: all nine v1.0 tools present; v1.1 tools optional extras.

---

## Changelog

- **v1.1** — Optional registry summary/section; registry load order for inspect loop (SCP-R5).
Loading