From 81320dc983e791e5e10d91d4064d4f47d369a8eb Mon Sep 17 00:00:00 2001 From: LittleCoinCoin Date: Wed, 27 Aug 2025 21:14:41 +0900 Subject: [PATCH] feat(schemas): add package schema v1.2.1 with dual entry-point support Introduce schema v1.2.1 which adds dual entry-point configuration (mcp_server + hatch_mcp_server) and enforces that all declared tools exist on the FastMCP server implementation. --- README.md | 4 +- docs/package/examples.md | 44 ++- docs/package/overview.md | 13 +- docs/package/v1.2.1_migration_guide.md | 291 ++++++++++++++++++ package/v1.2.1/hatch_pkg_metadata_schema.json | 224 ++++++++++++++ 5 files changed, 568 insertions(+), 8 deletions(-) create mode 100644 docs/package/v1.2.1_migration_guide.md create mode 100644 package/v1.2.1/hatch_pkg_metadata_schema.json diff --git a/README.md b/README.md index 9a2fe86..efc581b 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ JSON schemas for the CrackingShells organization package ecosystem. This repository contains JSON schemas for validating Hatch metadata: - **Package Schema**: Validates individual package metadata. [Learn More](docs/package/overview.md) - - Latest: `package/v1.2.0/hatch_pkg_metadata_schema.json` - - Versioned: `package/v1.2.0/hatch_pkg_metadata_schema.json` + - Latest: `package/v1.2.1/hatch_pkg_metadata_schema.json` + - Versioned: `package/v1.2.1/hatch_pkg_metadata_schema.json`, `package/v1.2.0/hatch_pkg_metadata_schema.json` - Deprecated: `package/v1.0/hatch_pkg_metadata_schema.json`, `package/v1.1.0/hatch_pkg_metadata_schema.json` - **Registry Schema**: Validates the central package registry. [Learn More](docs/registry/overview.md) diff --git a/docs/package/examples.md b/docs/package/examples.md index e8a88fe..d0653f0 100644 --- a/docs/package/examples.md +++ b/docs/package/examples.md @@ -2,7 +2,49 @@ This document provides examples of valid package metadata files compliant with the Hatch Package Schema. -## Basic Example +## v1.2.1 Dual Entry Point Example + +```json +{ + "$schema": "https://raw.githubusercontent.com/crackingshells/Hatch-Schemas/main/package/v1.2.1/hatch_pkg_metadata_schema.json", + "package_schema_version": "1.2.1", + "name": "arithmetic_package", + "version": "1.3.0", + "description": "A package for arithmetic operations with dual entry points", + "tags": ["math", "arithmetic", "dual-entry"], + "author": { + "name": "John Doe", + "email": "john.doe@example.com" + }, + "license": { + "name": "MIT" + }, + "entry_point": { + "mcp_server": "mcp_arithmetic.py", + "hatch_mcp_server": "hatch_mcp_arithmetic.py" + }, + "tools": [ + {"name": "add", "description": "Add two numbers together."}, + {"name": "subtract", "description": "Subtract one number from another."}, + {"name": "multiply", "description": "Multiply two numbers together."}, + {"name": "divide", "description": "Divide one number by another."} + ], + "dependencies": { + "hatch": [], + "python": [{ + "name": "numpy", "version_constraint": ">=2.2.0", "package_manager": "pip" + }], + "system": [], + "docker": [] + }, + "citations": { + "origin": "John Doe, \"Origin: Example MCP Server for Hatch!\", 2025", + "mcp": "John Doe, \"MCP: Example Arithmetic Tools for Hatch!\", 2025" + } +} +``` + +## Basic Example (v1.2.0) ```json { diff --git a/docs/package/overview.md b/docs/package/overview.md index d57148d..02103d3 100644 --- a/docs/package/overview.md +++ b/docs/package/overview.md @@ -6,7 +6,7 @@ The Package Schema (`hatch_pkg_metadata_schema.json`) defines the structure for ## Current Version -The current version of the Package Schema is **v1.2.0**. +The current version of the Package Schema is **v1.2.1**. ## Schema Structure @@ -18,7 +18,7 @@ The Package Schema includes the following major sections: - **Package Links**: Repository and documentation URLs - **Dependencies**: Hatch, Python, system, and Docker dependencies - **Compatibility Requirements**: Hatchling and Python version constraints -- **Entry Points and Tools**: Primary entry point and additional tools +- **Entry Points and Tools**: Dual entry point configuration (FastMCP server + HatchMCP wrapper) and additional tools For detailed field-by-field documentation including types, formats, and examples, see the [Package Schema Field Reference](fields.md). @@ -43,10 +43,10 @@ For detailed field-by-field documentation including types, formats, and examples ```json { - "package_schema_version": "1.2.0", + "package_schema_version": "1.2.1", "name": "example_package", "version": "1.0.0", - "description": "An example Hatch package", + "description": "An example Hatch package with dual entry points", "tags": ["example", "demo"], "author": { "name": "John Doe", @@ -56,7 +56,10 @@ For detailed field-by-field documentation including types, formats, and examples "name": "MIT", "uri": "https://opensource.org/licenses/MIT" }, - "entry_point": "server.py", + "entry_point": { + "mcp_server": "mcp_server.py", + "hatch_mcp_server": "hatch_mcp_server.py" + }, "dependencies": { "hatch": [ { diff --git a/docs/package/v1.2.1_migration_guide.md b/docs/package/v1.2.1_migration_guide.md new file mode 100644 index 0000000..f2acd0d --- /dev/null +++ b/docs/package/v1.2.1_migration_guide.md @@ -0,0 +1,291 @@ +# Migration Guide: Schema v1.2.0 → v1.2.1 + +## Overview + +Schema version 1.2.1 introduces **dual entry point support** for Hatch packages, enabling packages to declare both a FastMCP server implementation and a HatchMCP wrapper file. This enhancement provides better separation of concerns and ensures tool availability when FastMCP servers are imported independently. + +## Key Changes in v1.2.1 + +### 1. Dual Entry Point Configuration + +**v1.2.0 (Single Entry Point)**: +```json +{ + "package_schema_version": "1.2.0", + "entry_point": "hatch_mcp_server.py" +} +``` + +**v1.2.1 (Dual Entry Point)**: +```json +{ + "package_schema_version": "1.2.1", + "entry_point": { + "mcp_server": "mcp_server.py", + "hatch_mcp_server": "hatch_mcp_server.py" + } +} +``` + +### 2. Tool Enforcement + +In v1.2.1, **ALL tools declared in metadata must exist in the FastMCP server file** with proper `@mcp.tool()` decorators. This ensures: + +- Tools are available when FastMCP server is imported independently +- Consistency across the Cracking Shells ecosystem +- Better external organization compatibility + +## Migration Steps + +### Step 1: Update Package Structure + +If you have a single-file package, split it into dual files: + +**Before (v1.2.0)**: +``` +my_package/ +├── hatch_metadata.json +├── server.py # Single file with everything +└── README.md +``` + +**After (v1.2.1)**: +``` +my_package/ +├── hatch_metadata.json +├── mcp_server.py # FastMCP server implementation +├── hatch_mcp_server.py # HatchMCP wrapper +└── README.md +``` + +### Step 2: Create FastMCP Server File + +Create a dedicated FastMCP server file (`mcp_server.py`): + +```python +import numpy as np +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP("MyPackage", log_level="WARNING") + +@mcp.tool() +def my_tool(param: str) -> str: + """Tool description.""" + return f"Processed: {param}" + +# Add all your tools here with @mcp.tool() decorators + +if __name__ == "__main__": + mcp.run() +``` + +### Step 3: Create HatchMCP Wrapper File + +Create a HatchMCP wrapper file (`hatch_mcp_server.py`): + +```python +from hatch_mcp_server import HatchMCP +from mcp_server import mcp # Import from your FastMCP server + +hatch_mcp = HatchMCP("MyPackage", + fast_mcp=mcp, + origin_citation="Your citation here", + mcp_citation="Your MCP citation here") + +if __name__ == "__main__": + hatch_mcp.server.run() +``` + +### Step 4: Update Metadata + +Update your `hatch_metadata.json`: + +```json +{ + "package_schema_version": "1.2.1", + "name": "my_package", + "version": "2.0.0", + "description": "Updated package with dual entry points", + "entry_point": { + "mcp_server": "mcp_server.py", + "hatch_mcp_server": "hatch_mcp_server.py" + }, + "tools": [ + {"name": "my_tool", "description": "Tool description."} + ] + // ... other fields unchanged +} +``` + +## Complete Migration Example + +### Original v1.2.0 Package + +**hatch_metadata.json**: +```json +{ + "package_schema_version": "1.2.0", + "name": "arithmetic_pkg", + "version": "1.2.0", + "entry_point": "arithmetic.py", + "tools": [ + {"name": "add", "description": "Add two numbers."}, + {"name": "multiply", "description": "Multiply two numbers."} + ] +} +``` + +**arithmetic.py**: +```python +from hatch_mcp_server import HatchMCP + +hatch_mcp = HatchMCP("ArithmeticTools") + +@hatch_mcp.server.tool() +def add(a: float, b: float) -> float: + """Add two numbers together.""" + return a + b + +@hatch_mcp.server.tool() +def multiply(a: float, b: float) -> float: + """Multiply two numbers together.""" + return a * b + +if __name__ == "__main__": + hatch_mcp.server.run() +``` + +### Migrated v1.2.1 Package + +**hatch_metadata.json**: +```json +{ + "package_schema_version": "1.2.1", + "name": "arithmetic_pkg", + "version": "2.0.0", + "entry_point": { + "mcp_server": "mcp_arithmetic.py", + "hatch_mcp_server": "hatch_mcp_arithmetic.py" + }, + "tools": [ + {"name": "add", "description": "Add two numbers."}, + {"name": "multiply", "description": "Multiply two numbers."} + ] +} +``` + +**mcp_arithmetic.py** (FastMCP Server): +```python +from mcp.server.fastmcp import FastMCP + +mcp = FastMCP("ArithmeticTools", log_level="WARNING") + +@mcp.tool() +def add(a: float, b: float) -> float: + """Add two numbers together.""" + return a + b + +@mcp.tool() +def multiply(a: float, b: float) -> float: + """Multiply two numbers together.""" + return a * b + +if __name__ == "__main__": + mcp.run() +``` + +**hatch_mcp_arithmetic.py** (HatchMCP Wrapper): +```python +from hatch_mcp_server import HatchMCP +from mcp_arithmetic import mcp + +hatch_mcp = HatchMCP("ArithmeticTools", + fast_mcp=mcp, + origin_citation="Your origin citation", + mcp_citation="Your MCP citation") + +if __name__ == "__main__": + hatch_mcp.server.run() +``` + +## Validation Requirements + +### Tool Enforcement + +All tools declared in metadata **MUST** exist in the FastMCP server file: + +✅ **Correct**: +```python +# In mcp_server.py +@mcp.tool() +def my_tool(): + """Tool implementation.""" + pass + +# In hatch_metadata.json +"tools": [{"name": "my_tool", "description": "Tool description."}] +``` + +❌ **Incorrect**: +```python +# Tool only in HatchMCP wrapper - will fail validation +@hatch_mcp.server.tool() +def my_tool(): + pass +``` + +### Import Relationship + +The HatchMCP wrapper **MUST** import the `mcp` object from the FastMCP server: + +✅ **Correct**: +```python +from mcp_server import mcp # Correct import +``` + +❌ **Incorrect**: +```python +from other_module import mcp # Wrong module +``` + +## Backward Compatibility + +- **Existing v1.2.0 and v1.1.0 packages continue to work unchanged** +- No breaking changes to existing packages +- Validator chain automatically routes packages to appropriate validators +- Migration to v1.2.1 is optional but recommended for new packages + +## Benefits of Migration + +1. **Better Separation of Concerns**: FastMCP server contains pure business logic +2. **External Compatibility**: Other organizations can import FastMCP servers directly +3. **Tool Availability**: Tools guaranteed to be available when FastMCP server imported +4. **Enhanced Validation**: More comprehensive package validation +5. **Future-Proof**: Better foundation for future enhancements + +## Troubleshooting + +### Common Migration Issues + +**Issue**: Tool validation fails +**Solution**: Ensure all declared tools exist in FastMCP server with `@mcp.tool()` decorators + +**Issue**: Import validation fails +**Solution**: Verify HatchMCP wrapper imports `mcp` from correct FastMCP server file + +**Issue**: Schema validation fails +**Solution**: Ensure `package_schema_version` is exactly `"1.2.1"` and entry point is object format + +### Getting Help + +- Check validation error messages for specific guidance +- Refer to the arithmetic_pkg_1_3_0 reference implementation +- Review the complete examples in this guide + +## Next Steps + +After migration: +1. Test your package thoroughly +2. Update your documentation +3. Consider incrementing your package version to indicate the structural changes +4. Update any CI/CD pipelines to handle the new dual-file structure diff --git a/package/v1.2.1/hatch_pkg_metadata_schema.json b/package/v1.2.1/hatch_pkg_metadata_schema.json new file mode 100644 index 0000000..19892e2 --- /dev/null +++ b/package/v1.2.1/hatch_pkg_metadata_schema.json @@ -0,0 +1,224 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Hatch Package Metadata", + "description": "Schema for Hatch MCP Server package metadata with dual entry point support", + "type": "object", + "required": ["package_schema_version", "name", "version", "entry_point", "description", "tags", "author", "license"], + "properties": { + "package_schema_version": { + "type": "string", + "description": "Version of the schema used for this package metadata", + "pattern": "^1\\.2\\.1$" + }, + "name": { + "type": "string", + "description": "Package identifier", + "pattern": "^[a-z0-9_]+$" + }, + "version": { + "type": "string", + "description": "Semantic version of the package", + "pattern": "^\\d+(\\.\\d+)*$" + }, + "description": { + "type": "string", + "description": "Human-readable description of the package" + }, + "tags": { + "type": "array", + "items": {"type": "string"}, + "description": "Keywords for discovery" + }, + "author": { + "type": "object", + "required": ["name"], + "properties": { + "name": {"type": "string"}, + "email": {"type": "string", "format": "email"} + } + }, + "contributors": { + "type": "array", + "items": { + "type": "object", + "required": ["name"], + "properties": { + "name": {"type": "string"}, + "email": {"type": "string", "format": "email"} + } + } + }, + "license": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "description": "Name of the license" + }, + "uri": { + "type": "string", + "format": "uri", + "description": "URL to the license text. It can point to a file in the package or an external URL." + } + } + }, + "repository": {"type": "string", "format": "uri"}, + "documentation": {"type": "string", "format": "uri"}, + "dependencies": { + "type": "object", + "properties": { + "hatch": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version_constraint"], + "properties": { + "name": { + "type": "string", + "pattern": "^[A-Za-z0-9_\\-./\\\\:]+$", + "description": "Name of the Hatch package. The name can match an absolute or relative path for local packages. If it is a relative path, it is relative to the package's root directory. For remote packages (i.e. Hatch registry), a single name or, to remove ambiguity, the name prepended with the repository name, e.g., ':'." + }, + "version_constraint": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for the Hatch package" + } + } + }, + "description": "Hatch packages required." + }, + "python": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version_constraint"], + "properties": { + "name": { + "type": "string", + "pattern": "^[\\w\\-./\\\\]+$", + "description": "Name of the Python package. The name can match an absolute or relative path to a directory to a local package. If it is a relative path, it is relative to the package's root directory." + }, + "version_constraint": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for the Python package" + }, + "package_manager": { + "type": "string", + "enum": ["pip"], + "default": "pip", + "description": "Package manager to use for installation" + } + } + }, + "description": "Python packages required." + }, + "system": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version_constraint"], + "properties": { + "name": { + "type": "string", + "pattern": "^\\w+$", + "description": "Name of the system package" + }, + "version_constraint": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for the system package" + }, + "package_manager": { + "type": "string", + "enum": ["apt"], + "default": "apt", + "description": "Package manager to use for installation" + } + } + }, + "description": "System packages required." + }, + "docker": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "version_constraint"], + "properties": { + "name": { + "type": "string", + "pattern": "^\\w+$", + "description": "Name of the Docker image" + }, + "version_constraint": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for the Docker image" + }, + "registry": { + "type": "string", + "enum": ["dockerhub"], + "default": "dockerhub", + "description": "Registry to pull the Docker image from" + } + } + }, + "description": "Docker images required." + } + } + }, + "compatibility": { + "type": "object", + "properties": { + "hatchling": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for Hatchling compatibility, e.g., '>=0.1.0'" + }, + "python": { + "type": "string", + "pattern": "^\\s*(==|>=|<=|!=)\\s*\\d+(\\.\\d+)*$", + "description": "Version constraint for Python compatibility, e.g., '>=3.6'" + } + } + }, + "entry_point": { + "type": "object", + "description": "Dual entry point configuration for FastMCP server and HatchMCP wrapper", + "properties": { + "mcp_server": { + "type": "string", + "description": "FastMCP server implementation file", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]*\\.py$" + }, + "hatch_mcp_server": { + "type": "string", + "description": "HatchMCP wrapper file", + "pattern": "^[a-zA-Z0-9_][a-zA-Z0-9_.-]*\\.py$" + } + }, + "required": ["mcp_server", "hatch_mcp_server"], + "additionalProperties": false + }, + "tools": { + "type": "array", + "items": { + "type": "object", + "required": ["name", "description"], + "properties": { + "name": {"type": "string"}, + "description": {"type": "string"} + } + } + }, + "citations": { + "type": "object", + "properties": { + "origin": {"type": "string"}, + "mcp": {"type": "string"} + } + } + }, + "additionalProperties": false +}