docs(P19MCP1): 落地MCP只读工具链基准与校验脚本
这个提交包含在:
+107
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Validate MCP baseline documents for P19+MCP-1."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
DOC_PATH = ROOT / "docs" / "mcp-tools.md"
|
||||
EXAMPLE_PATH = ROOT / ".mcp.json.example"
|
||||
AGENTS_PATH = ROOT / "AGENTS.md"
|
||||
|
||||
|
||||
def fail(message: str) -> int:
|
||||
print(f"[ERR] {message}")
|
||||
return 1
|
||||
|
||||
|
||||
def require(text: str, needle: str, label: str, errors: list[str]) -> None:
|
||||
if needle not in text:
|
||||
errors.append(f"missing {label}: {needle}")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
errors: list[str] = []
|
||||
|
||||
if not DOC_PATH.exists():
|
||||
errors.append(f"missing file: {DOC_PATH}")
|
||||
if not EXAMPLE_PATH.exists():
|
||||
errors.append(f"missing file: {EXAMPLE_PATH}")
|
||||
if not AGENTS_PATH.exists():
|
||||
errors.append(f"missing file: {AGENTS_PATH}")
|
||||
|
||||
if errors:
|
||||
for error in errors:
|
||||
print(f"[ERR] {error}")
|
||||
return 1
|
||||
|
||||
doc_text = DOC_PATH.read_text(encoding="utf-8")
|
||||
agents_text = AGENTS_PATH.read_text(encoding="utf-8")
|
||||
|
||||
require(doc_text, "## Enabled Servers", "section", errors)
|
||||
require(doc_text, "- `postgres`", "enabled postgres", errors)
|
||||
require(doc_text, "## Candidate Servers (Not Enabled)", "section", errors)
|
||||
require(doc_text, "`github`", "candidate github", errors)
|
||||
require(doc_text, "postgres:query", "tool", errors)
|
||||
require(doc_text, "READ ONLY", "readonly phrase", errors)
|
||||
require(doc_text, "不提交真实密钥/连接串", "secret hygiene", errors)
|
||||
require(doc_text, "github deferred", "github deferred", errors)
|
||||
|
||||
if "docs/mcp-tools.md" not in agents_text:
|
||||
errors.append("AGENTS.md missing docs/mcp-tools.md reference")
|
||||
|
||||
try:
|
||||
example = json.loads(EXAMPLE_PATH.read_text(encoding="utf-8"))
|
||||
except json.JSONDecodeError as exc:
|
||||
errors.append(f"invalid json in .mcp.json.example: {exc}")
|
||||
example = {}
|
||||
|
||||
servers = example.get("mcpServers") if isinstance(example, dict) else None
|
||||
if not isinstance(servers, dict):
|
||||
errors.append(".mcp.json.example missing mcpServers object")
|
||||
else:
|
||||
if set(servers.keys()) != {"postgres"}:
|
||||
errors.append(f".mcp.json.example must contain only postgres server, got: {sorted(servers.keys())}")
|
||||
|
||||
postgres = servers.get("postgres")
|
||||
if not isinstance(postgres, dict):
|
||||
errors.append("postgres server config missing or invalid")
|
||||
else:
|
||||
command = postgres.get("command")
|
||||
args = postgres.get("args")
|
||||
if command != "npx":
|
||||
errors.append(f"postgres command must be npx, got: {command}")
|
||||
if not isinstance(args, list):
|
||||
errors.append("postgres args must be a list")
|
||||
else:
|
||||
flattened = " ".join(str(item) for item in args)
|
||||
if "@modelcontextprotocol/server-postgres" not in flattened:
|
||||
errors.append("postgres args missing official server package")
|
||||
if "<READONLY_USER>" not in flattened:
|
||||
errors.append("postgres args missing readonly user placeholder")
|
||||
if "<PASSWORD>" not in flattened or "<HOST>" not in flattened or "<PORT>" not in flattened or "<DB>" not in flattened:
|
||||
errors.append("postgres args missing connection placeholders")
|
||||
|
||||
example_text_upper = EXAMPLE_PATH.read_text(encoding="utf-8").upper()
|
||||
for forbidden in ["GITHUB", "TOKEN"]:
|
||||
if forbidden in example_text_upper:
|
||||
errors.append(f".mcp.json.example contains forbidden token: {forbidden}")
|
||||
|
||||
if "postgresql://localhost/" in EXAMPLE_PATH.read_text(encoding="utf-8"):
|
||||
errors.append(".mcp.json.example must not contain a concrete localhost connection string")
|
||||
|
||||
if errors:
|
||||
print("[ERR] MCP tools validation failed")
|
||||
for error in errors:
|
||||
print(f" - {error}")
|
||||
return 1
|
||||
|
||||
print("[OK] MCP tools baseline validated (docs/mcp-tools.md, .mcp.json.example, AGENTS.md)")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
在新工单中引用
屏蔽一个用户