Skip to main content

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

License Python 3.10+

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.

  1. Fork the repo
  2. Create a feature branch
  3. Add tests for new validators
  4. Submit a PR with clear description

See CONTRIBUTING.md for details.

Related Projects

References

License

Apache License 2.0 - See LICENSE for details.

Copyright 2025 SyzygySys

Support


Built with ❤️ as a gift to the autonomous systems community.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

preflight_tools-0.1.0.tar.gz (30.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

preflight_tools-0.1.0-py3-none-any.whl (39.0 kB view details)

Uploaded Python 3

File details

Details for the file preflight_tools-0.1.0.tar.gz.

File metadata

  • Download URL: preflight_tools-0.1.0.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

Hashes for preflight_tools-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8fdd84a4f6a613ad000a15725b47abc69b2f3211d4e90d0553a5d16ab8f26e8f
MD5 816e843944dd6dcfc86c0e1c670997b2
BLAKE2b-256 1f4f0f88bd15c0bfc7248ca75a0dd3adfc92304628f3d7521e40c9e65404460c

See more details on using hashes here.

File details

Details for the file preflight_tools-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: preflight_tools-0.1.0-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

Hashes for preflight_tools-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f88466ef918d090daad937cbb5afa609076648188bc6ff6efa679135c1ba571b
MD5 f20e4b005db72389698972636e7e5b36
BLAKE2b-256 ead4ecf02549380070036af45ffb56115d082ba049d429fa6c96b16f019e9486

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page