Skip to content

Commit e37cc22

Browse files
authored
Fix/relatd mcp performance (#648)
* fix: related fields laoded from index * Fix styling * fix: no index in repository * Fix styling * fix: wip * Fix styling * Fix styling * fix: wip --------- Co-authored-by: binaryk <binaryk@users.noreply.github.com>
1 parent c4fcbb3 commit e37cc22

21 files changed

+454
-46
lines changed

src/Eager/Related.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ public function resolveField(Repository $repository): EagerField
6464
{
6565
return $this
6666
->field
67+
->forMcp($repository->isForMcp())
6768
->columns($this->getColumns())
6869
->resolve($repository);
6970
}

src/Eager/RelatedCollection.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Binaryk\LaravelRestify\Fields\MorphToMany;
1212
use Binaryk\LaravelRestify\Filters\SortableFilter;
1313
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
14+
use Binaryk\LaravelRestify\MCP\Concerns\HasMcpTools;
1415
use Binaryk\LaravelRestify\Repositories\Repository;
1516
use Illuminate\Support\Collection;
1617

@@ -97,6 +98,21 @@ public function forIndex(RestifyRequest $request, Repository $repository): self
9798
});
9899
}
99100

101+
public function forMcp(RestifyRequest $request, Repository $repository): self
102+
{
103+
return $this->filter(function (Related $related) {
104+
// If there's an EagerField, check its repository class
105+
if ($related->field && $related->field->repositoryClass) {
106+
return in_array(HasMcpTools::class, class_uses_recursive($related->field->repositoryClass), true);
107+
}
108+
109+
// For string relationships (without EagerField), we need to find the repository
110+
// This happens when relationships are defined as static::$related = ['user']
111+
// We'll allow these through and let the serialization handle the filtering
112+
return true;
113+
});
114+
}
115+
100116
public function inRequest(RestifyRequest $request, Repository $repository): self
101117
{
102118
return $this->filter(function (mixed $repositoryRelatedField, $repositoryRelatedKey) use (
@@ -167,7 +183,8 @@ public function forRequest(RestifyRequest $request, Repository $repository): sel
167183
->authorized($request)
168184
->inRequest($request, $repository)
169185
->when($request->isShowRequest(), fn (self $collection) => $collection->forShow($request, $repository))
170-
->when($request->isIndexRequest(), fn (self $collection) => $collection->forIndex($request, $repository));
186+
->when($request->isIndexRequest(), fn (self $collection) => $collection->forIndex($request, $repository))
187+
->when($repository->isForMcp(), fn (self $collection) => $collection->forIndex($request, $repository));
171188
}
172189

173190
public function unserialized(RestifyRequest $request, Repository $repository)

src/Fields/BelongsToMany.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
use Binaryk\LaravelRestify\Contracts\RestifySearchable;
66
use Binaryk\LaravelRestify\Fields\Concerns\Attachable;
77
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
8+
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
89
use Binaryk\LaravelRestify\Repositories\PivotsCollection;
910
use Binaryk\LaravelRestify\Repositories\Repository;
1011
use Closure;
1112
use Illuminate\Auth\Access\AuthorizationException;
12-
use Illuminate\Http\Request;
1313

1414
class BelongsToMany extends EagerField
1515
{
@@ -51,8 +51,15 @@ public function resolve($repository, $attribute = null)
5151

5252
$this->value = $paginator->map(function ($item) {
5353
try {
54-
return $this->repositoryClass::resolveWith($item)
55-
->allowToShow(app(Request::class))
54+
/**
55+
* @var Repository $repositoryFromClass
56+
*/
57+
$repositoryFromClass = $this->repositoryClass::resolveWith($item);
58+
59+
return $repositoryFromClass
60+
->allowToShow(
61+
$this->isForMcp() ? app(McpRequest::class) : app(RestifyRequest::class)
62+
)
5663
->withPivots(
5764
PivotsCollection::make($this->pivotFields)
5865
->map(fn (Field $field) => clone $field)

src/Fields/EagerField.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Binaryk\LaravelRestify\Filters\RelatedQuery;
66
use Binaryk\LaravelRestify\Http\Requests\RestifyRequest;
7+
use Binaryk\LaravelRestify\MCP\Requests\McpRequest;
78
use Binaryk\LaravelRestify\Repositories\Repository;
89
use Binaryk\LaravelRestify\Restify;
910
use Binaryk\LaravelRestify\Traits\HasColumns;
@@ -30,6 +31,8 @@ class EagerField extends Field
3031

3132
private RelatedQuery $relatedQuery;
3233

34+
public bool $forMcp = false;
35+
3336
public function __construct($attribute, ?string $parentRepository = null)
3437
{
3538
parent::__construct(attribute: $attribute);
@@ -85,7 +88,7 @@ public function resolve($repository, $attribute = null)
8588
$serializableRepository = $this->repositoryClass::resolveWith($relatedModel);
8689

8790
$this->value = $serializableRepository
88-
->allowToShow($repository->request ?? app(Request::class))
91+
->allowToShow($this->isForMcp() ? app(McpRequest::class) : app(RestifyRequest::class))
8992
->columns()
9093
->eager($this);
9194
} catch (AuthorizationException) {
@@ -160,4 +163,22 @@ public function qualifySortable(RestifyRequest $request): ?string
160163

161164
return $table.'.attributes.'.$this->sortableColumn;
162165
}
166+
167+
public function forMcp(bool|callable $forMcp = false): self
168+
{
169+
if (is_callable($forMcp)) {
170+
$this->forMcp = $forMcp();
171+
172+
return $this;
173+
}
174+
175+
$this->forMcp = $forMcp;
176+
177+
return $this;
178+
}
179+
180+
public function isForMcp(): bool
181+
{
182+
return $this->forMcp;
183+
}
163184
}

src/MCP/Concerns/McpActionTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public function actionTool(Action $action, array $arguments, McpActionRequest $a
6363

6464
public static function actionToolSchema(Action $action, ToolInputSchema $schema, McpActionRequest $mcpRequest): void
6565
{
66-
$modelName = class_basename(static::$model);
66+
$modelName = class_basename(static::guessModelClassName());
6767

6868
// Add action-specific validation rules
6969
$actionRules = $action->rules();

src/MCP/Concerns/McpDestroyTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function deleteTool(array $arguments, McpRequest $request): array
2525
public static function destroyToolSchema(ToolInputSchema $schema): void
2626
{
2727
$key = static::uriKey();
28-
$modelName = class_basename(static::$model);
28+
$modelName = class_basename(static::guessModelClassName());
2929

3030
$schema->string('id')
3131
->description("The ID of the $modelName to delete")

src/MCP/Concerns/McpGetterTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function getterTool(Getter $getter, array $arguments, McpGetterRequest $g
5050

5151
public static function getterToolSchema(Getter $getter, ToolInputSchema $schema, McpGetterRequest $mcpRequest): void
5252
{
53-
$modelName = class_basename(static::$model);
53+
$modelName = class_basename(static::guessModelClassName());
5454

5555
// Add getter-specific validation rules if the getter has a rules method
5656
if (method_exists($getter, 'rules')) {

src/MCP/Concerns/McpShowTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public function showTool(array $arguments, McpRequest $request): array
3636

3737
public static function showToolSchema(ToolInputSchema $schema): void
3838
{
39-
$modelName = class_basename(static::$model);
39+
$modelName = class_basename(static::guessModelClassName());
4040

4141
$schema->string('id')
4242
->description("The ID of the $modelName to retrieve")

src/MCP/Concerns/McpStoreTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function storeTool(array $arguments, McpRequest $request): array
2121

2222
public static function storeToolSchema(ToolInputSchema $schema): void
2323
{
24-
$repository = static::resolveWith(app(static::$model));
24+
$repository = static::resolveWith(static::newModel());
2525

2626
$repository->collectFields($request = app(McpRequest::class))
2727
->forStore($request, $repository)

src/MCP/Concerns/McpUpdateTool.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function updateTool(array $arguments, McpRequest $request): array
2525
public static function updateToolSchema(ToolInputSchema $schema): void
2626
{
2727
$key = static::uriKey();
28-
$modelName = class_basename(static::$model);
28+
$modelName = class_basename(static::guessModelClassName());
2929

3030
$schema->string('id')
3131
->description("The ID of the $modelName to update")

0 commit comments

Comments
 (0)