{"id":36281652,"url":"https://github.com/code-wheel/mcp-schema-builder-php","last_synced_at":"2026-01-15T22:11:42.495Z","repository":{"id":331577442,"uuid":"1131372263","full_name":"code-wheel/mcp-schema-builder-php","owner":"code-wheel","description":"Fluent JSON Schema builder for MCP tool definitions","archived":false,"fork":false,"pushed_at":"2026-01-10T06:23:28.000Z","size":49,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-11T13:48:45.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/code-wheel.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-09T22:33:54.000Z","updated_at":"2026-01-10T06:23:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/code-wheel/mcp-schema-builder-php","commit_stats":null,"previous_names":["code-wheel/mcp-schema-builder-php"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/code-wheel/mcp-schema-builder-php","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-wheel%2Fmcp-schema-builder-php","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-wheel%2Fmcp-schema-builder-php/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-wheel%2Fmcp-schema-builder-php/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-wheel%2Fmcp-schema-builder-php/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/code-wheel","download_url":"https://codeload.github.com/code-wheel/mcp-schema-builder-php/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/code-wheel%2Fmcp-schema-builder-php/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28472624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T20:50:13.584Z","status":"ssl_error","status_checked_at":"2026-01-15T20:49:17.379Z","response_time":62,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-11T09:06:00.555Z","updated_at":"2026-01-15T22:11:42.490Z","avatar_url":"https://github.com/code-wheel.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MCP Schema Builder\n\n[![CI](https://github.com/code-wheel/mcp-schema-builder/actions/workflows/ci.yml/badge.svg)](https://github.com/code-wheel/mcp-schema-builder/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/code-wheel/mcp-schema-builder/graph/badge.svg)](https://codecov.io/gh/code-wheel/mcp-schema-builder)\n[![Latest Stable Version](https://poser.pugx.org/code-wheel/mcp-schema-builder/v)](https://packagist.org/packages/code-wheel/mcp-schema-builder)\n[![License](https://poser.pugx.org/code-wheel/mcp-schema-builder/license)](https://packagist.org/packages/code-wheel/mcp-schema-builder)\n\nA fluent JSON Schema builder with validation for MCP (Model Context Protocol) tool definitions. Build type-safe schemas, validate LLM-generated inputs, and use pre-built patterns for common MCP tools.\n\n## Installation\n\n```bash\ncomposer require code-wheel/mcp-schema-builder\n```\n\n## Quick Start\n\n### Building Schemas\n\n```php\nuse CodeWheel\\McpSchemaBuilder\\SchemaBuilder;\n\n$schema = SchemaBuilder::object()\n    -\u003eproperty('name', SchemaBuilder::string()-\u003eminLength(1)-\u003erequired())\n    -\u003eproperty('email', SchemaBuilder::string()-\u003eformat('email')-\u003erequired())\n    -\u003eproperty('age', SchemaBuilder::integer()-\u003eminimum(0)-\u003emaximum(150))\n    -\u003eproperty('role', SchemaBuilder::string()-\u003eenum(['admin', 'user', 'guest'])-\u003edefault('user'))\n    -\u003ebuild();\n```\n\n### Validating Input\n\n```php\nuse CodeWheel\\McpSchemaBuilder\\SchemaValidator;\n\n$validator = new SchemaValidator();\n$result = $validator-\u003evalidate($input, $schema);\n\nif (!$result-\u003eisValid()) {\n    foreach ($result-\u003egetErrors() as $error) {\n        echo \"{$error-\u003epath}: {$error-\u003emessage}\\n\";\n        // \"email: Invalid email format\"\n        // \"age: Value must be \u003e= 0\"\n    }\n\n    // Or convert to ErrorBag for tool responses\n    return $result-\u003etoErrorBag()-\u003etoToolResult();\n}\n```\n\n### MCP Presets\n\n```php\nuse CodeWheel\\McpSchemaBuilder\\McpSchema;\n\n// Common patterns for MCP tools\n$schema = SchemaBuilder::object()\n    -\u003eproperty('node_id', McpSchema::entityId('node'))       // Entity ID with description\n    -\u003eproperty('bundle', McpSchema::machineName())           // Machine name pattern\n    -\u003eproperty('query', McpSchema::searchQuery(2))           // Search with min length\n    -\u003emerge(McpSchema::pagination(50, 100))                  // limit + offset\n    -\u003emerge(McpSchema::sorting(['created', 'title']))        // sort_by + sort_order\n    -\u003ebuild();\n\n// Complete tool schemas\n$listSchema = McpSchema::listToolSchema(\n    filterFields: ['status', 'author'],\n    sortFields: ['created', 'updated', 'title']\n);\n\n$getSchema = McpSchema::getToolSchema('node_id', 'node');\n\n$createSchema = McpSchema::createToolSchema(\n    requiredFields: ['title' =\u003e SchemaBuilder::string(), 'body' =\u003e SchemaBuilder::string()],\n    optionalFields: ['status' =\u003e SchemaBuilder::string()-\u003eenum(['draft', 'published'])]\n);\n\n$deleteSchema = McpSchema::deleteToolSchema('node_id', includeForce: true);\n```\n\n### Schema Composition\n\n```php\n// Reusable schema fragments\n$timestamps = SchemaBuilder::object()\n    -\u003eproperty('created', SchemaBuilder::string()-\u003eformat('date-time'))\n    -\u003eproperty('updated', SchemaBuilder::string()-\u003eformat('date-time'));\n\n$author = SchemaBuilder::object()\n    -\u003eproperty('author_id', SchemaBuilder::string()-\u003erequired())\n    -\u003eproperty('author_name', SchemaBuilder::string());\n\n// Compose into larger schema\n$contentSchema = SchemaBuilder::object()\n    -\u003eproperty('id', SchemaBuilder::string()-\u003erequired())\n    -\u003eproperty('title', SchemaBuilder::string()-\u003erequired())\n    -\u003emerge($timestamps)\n    -\u003emerge($author)\n    -\u003ebuild();\n\n// Extend without modifying original\n$extendedSchema = $timestamps-\u003eextend()\n    -\u003eproperty('deleted', SchemaBuilder::string()-\u003eformat('date-time'))\n    -\u003ebuild();\n```\n\n## Schema Builder API\n\n### String\n\n```php\nSchemaBuilder::string()\n    -\u003edescription('Field description')\n    -\u003eminLength(1)\n    -\u003emaxLength(255)\n    -\u003epattern('^[a-z]+$')\n    -\u003eformat('email')  // email, uri, uuid, date, date-time\n    -\u003eenum(['a', 'b', 'c'])\n    -\u003edefault('a')\n    -\u003enullable()\n    -\u003erequired();\n```\n\n### Integer / Number\n\n```php\nSchemaBuilder::integer()\n    -\u003eminimum(0)\n    -\u003emaximum(100)\n    -\u003eexclusiveMinimum(0)\n    -\u003eexclusiveMaximum(100);\n\nSchemaBuilder::number()\n    -\u003eminimum(0.0)\n    -\u003emaximum(1.0);\n```\n\n### Boolean\n\n```php\nSchemaBuilder::boolean()\n    -\u003edefault(false);\n```\n\n### Array\n\n```php\nSchemaBuilder::array(SchemaBuilder::string())\n    -\u003eminItems(1)\n    -\u003emaxItems(10)\n    -\u003euniqueItems();\n```\n\n### Object\n\n```php\nSchemaBuilder::object()\n    -\u003eproperty('name', SchemaBuilder::string()-\u003erequired())\n    -\u003eproperty('age', SchemaBuilder::integer())\n    -\u003eadditionalProperties(false)\n    -\u003eminProperties(1)\n    -\u003emaxProperties(10);\n```\n\n## MCP Presets Reference\n\n### Identifiers\n\n| Method | Description |\n|--------|-------------|\n| `McpSchema::entityId($type)` | Entity ID (numeric or UUID) |\n| `McpSchema::machineName($desc)` | Machine name pattern `[a-z][a-z0-9_]*` |\n| `McpSchema::uuid()` | UUID format |\n| `McpSchema::slug()` | URL-safe slug |\n\n### Pagination \u0026 Filtering\n\n| Method | Description |\n|--------|-------------|\n| `McpSchema::pagination($default, $max)` | limit + offset properties |\n| `McpSchema::cursorPagination($default)` | limit + cursor properties |\n| `McpSchema::sorting($fields)` | sort_by + sort_order properties |\n| `McpSchema::searchQuery($minLen)` | Search query string |\n| `McpSchema::statusFilter($statuses)` | Status enum filter |\n| `McpSchema::dateRange()` | from + to date properties |\n\n### Content\n\n| Method | Description |\n|--------|-------------|\n| `McpSchema::title($maxLen)` | Title string with length limits |\n| `McpSchema::body($allowHtml)` | Body/content field |\n| `McpSchema::tags()` | Array of tag strings |\n| `McpSchema::metadata()` | Key-value object |\n\n### Complete Tool Schemas\n\n| Method | Description |\n|--------|-------------|\n| `McpSchema::listToolSchema($filters, $sorts)` | List entities with pagination |\n| `McpSchema::getToolSchema($idField, $type)` | Get single entity by ID |\n| `McpSchema::createToolSchema($required, $optional)` | Create entity |\n| `McpSchema::updateToolSchema($idField, $fields)` | Update entity |\n| `McpSchema::deleteToolSchema($idField, $force)` | Delete entity |\n| `McpSchema::confirmation()` | Destructive operation confirmation |\n\n## Validation\n\nThe `SchemaValidator` validates:\n\n- **Type checking**: string, integer, number, boolean, array, object\n- **String constraints**: minLength, maxLength, pattern, format\n- **Number constraints**: minimum, maximum, exclusiveMinimum, exclusiveMaximum\n- **Array constraints**: minItems, maxItems, uniqueItems, items schema\n- **Object constraints**: required properties, additionalProperties\n- **Enum validation**: Value must be in allowed list\n- **Format validation**: email, uri, uuid, date, date-time, ipv4, ipv6\n\n```php\n$validator = new SchemaValidator();\n$result = $validator-\u003evalidate($input, $schema);\n\n$result-\u003eisValid();           // bool\n$result-\u003egetErrors();         // ValidationError[]\n$result-\u003etoErrorBag();        // ErrorBag (from mcp-error-codes)\n```\n\n## Integration with mcp-error-codes\n\n```php\nuse CodeWheel\\McpSchemaBuilder\\SchemaValidator;\nuse CodeWheel\\McpErrorCodes\\ErrorBag;\n\n$validator = new SchemaValidator();\n$result = $validator-\u003evalidate($input, $schema);\n\nif (!$result-\u003eisValid()) {\n    // Convert validation errors to ErrorBag\n    $errorBag = $result-\u003etoErrorBag();\n\n    // Return as MCP tool result\n    return $errorBag-\u003etoToolResult();\n}\n```\n\n## Integration with mcp-tool-gateway\n\n```php\nuse CodeWheel\\McpToolGateway\\Middleware\\ValidatingMiddleware;\nuse CodeWheel\\McpToolGateway\\Middleware\\MiddlewarePipeline;\nuse CodeWheel\\McpSchemaBuilder\\SchemaValidator;\n\n// Automatic validation before tool execution\n$validator = new SchemaValidator();\n$middleware = new ValidatingMiddleware($provider, $validator);\n\n$pipeline = new MiddlewarePipeline($provider);\n$pipeline-\u003eadd($middleware);\n\n// Invalid inputs are rejected before reaching tools\n$result = $pipeline-\u003eexecute('create_user', $input);\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-wheel%2Fmcp-schema-builder-php","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcode-wheel%2Fmcp-schema-builder-php","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcode-wheel%2Fmcp-schema-builder-php/lists"}