Skip to content
Merged
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ jobs:
run: sleep 5

- name: Execute tests
run: ./vendor/bin/testbench package:test --no-coverage
run: composer test
2 changes: 1 addition & 1 deletion src/Actions/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static function indexQuery(RestifyRequest $request, $query)
/**
* The callback used to authorize running the action.
*/
public ?Closure $runCallback;
public ?Closure $runCallback = null;

public function name()
{
Expand Down
4 changes: 2 additions & 2 deletions src/Fields/FieldCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Binaryk\LaravelRestify\Fields;

use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequestable;
use Binaryk\LaravelRestify\Repositories\Repository;
use Illuminate\Http\Request;
use Illuminate\Support\Collection;
Expand Down Expand Up @@ -70,7 +70,7 @@ public function forIndex(RestifyRequest $request, $repository): self
public function forMcpIndex(RestifyRequest $request, $repository): self
{
// If this is an MCP request and repository has fieldsForMcpIndex method
if ($request instanceof McpRequest && method_exists($repository, 'fieldsForMcpIndex')) {
if ($request instanceof McpRequestable && method_exists($repository, 'fieldsForMcpIndex')) {
// Get the MCP-specific fields from the repository
$mcpFields = $repository->fieldsForMcpIndex($request);
$mcpFieldAttributes = collect($mcpFields)->map(fn ($field) => $field->attribute)->toArray();
Expand Down
6 changes: 3 additions & 3 deletions src/Fields/OrganicField.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Binaryk\LaravelRestify\Fields;

use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequestable;
use Binaryk\LaravelRestify\Traits\ProxiesCanSeeToGate;
use Closure;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -101,7 +101,7 @@ public function isShownOnShow(RestifyRequest $request, $repository): bool
}

// Check MCP-specific visibility for MCP requests
if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
return $this->isShownOnMcp($request, $repository);
}

Expand All @@ -124,7 +124,7 @@ public function isShownOnIndex(RestifyRequest $request, $repository): bool
}

// Check MCP-specific visibility for MCP requests
if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
return $this->isShownOnMcp($request, $repository);
}

Expand Down
6 changes: 3 additions & 3 deletions src/Filters/MatchesCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
namespace Binaryk\LaravelRestify\Filters;

use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequestable;
use Binaryk\LaravelRestify\Repositories\Repository;
use Closure;
use Illuminate\Database\Eloquent\Builder;
Expand Down Expand Up @@ -70,11 +70,11 @@ public function inQuery(RestifyRequest $request): self
$value = $request->query($filter->column());
$negatedValue = $request->query("-{$filter->column()}");

if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
$negatedValue = $request->input("-{$filter->column()}");
}

if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
$value = $request->input($filter->column());
}

Expand Down
73 changes: 27 additions & 46 deletions src/Http/Requests/Concerns/DetermineRequestType.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,15 @@
use Binaryk\LaravelRestify\Http\Requests\RepositoryStoreRequest;
use Binaryk\LaravelRestify\Http\Requests\RepositoryUpdateBulkRequest;
use Binaryk\LaravelRestify\Http\Requests\RepositoryUpdateRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpActionRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpDestroyRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpGetterRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpIndexRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpShowRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpStoreBulkRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpStoreRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpUpdateBulkRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpUpdateRequest;

