Skip to content

Commit c0f3c86

Browse files
binarykclaude
andauthored
feat: add MCP wrapper tool system for progressive repository discovery (#683)
* feat: add MCP wrapper tool system for progressive repository discovery Implement a 4-tool wrapper system (inspired by Klavis MCP) that reduces MCP tool explosion by wrapping repository operations through progressive discovery. **New Features:** - Add configurable MCP mode (`direct` or `wrapper`) via `RESTIFY_MCP_MODE` env variable - Create 4 wrapper tools for progressive discovery: - `discover-repositories`: List all MCP-enabled repositories - `get-repository-operations`: Get operations for a specific repository - `get-operation-details`: Get detailed schema for an operation - `execute-operation`: Execute an operation with parameters **Architecture:** - `ToolRegistry` service: Centralized registry for repository/operation metadata with caching - `WrapperToolHelpers` trait: Shared utilities for schema formatting and example generation - Multi-layer validation ensures only MCP-enabled repositories are accessible **Benefits:** - Reduces tool count from 50+ to 4 wrapper tools (in wrapper mode) - Better token efficiency for AI agents - Progressive discovery improves exploration - Backward compatible via config (defaults to `direct` mode) - Static tools remain unaffected regardless of mode **Validation:** - Only repositories with `HasMcpTools` trait are exposed - Each operation validates `mcpAllows*()` permissions - Clear error messages guide missing configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * test: add comprehensive integration tests for MCP wrapper tools Add WrapperToolsIntegrationTest covering all 4 wrapper tools and their functionality. **Tests Added:** - Wrapper mode exposes correct tools (4 wrapper + static tools) - discover-repositories: Lists only MCP-enabled repositories - discover-repositories: Search functionality works correctly - get-repository-operations: Returns complete operations list - get-repository-operations: Rejects non-MCP repositories with clear error - get-operation-details: Returns schema with examples - execute-operation: Creates records via wrapper (store operation) - execute-operation: Lists records via wrapper (index operation) - execute-operation: Validates operation permissions - Complete workflow: Tests entire discover → operations → details → execute flow **Coverage:** - 10 test methods - 74 assertions - Tests all 4 wrapper tools - Tests error handling and validation - Tests end-to-end workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]> * feat: nuno --------- Co-authored-by: Claude <[email protected]>
1 parent 8a26d36 commit c0f3c86

File tree

10 files changed

+2362
-0
lines changed

10 files changed

+2362
-0
lines changed

