Reference validators for autonomous systems protocols: MCP, A2A, ACE, OCC/OCS/OCP
Project description
Preflight Tools
Reference validators for autonomous systems protocols: MCP, A2A, ACE, OCC/OCS/OCP
Overview
Preflight Tools provides reference implementations for protocol compliance validation across autonomous agent ecosystems. These validators catch common integration issues before deployment, saving hours of debugging.
Supported Protocols
- MCP (Model Context Protocol) - Anthropic's protocol for LLM tool integration
- A2A (Agent-to-Agent) - Peer communication protocol for autonomous agents
- ACE (Autonomic Compliance Ecosystem) - Platform orchestration standards
- OCC/OCS/OCP - (Coming soon) Observability, compliance, and policy protocols
Installation
# Via pip
pip install preflight-tools
# Via Poetry
poetry add preflight-tools
# From source
git clone https://github.com/syzygysys/preflight-tools.git
cd preflight-tools
poetry install
Quick Start
MCP Validation
Validate your MCP server implementation against the specification:
# Validate a tools definition file
mcp-preflight-check validate path/to/tools.py
# Test a running server
mcp-preflight-check test http://localhost:8000
# Full report with verbose output
mcp-preflight-check validate --verbose path/to/tools.py
Example output:
✅ Tool names: All valid [a-zA-Z0-9_-]
✅ Properties schemas: All using objects {}
✅ Content wrappers: All responses properly wrapped
✅ Notification handling: Correctly implemented
✅ JSON-RPC structure: All responses include required fields
❌ Stdout pollution: Found 3 print statements that will break stdio transport
Fix suggestions:
Line 42: Remove print() statement
Line 89: Use logging instead of print()
Line 134: Redirect to stderr
A2A Validation
(Coming soon) Validate Agent-to-Agent protocol implementations:
a2a-preflight-check validate path/to/agent_config.yml
The Six Critical MCP Fixes
This validator is built from real-world debugging of LAP::CORE's MCP integration. See the full story: Debugging the Bridge
1. Tool Name Pattern
Problem: Tool names with dots fail Zod validation
Rule: Must match ^[a-zA-Z0-9_-]{1,64}$
# ❌ FAILS
{"name": "lap.health.ping"}
# ✅ PASSES
{"name": "lap_health_ping"}
2. Properties Schema Type
Problem: Empty properties as [] instead of {}
Rule: JSON Schema requires properties to be an object
# ❌ FAILS
{
"inputSchema": {
"type": "object",
"properties": [] # Wrong type
}
}
# ✅ PASSES
{
"inputSchema": {
"type": "object",
"properties": {} # Correct type
}
}
3. Content Wrapper Structure
Problem: Returning raw data instead of MCP content structure
Rule: All responses must be wrapped
# ❌ FAILS
return {"status": "ok", "value": 42}
# ✅ PASSES
return {
"content": [{
"type": "text",
"text": json.dumps({"status": "ok", "value": 42})
}]
}
4. Notification Handling
Problem: Returning errors for notification requests (no id field)
Rule: Notifications don't expect responses
# ❌ FAILS
async def dispatch(self, request: dict) -> str:
method = request.get("method")
if method not in self.handlers:
return json.dumps({"error": "unknown method"})
# ✅ PASSES
async def dispatch(self, request: dict) -> str:
# Check if this is a notification (no "id" field)
if "id" not in request:
return "" # Silent success
method = request.get("method")
# ... handle request-response
5. Stdout Pollution
Problem: Any output to stdout breaks JSON-RPC stdio transport
Rule: Redirect stderr early, never use print()
# ❌ FAILS - stderr goes to stdout
poetry run mcp-server 2>> /tmp/debug.log
# ✅ PASSES - redirect before Python starts
exec 2>/tmp/debug.log; poetry run mcp-server
In code:
# ❌ NEVER
print("Debug message")
# ✅ ALWAYS
import logging
logging.error("Debug message") # Goes to stderr
6. JSON-RPC Response Structure
Problem: Using exclude_none=True removes required fields when they're None
Rule: JSON-RPC 2.0 requires id and jsonrpc in every response
# ❌ FAILS - removes 'id' when it's None
class JsonRpcResponse(BaseModel):
jsonrpc: str = "2.0"
id: Optional[Any] = None
result: Optional[Any] = None
error: Optional[Dict[str, Any]] = None
def json(self, **kwargs):
return self.model_dump_json(exclude_none=True, **kwargs)
# ✅ PASSES - keeps required fields
class JsonRpcResponse(BaseModel):
jsonrpc: str = "2.0"
id: Optional[Any] = None
result: Optional[Any] = None
error: Optional[Dict[str, Any]] = None
def json(self, **kwargs):
data = self.model_dump()
# Keep id and jsonrpc always, only exclude result/error conditionally
if data.get('error') is not None:
data.pop('result', None)
elif data.get('result') is not None:
data.pop('error', None)
return json.dumps(data)
API Usage
Python API
from preflight_tools.mcp import MCPValidator
validator = MCPValidator()
# Validate a tools file
results = validator.validate_file("path/to/tools.py")
for issue in results.issues:
print(f"{issue.severity}: {issue.message}")
print(f" Fix: {issue.suggestion}")
# Test a running server
results = validator.test_server("http://localhost:8000")
print(f"Protocol version: {results.protocol_version}")
print(f"Tools found: {len(results.tools)}")
Configuration
Create a .preflight.toml in your project root:
[mcp]
strict = true # Fail on warnings
ignore = ["stdout-pollution"] # Skip specific checks
[a2a]
version = "0.1.0"
require_auth = true
Development
# Clone and setup
git clone https://github.com/syzygysys/preflight-tools.git
cd preflight-tools
poetry install
# Run tests
poetry run pytest
# Run validator on itself
poetry run mcp-preflight-check validate src/
# Format and lint
poetry run black src/ tests/
poetry run ruff check src/ tests/
poetry run mypy src/
Architecture
preflight-tools/
├── src/preflight_tools/
│ ├── mcp/ # MCP validation
│ │ ├── validator.py # Core validation logic
│ │ ├── checks.py # Individual check implementations
│ │ └── cli.py # Command-line interface
│ ├── a2a/ # A2A validation (coming soon)
│ └── common/ # Shared utilities
├── tests/
│ ├── test_mcp.py
│ └── fixtures/ # Test cases
└── docs/
└── protocols/ # Protocol specs
Contributing
We welcome contributions! This is a reference implementation for the community.
- Fork the repo
- Create a feature branch
- Add tests for new validators
- Submit a PR with clear description
See CONTRIBUTING.md for details.
Related Projects
- LAP::CORE - LAPI orchestration platform
- ACE Framework - Autonomic Compliance Ecosystem
- MCP Specification - Official MCP docs
References
- Log 14: Debugging the Bridge - The debugging session that inspired this tool
- MCP GitHub Issues - Report MCP bugs here
- SyzygySys Architecture Notebook - More technical deep-dives
License
Apache License 2.0 - See LICENSE for details.
Copyright 2025 SyzygySys
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Email: kevin@syzygysys.com
Built with ❤️ as a gift to the autonomous systems community.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file preflight_tools-0.1.1.tar.gz.
File metadata
- Download URL: preflight_tools-0.1.1.tar.gz
- Upload date:
- Size: 30.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.3 Linux/6.8.0-106-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a008cdd40d17e74a5d0e57b6bc58559d333f01fb454fb94113a3a6a1c3294ce1
|
|
| MD5 |
5efd8a29f414a17542dff4c2f10c7905
|
|
| BLAKE2b-256 |
1a2e985d0cd3f3d24bbef33e8e1cac673467e9339e82b00eef7134f14059bef4
|
File details
Details for the file preflight_tools-0.1.1-py3-none-any.whl.
File metadata
- Download URL: preflight_tools-0.1.1-py3-none-any.whl
- Upload date:
- Size: 39.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/2.3.2 CPython/3.12.3 Linux/6.8.0-106-generic
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c98259e8f7ffe7cf5da904a609ce78577ddf02c5e0d568faed96825c1b6364fd
|
|
| MD5 |
11f249f5057bf8bdcecf78d9dadd561e
|
|
| BLAKE2b-256 |
06c42c82df3f6cd8a3a1c6580a0817f4ce6733188d5fa77d5b0b5f9b06b7d336
|