Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions src/MCP/Concerns/WrapperToolHelpers.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,34 @@

namespace Binaryk\LaravelRestify\MCP\Concerns;

use Illuminate\JsonSchema\JsonSchemaTypeFactory;

trait WrapperToolHelpers
{
/**
* Format operation schema for display.
*
* Wraps the schema properties in an ObjectType before serialization to properly
* handle required fields and other attributes according to JSON Schema spec.
* This matches how Laravel MCP's Tool::toArray() works.
*/
protected function formatSchemaForDisplay(array $schema): array
{
$formatted = [];

foreach ($schema as $key => $value) {
if (is_object($value) && method_exists($value, 'toArray')) {
$formatted[$key] = $value->toArray();
} else {
$formatted[$key] = $value;
}
}
$schemaFactory = new JsonSchemaTypeFactory;
$objectType = $schemaFactory->object($schema);

return $formatted;
return $objectType->toArray();
}

/**
* Generate examples from operation schema.
*
* After wrapping in ObjectType, the schema has a 'properties' key containing all fields.
*/
protected function generateExamplesFromSchema(array $schema, string $operationType): array
{
$examples = [];
$properties = $schema['properties'] ?? [];

switch ($operationType) {
case 'index':
Expand All @@ -39,7 +41,7 @@ protected function generateExamplesFromSchema(array $schema, string $operationTy
],
];

if (isset($schema['search'])) {
if (isset($properties['search'])) {
$examples[] = [
'description' => 'Search with pagination',
'parameters' => [
Expand All @@ -50,7 +52,7 @@ protected function generateExamplesFromSchema(array $schema, string $operationTy
];
}

if (isset($schema['include'])) {
if (isset($properties['include'])) {
$examples[] = [
'description' => 'With relationships',
'parameters' => [
Expand All @@ -70,7 +72,7 @@ protected function generateExamplesFromSchema(array $schema, string $operationTy
],
];

if (isset($schema['include'])) {
if (isset($properties['include'])) {
$examples[] = [
'description' => 'Show with relationships',
'parameters' => [
Expand All @@ -83,7 +85,7 @@ protected function generateExamplesFromSchema(array $schema, string $operationTy

case 'store':
$exampleParams = [];
foreach ($schema as $key => $field) {
foreach ($properties as $key => $field) {
if ($key === 'include') {
continue;
}
Expand All @@ -101,7 +103,7 @@ protected function generateExamplesFromSchema(array $schema, string $operationTy

case 'update':
$exampleParams = ['id' => '1'];
foreach ($schema as $key => $field) {
foreach ($properties as $key => $field) {
if (in_array($key, ['id', 'include'])) {
continue;
}
Expand Down
14 changes: 9 additions & 5 deletions tests/MCP/WrapperToolsIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -441,11 +441,14 @@ public function mcpAllowsIndex(): bool
$this->assertArrayHasKey('examples', $resultContent);

// Assert schema contains expected fields
// Schema is now wrapped in ObjectType following JSON Schema spec
$schema = $resultContent['schema'];
$this->assertArrayHasKey('page', $schema);
$this->assertArrayHasKey('perPage', $schema);
$this->assertArrayHasKey('search', $schema);
$this->assertArrayHasKey('include', $schema);
$this->assertEquals('object', $schema['type']);
$this->assertArrayHasKey('properties', $schema);
$this->assertArrayHasKey('page', $schema['properties']);
$this->assertArrayHasKey('perPage', $schema['properties']);
$this->assertArrayHasKey('search', $schema['properties']);
$this->assertArrayHasKey('include', $schema['properties']);

// Assert examples are provided
$this->assertNotEmpty($resultContent['examples']);
Expand Down Expand Up @@ -729,7 +732,8 @@ public function mcpAllowsStore(): bool
$detailsResult = json_decode($detailsResponse->json()['result']['content'][0]['text'], true);

$this->assertArrayHasKey('schema', $detailsResult);
$this->assertArrayHasKey('title', $detailsResult['schema']);
// Schema is now wrapped in ObjectType, so check for properties
$this->assertArrayHasKey('properties', $detailsResult['schema']);

// Step 4: Execute the store operation
$executePayload = [
Expand Down
Loading