# Directory Structure
```
├── .gitignore
├── README.md
├── schemas
│ └── README.md
└── server.py
```
# Files
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | # Python
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 | *.so
6 | .Python
7 | build/
8 | develop-eggs/
9 | dist/
10 | downloads/
11 | eggs/
12 | .eggs/
13 | lib/
14 | lib64/
15 | parts/
16 | sdist/
17 | var/
18 | wheels/
19 | *.egg-info/
20 | .installed.cfg
21 | *.egg
22 |
23 | # Virtual Environment
24 | venv/
25 | env/
26 | ENV/
27 |
28 | # IDE files
29 | .idea/
30 | .vscode/
31 | *.swp
32 | *.swo
33 |
34 | # MCP specific
35 | schemas/*.json
36 |
```
--------------------------------------------------------------------------------
/schemas/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # JSON Schemas Directory
2 |
3 | This directory stores JSON schema files created with the MCP server.
4 |
5 | Each schema is saved as a separate JSON file with the schema ID as the filename.
6 |
7 | ## Schema Structure
8 |
9 | Schemas follow the JSON Schema specification and typically include:
10 | - `$id`: Unique identifier for the schema
11 | - `title`: Human-readable name
12 | - `type`: Schema type (object, array, string, etc.)
13 | - `properties`: Property definitions for object schemas
14 | - `required`: List of required properties
15 |
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # JSON Schema MCP Server
2 |
3 | An MCP server that manages JSON schemas and creates instances from them.
4 |
5 | ## Features
6 |
7 | - **Store and retrieve JSON schemas**
8 | - **Create new JSON schemas** with a simple tool
9 | - **Generate instances** from schemas with custom values
10 |
11 | ## Resources
12 |
13 | - `schema://{schema_id}` - Get a specific schema by ID
14 | - `schemas://list` - Get a list of all available schemas
15 |
16 | ## Tools
17 |
18 | - `create_schema` - Create a new JSON schema
19 | - `create_instance` - Create a JSON instance from a schema
20 |
21 | ## Usage
22 |
23 | 1. Install dependencies:
24 | ```
25 | pip install mcp[cli]
26 | ```
27 |
28 | 2. Run the server:
29 | ```
30 | python server.py
31 | ```
32 |
33 | 3. Or install with Claude Desktop:
34 | ```
35 | mcp install server.py
36 | ```
37 |
38 | ## Examples
39 |
40 | ### Creating a Person Schema
41 |
42 | ```
43 | // Create a schema for a person
44 | create_schema(
45 | title="Person",
46 | properties={
47 | "name": {"type": "string"},
48 | "age": {"type": "integer"},
49 | "email": {"type": "string", "format": "email"}
50 | },
51 | required=["name", "email"]
52 | )
53 | ```
54 |
55 | ### Creating an Instance
56 |
57 | ```
58 | // Create a person instance
59 | create_instance(
60 | schema_id="<schema-id-from-previous-step>",
61 | values={
62 | "name": "John Doe",
63 | "age": 30,
64 | "email": "[email protected]"
65 | }
66 | )
67 | ```
68 |
```
--------------------------------------------------------------------------------
/server.py:
--------------------------------------------------------------------------------
```python
1 | from mcp.server.fastmcp import FastMCP
2 | import os
3 | import json
4 | import uuid
5 | from pathlib import Path
6 |
7 | # Create the MCP server
8 | mcp = FastMCP("JSON Schema Server")
9 |
10 | # Set up schemas directory
11 | SCHEMAS_DIR = Path("schemas")
12 | os.makedirs(SCHEMAS_DIR, exist_ok=True)
13 |
14 | # Schema management functions
15 | def get_schema_path(schema_id):
16 | """Get the file path for a schema by ID"""
17 | return SCHEMAS_DIR / f"{schema_id}.json"
18 |
19 | def list_schemas():
20 | """Get list of available schemas"""
21 | schemas = []
22 | for file in SCHEMAS_DIR.glob("*.json"):
23 | schema_id = file.stem
24 | try:
25 | with open(file, "r") as f:
26 | schema = json.load(f)
27 | name = schema.get("title", schema_id)
28 | schemas.append({"id": schema_id, "name": name})
29 | except Exception as e:
30 | print(f"Error reading schema {file}: {e}")
31 | return schemas
32 |
33 | def save_schema(schema):
34 | """Save schema to file, assign ID if needed"""
35 | if schema.get("$id") is None:
36 | schema["$id"] = str(uuid.uuid4())
37 |
38 | schema_id = schema["$id"]
39 | schema_path = get_schema_path(schema_id)
40 |
41 | with open(schema_path, "w") as f:
42 | json.dump(schema, f, indent=2)
43 |
44 | return schema_id
45 |
46 | # Resource: Get a specific schema
47 | @mcp.resource("schema://{schema_id}")
48 | def get_schema(schema_id: str) -> str:
49 | """Get a JSON schema by ID"""
50 | schema_path = get_schema_path(schema_id)
51 |
52 | if not schema_path.exists():
53 | return f"Schema with ID '{schema_id}' not found"
54 |
55 | with open(schema_path, "r") as f:
56 | return f.read()
57 |
58 | # Resource: List all schemas
59 | @mcp.resource("schemas://list")
60 | def get_schemas_list() -> str:
61 | """List all available JSON schemas"""
62 | schemas = list_schemas()
63 | return json.dumps(schemas, indent=2)
64 |
65 | # Tool: Create a new JSON schema
66 | @mcp.tool()
67 | def create_schema(title: str, type: str = "object", properties: dict = None, required: list = None) -> str:
68 | """
69 | Create a new JSON schema
70 |
71 | Args:
72 | title: The title of the schema
73 | type: The type of the schema (object, array, string, number, etc.)
74 | properties: Dictionary of property definitions
75 | required: List of required property names
76 | """
77 | schema = {
78 | "title": title,
79 | "type": type
80 | }
81 |
82 | if properties:
83 | schema["properties"] = properties
84 |
85 | if required:
86 | schema["required"] = required
87 |
88 | schema_id = save_schema(schema)
89 | return f"Schema created with ID: {schema_id}"
90 |
91 | # Tool: Create an instance from a schema
92 | @mcp.tool()
93 | def create_instance(schema_id: str, values: dict = None) -> str:
94 | """
95 | Create a JSON instance based on a schema
96 |
97 | Args:
98 | schema_id: ID of the schema to use
99 | values: Values to populate in the instance
100 | """
101 | schema_path = get_schema_path(schema_id)
102 |
103 | if not schema_path.exists():
104 | return f"Schema with ID '{schema_id}' not found"
105 |
106 | with open(schema_path, "r") as f:
107 | schema = json.load(f)
108 |
109 | # Create a simple instance based on schema
110 | instance = {}
111 |
112 | if schema.get("type") == "object" and schema.get("properties"):
113 | for prop_name, prop_def in schema["properties"].items():
114 | # Use provided value or a default based on type
115 | if values and prop_name in values:
116 | instance[prop_name] = values[prop_name]
117 | else:
118 | # Simple default values based on property type
119 | prop_type = prop_def.get("type", "string")
120 | if prop_type == "string":
121 | instance[prop_name] = ""
122 | elif prop_type == "number" or prop_type == "integer":
123 | instance[prop_name] = 0
124 | elif prop_type == "boolean":
125 | instance[prop_name] = False
126 | elif prop_type == "array":
127 | instance[prop_name] = []
128 | elif prop_type == "object":
129 | instance[prop_name] = {}
130 | # Add other type defaults as needed
131 |
132 | return json.dumps(instance, indent=2)
133 |
134 | # Run the server
135 | if __name__ == "__main__":
136 | mcp.run(transport="stdio")
137 |
```