Skip to content

Commit 605e8a7

Browse files
committed
fix: wip
1 parent a2cbf3b commit 605e8a7

File tree

3 files changed

+142
-10
lines changed

3 files changed

+142
-10
lines changed

src/Fields/EagerField.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,6 @@ public function resolve($repository, $attribute = null)
8585
*/
8686
$serializableRepository = $this->repositoryClass::resolveWith($relatedModel);
8787

88-
// Only set the request for MCP requests to preserve MCP-specific behavior
89-
// without interfering with regular column selection
90-
if (isset($repository->request) && $repository->request instanceof McpRequest) {
91-
$serializableRepository->request = $repository->request;
92-
}
93-
9488
$this->value = $serializableRepository
9589
->allowToShow($repository->request ?? app(Request::class))
9690
->columns()

src/Repositories/Repository.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ class Repository implements JsonSerializable, RestifySearchable
107107
*/
108108
public Model $resource;
109109

110-
public RestifyRequest $request;
110+
// public RestifyRequest $request;
111111

112112
/**
113113
* The list of relations available for the show or index.
@@ -209,7 +209,6 @@ public function __construct()
209209
{
210210
$this->bootIfNotBooted();
211211
$this->ensureResourceExists();
212-
$this->request = app(RestifyRequest::class);
213212
}
214213

215214
/**
@@ -609,7 +608,7 @@ public function resolveIndexRelationships($request)
609608
public function indexAsArray(RestifyRequest $request): array
610609
{
611610
// Preserve the request instance for the entire flow
612-
$this->request = $request;
611+
// $this->request = $request;
613612

614613
// Check if the model was set under the repository
615614
throw_if(
@@ -628,7 +627,7 @@ public function indexAsArray(RestifyRequest $request): array
628627
$items = $this->indexCollection($request, $paginator->getCollection())->map(function ($value) use ($request) {
629628
$repository = static::resolveWith($value);
630629
// Ensure each resolved repository maintains the original request
631-
$repository->request = $request;
630+
// $repository->request = $request;
632631

633632
return $repository;
634633
})->filter(function (self $repository) use ($request) {

tests/MCP/McpFieldsIntegrationTest.php

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,28 @@
44

55
use Binaryk\LaravelRestify\Fields\Field;
66
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
7+
use Binaryk\LaravelRestify\MCP\Concerns\HasMcpTools;
78
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
9+
use Binaryk\LaravelRestify\MCP\RestifyServer;
810
use Binaryk\LaravelRestify\Repositories\Repository;
11+
use Binaryk\LaravelRestify\Restify;
12+
use Binaryk\LaravelRestify\Tests\Database\Factories\PostFactory;
913
use Binaryk\LaravelRestify\Tests\Fixtures\Post\Post;
1014
use Binaryk\LaravelRestify\Tests\IntegrationTestCase;
15+
use Illuminate\Foundation\Testing\RefreshDatabase;
16+
use Laravel\Mcp\Server\Facades\Mcp;
17+
use Laravel\Mcp\Server\McpServiceProvider;
1118

1219
class McpFieldsIntegrationTest extends IntegrationTestCase
1320
{
21+
use RefreshDatabase;
22+
23+
protected function getPackageProviders($app): array
24+
{
25+
return array_merge(parent::getPackageProviders($app), [
26+
McpServiceProvider::class,
27+
]);
28+
}
1429
public function test_repository_uses_mcp_specific_field_methods(): void
1530
{
1631
$repository = new class extends Repository
@@ -160,4 +175,128 @@ public function fieldsForMcpGetter(RestifyRequest $request): array
160175
$this->assertContains('analytics_data', $mcpGetterFieldNames);
161176
$this->assertContains('performance_metrics', $mcpGetterFieldNames);
162177
}
178+
179+
public function test_mcp_http_integration_uses_mcp_specific_fields(): void
180+
{
181+
// Create test repository with MCP tools enabled
182+
$mcpRepository = new class extends Repository
183+
{
184+
use HasMcpTools;
185+
186+
public static $model = Post::class;
187+
188+
public static string $uriKey = 'test-posts';
189+
190+
public function fields(RestifyRequest $request): array
191+
{
192+
return [
193+
Field::make('title'),
194+
Field::make('description'),
195+
];
196+
}
197+
198+
public function fieldsForMcpIndex(RestifyRequest $request): array
199+
{
200+
return [
201+
Field::make('title'),
202+
Field::make('description'),
203+
Field::make('user_id'),
204+
Field::make('mcp_metadata')->resolveCallback(fn () => 'mcp-specific-data'),
205+
Field::make('internal_tracking')->resolveCallback(fn () => 'internal-123'),
206+
];
207+
}
208+
209+
public function mcpAllowsIndex(): bool
210+
{
211+
return true;
212+
}
213+
};
214+
215+
// Register the repository with Restify
216+
Restify::repositories([
217+
$mcpRepository::class,
218+
]);
219+
220+
// Register MCP server route
221+
Mcp::web('test-restify', RestifyServer::class);
222+
223+
// Create test data
224+
PostFactory::many(2);
225+
226+
// First, get the available tools to verify our tool exists
227+
$toolsListPayload = [
228+
'jsonrpc' => '2.0',
229+
'id' => 1,
230+
'method' => 'tools/list',
231+
'params' => [],
232+
];
233+
234+
$toolsResponse = $this->postJson('/test-restify', $toolsListPayload);
235+
$toolsResponse->assertOk();
236+
237+
$toolsData = $toolsResponse->json();
238+
239+
// Find our expected tool name
240+
$availableTools = collect($toolsData['result']['tools'])->pluck('name')->toArray();
241+
$indexToolName = collect($availableTools)->filter(fn($name) => str_contains($name, 'test-posts') && str_contains($name, 'index'))->first();
242+
243+
$this->assertNotNull($indexToolName, 'Expected test-posts index tool not found. Available tools: ' . implode(', ', $availableTools));
244+
245+
// Create MCP JSON-RPC 2.0 request payload for calling the index tool
246+
$mcpPayload = [
247+
'jsonrpc' => '2.0',
248+
'id' => 2,
249+
'method' => 'tools/call',
250+
'params' => [
251+
'name' => $indexToolName,
252+
'arguments' => [
253+
'perPage' => 10,
254+
],
255+
],
256+
];
257+
258+
// Make HTTP POST request to MCP endpoint
259+
$response = $this->postJson('/test-restify', $mcpPayload);
260+
261+
// Assert successful response
262+
$response->assertOk();
263+
264+
// Get the response data
265+
$responseData = $response->json();
266+
267+
// First check if this is an error response
268+
if (isset($responseData['error'])) {
269+
$this->fail('MCP Error: ' . $responseData['error']['message']);
270+
}
271+
272+
// Assert JSON-RPC response structure
273+
$this->assertArrayHasKey('jsonrpc', $responseData);
274+
$this->assertEquals('2.0', $responseData['jsonrpc']);
275+
$this->assertArrayHasKey('id', $responseData);
276+
$this->assertEquals(2, $responseData['id']);
277+
$this->assertArrayHasKey('result', $responseData);
278+
279+
// Parse the result content (should be JSON string)
280+
$resultContent = json_decode($responseData['result']['content'][0]['text'], true);
281+
282+
// Assert that MCP-specific fields are present in the response
283+
$this->assertArrayHasKey('data', $resultContent);
284+
$this->assertNotEmpty($resultContent['data']);
285+
286+
$firstItem = $resultContent['data'][0];
287+
$this->assertArrayHasKey('attributes', $firstItem);
288+
289+
$attributes = $firstItem['attributes'];
290+
291+
// Assert MCP-specific fields that should only appear in MCP requests
292+
$this->assertArrayHasKey('mcp_metadata', $attributes);
293+
$this->assertArrayHasKey('internal_tracking', $attributes);
294+
$this->assertEquals('mcp-specific-data', $attributes['mcp_metadata']);
295+
$this->assertEquals('internal-123', $attributes['internal_tracking']);
296+
297+
// Assert regular fields are also present
298+
$this->assertArrayHasKey('title', $attributes);
299+
$this->assertArrayHasKey('description', $attributes);
300+
$this->assertArrayHasKey('user_id', $attributes);
301+
}
163302
}

0 commit comments

Comments
 (0)