config/restify.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,27 @@
284284
|
285285
*/
286286
'mcp' => [
287+
/*
288+
|--------------------------------------------------------------------------
289+
| MCP Mode
290+
|--------------------------------------------------------------------------
291+
|
292+
| This setting controls how repository operations are exposed to MCP clients.
293+
|
294+
| - 'direct': Each repository operation (index, show, store, etc.) is
295+
| registered as a separate MCP tool. This provides immediate access to
296+
| all operations but can result in many tools.
297+
|
298+
| - 'wrapper': Repository operations are accessed through 4 wrapper tools
299+
| (discover, get operations, get details, execute). This reduces tool
300+
| count and provides progressive discovery but requires multiple calls.
301+
|
302+
| Static tools (like GlobalSearchTool) are always registered directly
303+
| regardless of this setting.
304+
|
305+
*/
306+
'mode' => env('RESTIFY_MCP_MODE', 'direct'),
307+
287308
'tools' => [
288309
'exclude' => [
289310
// Tool classes to exclude from discovery

docs-v3/content/docs/mcp/mcp.md

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ The MCP integration respects your existing Restify configuration and adds MCP-sp
180180
'server_name' => 'My App MCP Server',
181181
'server_version' => '1.0.0',
182182
'default_pagination' => 25,
183+
'mode' => env('RESTIFY_MCP_MODE', 'direct'), // 'direct' or 'wrapper'
183184
'tools' => [
184185
'exclude' => [
185186
// Tools to exclude from discovery
@@ -190,3 +191,227 @@ The MCP integration respects your existing Restify configuration and adds MCP-sp
190191
],
191192
],
192193
```
194+
195+
## MCP Mode: Direct vs Wrapper
196+
197+
Laravel Restify offers two modes for exposing your repositories through MCP: **Direct Mode** and **Wrapper Mode**. Each mode has different trade-offs in terms of token usage and discoverability.
198+
199+
### Direct Mode (Default)
200+
201+
In direct mode, every repository operation (index, show, store, update, delete) and custom action/getter is exposed as a separate MCP tool. This provides maximum discoverability for AI agents.
202+
203+
**When to use Direct Mode:**
204+
- You have a small number of repositories (< 10)
205+
- You want AI agents to instantly see all available operations
206+
- Token usage is not a concern
207+
- You prefer simpler, more straightforward tool discovery
208+
209+
**Example:** With 10 repositories, each having 5 CRUD operations plus 2 actions, you would expose **70 tools** to the AI agent.
210+
211+
**Configuration:**
212+
```php
213+
// .env
214+
RESTIFY_MCP_MODE=direct
215+
```
216+
217+
### Wrapper Mode (Token-Efficient)
218+
219+
Wrapper mode uses a progressive discovery pattern that exposes only **4 wrapper tools** regardless of how many repositories you have. AI agents discover and execute operations through a multi-step workflow.
220+
221+
**When to use Wrapper Mode:**
222+
- You have many repositories (10+)
223+
- Token usage efficiency is important (e.g., working with large context windows)
224+
- You want to reduce the initial tool list size
225+
- You're building complex applications with dozens of repositories
226+
227+
**Token Savings Example:**
228+
- Direct mode with 50 repositories: ~250+ tools exposed
229+
- Wrapper mode with 50 repositories: **4 tools exposed**
230+
- **Token reduction: ~98% fewer tokens used for tool definitions**
231+
232+
**Configuration:**
233+
```php
234+
// .env
235+
RESTIFY_MCP_MODE=wrapper
236+
```
237+
238+
### The 4 Wrapper Tools
239+
240+
When using wrapper mode, AI agents use these 4 tools in a progressive discovery workflow:
241+
242+
#### 1. `discover-repositories`
243+
Lists all available MCP-enabled repositories with metadata. Supports optional search filtering.
244+
245+
**Example Request:**
246+
```json
247+
{
248+
"search": "user"
249+
}
250+
```
251+
252+
**Example Response:**
253+
```json
254+
{
255+
"success": true,
256+
"repositories": [
257+
{
258+
"name": "users",
259+
"title": "Users",
260+
"description": "Manage user accounts",
261+
"operations": ["index", "show", "store", "update", "delete", "profile"],
262+
"actions_count": 2,
263+
"getters_count": 1
264+
}
265+
]
266+
}
267+
```
268+
269+
#### 2. `get-repository-operations`
270+
Lists all operations, actions, and getters available for a specific repository.
271+
272+
**Example Request:**
273+
```json
274+
{
275+
"repository": "users"
276+
}
277+
```
278+
279+
**Example Response:**
280+
```json
281+
{
282+
"success": true,
283+
"repository": "users",
284+
"crud_operations": ["index", "show", "store", "update", "delete", "profile"],
285+
"actions": [
286+
{
287+
"name": "activate-user",
288+
"title": "Activate User",
289+
"description": "Activate a user account"
290+
}
291+
],
292+
"getters": [
293+
{
294+
"name": "active-users",
295+
"title": "Active Users",
296+
"description": "Get all active users"
297+
}
298+
]
299+
}
300+
```
301+
302+
#### 3. `get-operation-details`
303+
Returns the complete JSON schema and documentation for a specific operation, including all parameters, validation rules, and examples.
304+
305+
**Example Request:**
306+
```json
307+
{
308+
"repository": "users",
309+
"operation_type": "store"
310+
}
311+
```
312+
313+
**Example Response:**
314+
```json
315+
{
316+
"success": true,
317+
"operation": "store",
318+
"type": "create",
319+
"title": "Create User",
320+
"description": "Create a new user account",
321+
"schema": {
322+
"type": "object",
323+
"properties": {
324+
"name": {
325+
"type": "string",
326+
"description": "The user's full name",
327+
"required": true
328+
},
329+
"email": {
330+
"type": "string",
331+
"description": "The user's email address",
332+
"required": true
333+
}
334+
}
335+
},
336+
"examples": [
337+
{
338+
"name": "John Doe",
339+
"email": "[email protected]"
340+
}
341+
]
342+
}
343+
```
344+
345+
#### 4. `execute-operation`
346+
Executes a repository operation with the provided parameters. This is the final step after discovering the repository, listing operations, and getting operation details.
347+
348+
**Example Request:**
349+
```json
350+
{
351+
"repository": "users",
352+
"operation_type": "store",
353+
"parameters": {
354+
"name": "John Doe",
355+
"email": "[email protected]"
356+
}
357+
}
358+
```
359+
360+
**Example Response:**
361+
```json
362+
{
363+
"success": true,
364+
"data": {
365+
"id": 123,
366+
"name": "John Doe",
367+
"email": "[email protected]"
368+
}
369+
}
370+
```
371+
372+
### Wrapper Mode Workflow
373+
374+
Here's a typical workflow when an AI agent uses wrapper mode:
375+
376+
1. **Discover repositories**: Agent calls `discover-repositories` to see what repositories are available
377+
2. **Explore operations**: Agent calls `get-repository-operations` for the target repository
378+
3. **Get schema**: Agent calls `get-operation-details` to understand required parameters
379+
4. **Execute**: Agent calls `execute-operation` with the correct parameters
380+
381+
This progressive discovery pattern reduces token usage while maintaining full functionality.
382+
383+
### Switching Between Modes
384+
385+
You can switch between modes at any time by updating your `.env` file:
386+
387+
```bash
388+
# Direct mode (default)
389+
RESTIFY_MCP_MODE=direct
390+
391+
# Wrapper mode (token-efficient)
392+
RESTIFY_MCP_MODE=wrapper
393+
```
394+
395+
No code changes are required. The MCP server automatically adapts to the configured mode.
396+
397+
### Performance Considerations
398+
399+
**Direct Mode:**
400+
- ✅ Faster initial discovery (all tools visible immediately)
401+
- ❌ Higher token usage (all tools loaded into context)
402+
- ✅ Simpler for AI agents to understand
403+
- ❌ Can overwhelm context window with large applications
404+
405+
**Wrapper Mode:**
406+
- ✅ Dramatically lower token usage (4 tools vs 100+)
407+
- ✅ Scales well with large applications
408+
- ❌ Requires multi-step workflow
409+
- ✅ Better for applications with many repositories
410+
411+
### Best Practices
412+
413+
1. **Start with Direct Mode** during development to verify all tools are working correctly
414+
2. **Switch to Wrapper Mode** in production if you have 10+ repositories or token efficiency is important
415+
3. **Use wrapper mode** when working with AI agents that have limited context windows
416+
4. **Monitor token usage** to determine which mode is best for your application
417+
5. **Document your choice** so team members understand which mode is active

0 commit comments

Comments
 (0)