/**
* @mixin RestifyRequest
Expand All @@ -21,11 +29,8 @@ trait DetermineRequestType
{
public function isIndexRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isIndexRequest();
}

return $this instanceof RepositoryIndexRequest;
return $this instanceof RepositoryIndexRequest
|| $this instanceof McpIndexRequest;
}

public function isGlobalRequest(): bool
Expand All @@ -35,73 +40,49 @@ public function isGlobalRequest(): bool

public function isShowRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isShowRequest();
}

return $this instanceof RepositoryShowRequest;
return $this instanceof RepositoryShowRequest
|| $this instanceof McpShowRequest;
}

public function isUpdateRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isUpdateRequest();
}

return $this instanceof RepositoryUpdateRequest;
return $this instanceof RepositoryUpdateRequest
|| $this instanceof McpUpdateRequest;
}

public function isStoreRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isStoreRequest();
}

return $this instanceof RepositoryStoreRequest;
return $this instanceof RepositoryStoreRequest
|| $this instanceof McpStoreRequest;
}

public function isDestroyRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isDestroyRequest();
}

return $this instanceof RepositoryDestroyRequest;
return $this instanceof RepositoryDestroyRequest
|| $this instanceof McpDestroyRequest;
}

public function isStoreBulkRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isStoreBulkRequest();
}

return $this instanceof RepositoryStoreBulkRequest;
return $this instanceof RepositoryStoreBulkRequest
|| $this instanceof McpStoreBulkRequest;
}

public function isUpdateBulkRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isUpdateBulkRequest();
}

return $this instanceof RepositoryUpdateBulkRequest;
return $this instanceof RepositoryUpdateBulkRequest
|| $this instanceof McpUpdateBulkRequest;
}

public function isActionRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isActionRequest();
}

return $this instanceof ActionRequest;
return $this instanceof ActionRequest
|| $this instanceof McpActionRequest;
}

public function isGetterRequest(): bool
{
if ($this instanceof McpRequest) {
return $this->isGetterRequest();
}

return $this instanceof GetterRequest;
return $this instanceof GetterRequest
|| $this instanceof McpGetterRequest;
}
}
4 changes: 3 additions & 1 deletion src/MCP/Requests/McpActionRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpActionRequest extends McpRequest {}
use Binaryk\LaravelRestify\Http\Requests\ActionRequest;

class McpActionRequest extends ActionRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpDestroyRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpDestroyRequest extends McpRequest {}
class McpDestroyRequest extends McpRequest implements McpRequestable {}
4 changes: 3 additions & 1 deletion src/MCP/Requests/McpGetterRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpGetterRequest extends McpRequest {}
use Binaryk\LaravelRestify\Http\Requests\GetterRequest;

class McpGetterRequest extends GetterRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpIndexRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpIndexRequest extends McpRequest {}
class McpIndexRequest extends McpRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;

class McpRequest extends RestifyRequest
class McpRequest extends RestifyRequest implements McpRequestable
{
/**
* Get the MCP tool name from the request payload.
Expand Down
5 changes: 5 additions & 0 deletions src/MCP/Requests/McpRequestable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

namespace Binaryk\LaravelRestify\MCP\Requests;

interface McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpShowRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpShowRequest extends McpRequest {}
class McpShowRequest extends McpRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpStoreBulkRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpStoreBulkRequest extends McpRequest {}
class McpStoreBulkRequest extends McpRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpStoreRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpStoreRequest extends McpRequest {}
class McpStoreRequest extends McpRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpUpdateBulkRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpUpdateBulkRequest extends McpRequest {}
class McpUpdateBulkRequest extends McpRequest implements McpRequestable {}
2 changes: 1 addition & 1 deletion src/MCP/Requests/McpUpdateRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

namespace Binaryk\LaravelRestify\MCP\Requests;

class McpUpdateRequest extends McpRequest {}
class McpUpdateRequest extends McpRequest implements McpRequestable {}
24 changes: 24 additions & 0 deletions src/MCP/Tools/Operations/ActionTool.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,30 @@ public function handle(Request $request): Response
{
$mcpRequest = app(McpActionRequest::class);
$mcpRequest->replace($request->all());
$mcpRequest->merge([
'mcp_repository_key' => $this->repository->uriKey(),
]);

// Parse repositories string to array if provided
if ($mcpRequest->has('repositories') && is_string($mcpRequest->input('repositories'))) {
$repositories = json_decode($mcpRequest->input('repositories'), true) ?? [];
$mcpRequest->merge(['repositories' => $repositories]);
}

// For show actions with single ID, set the route parameter
if ($id = $mcpRequest->input('id')) {
$mcpRequest->setRouteResolver(function () use ($id) {
return new class($id)
{
public function __construct(private $id) {}

public function parameter($key, $default = null)
{
return $key === 'repositoryId' ? $this->id : $default;
}
};
});
}

$result = $this->repository->actionTool($this->action, $mcpRequest);

Expand Down
6 changes: 3 additions & 3 deletions src/Repositories/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
use Binaryk\LaravelRestify\Http\Controllers\RestResponse;
use Binaryk\LaravelRestify\Http\Requests\RepositoryStoreBulkRequest;
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
use Binaryk\LaravelRestify\MCP\Requests\McpRequestable;
use Binaryk\LaravelRestify\Models\Concerns\HasActionLogs;
use Binaryk\LaravelRestify\Models\CreationAware;
use Binaryk\LaravelRestify\Repositories\Concerns\InteractsWithAttachers;
Expand Down Expand Up @@ -288,7 +288,7 @@ public function collectFields(RestifyRequest $request): FieldCollection
$method = 'fields';

// MCP-specific field methods (highest priority)
if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
if ($request->isIndexRequest() && method_exists($this, 'fieldsForMcpIndex')) {
$method = 'fieldsForMcpIndex';
} elseif ($request->isShowRequest() && method_exists($this, 'fieldsForMcpShow')) {
Expand Down Expand Up @@ -575,7 +575,7 @@ public function resolveIndexPivots(RestifyRequest $request): array
*/
public function resolveRelationships($request): array
{
if ($request instanceof McpRequest) {
if ($request instanceof McpRequestable) {
$this->forMcp(get_class($request));
}

Expand Down
Loading