Laravel MCP 1.0: Searchable Tool Catalogs Explained | Mohamed Said        [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com) [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles  ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

       [  ](https://github.com/EG-Mohamed)       

 [ Home ](https://msaied.com) [ Projects ](https://msaied.com/projects) [ Articles ](https://msaied.com/articles) [ Certificates ](https://msaied.com/certificates) [ Contact ](https://msaied.com#contact-section) 

  [ home ](https://msaied.com)    [ articles ](https://msaied.com/articles)    A Better Way to Build MCP Servers with Laravel: Searchable Tool Catalogs        On this page       1. [  The Problem: Every Tool Loads on Every Request ](#the-problem-every-tool-loads-on-every-request)
2. [  Four Versions, Three Thrown Away ](#four-versions-three-thrown-away)
3. [  Version 1: Eval-Based Code Execution (Tinker) ](#version-1-eval-based-code-execution-tinker)
4. [  Version 2: Adding a Real Sandbox ](#version-2-adding-a-real-sandbox)
5. [  Version 3: A Restricted PHP Dialect ](#version-3-a-restricted-php-dialect)
6. [  Version 4: JSON Batch Format ](#version-4-json-batch-format)
7. [  What Shipped: Searchable Tool Catalogs ](#what-shipped-searchable-tool-catalogs)
8. [  Measured Results ](#measured-results)
9. [  Where This Fits ](#where-this-fits)
10. [  Key Takeaways ](#key-takeaways)

  ![A Better Way to Build MCP Servers with Laravel: Searchable Tool Catalogs](https://cdn.msaied.com/668/32076b03bd740aac38c18657dc86318c.png)

 [  Laravel ](https://msaied.com/articles?category=laravel) [  AI ](https://msaied.com/articles?category=ai)  #Laravel MCP   #MCP Server   #AI Agents   #Tool Catalogs   #PHP   #Laravel 1.0  

 A Better Way to Build MCP Servers with Laravel: Searchable Tool Catalogs 
==========================================================================

     11 Sep 2026      4 min read    ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said  

       Table of contents

  10 sections  

1. [  01   The Problem: Every Tool Loads on Every Request  ](#the-problem-every-tool-loads-on-every-request)
2. [  02   Four Versions, Three Thrown Away  ](#four-versions-three-thrown-away)
3. [  03   Version 1: Eval-Based Code Execution (Tinker)  ](#version-1-eval-based-code-execution-tinker)
4. [  04   Version 2: Adding a Real Sandbox  ](#version-2-adding-a-real-sandbox)
5. [  05   Version 3: A Restricted PHP Dialect  ](#version-3-a-restricted-php-dialect)
6. [  06   Version 4: JSON Batch Format  ](#version-4-json-batch-format)
7. [  07   What Shipped: Searchable Tool Catalogs  ](#what-shipped-searchable-tool-catalogs)
8. [  08   Measured Results  ](#measured-results)
9. [  09   Where This Fits  ](#where-this-fits)
10. [  10   Key Takeaways  ](#key-takeaways)

       The Problem: Every Tool Loads on Every Request
----------------------------------------------

Model Context Protocol (MCP) servers expose tools to AI agents, but there is a hidden cost most developers overlook. Before an agent reads a single user message, the name, description, and full JSON Schema of **every registered tool** is already in the context window. Anthropic's own benchmarks put a 50-tool MCP setup at roughly 72,000 tokens upfront — around 1,000 tokens per tool.

Token cost is only part of the story. On Anthropic's MCP evaluations with large tool libraries, deferring definitions and searching instead moved Opus 4 from 49% to 74% accuracy, and Opus 4.5 from 79.5% to 88.1%. Forty tool descriptions really is forty chances to pick the wrong one.

Four Versions, Three Thrown Away
--------------------------------

Building Laravel MCP 1.0, the author worked through four design iterations before landing on the shipped solution.

### Version 1: Eval-Based Code Execution (Tinker)

The first attempt generated PHP function signatures from tool definitions and ran agent-written code through `eval()`. It worked well in tests — but those tests only exercised expected snippets. Nothing prevented the model from writing arbitrary PHP with full access to the application container, database, and environment. The sandbox was absent.

### Version 2: Adding a Real Sandbox

Cloudflare's Code Mode runs generated JavaScript in V8 isolates. PHP has no equivalent in-process sandbox. Every viable option — containers, Firecracker microVMs, hosted sandboxes like E2B, WASM via Extism — added infrastructure that a Composer package cannot safely impose on thousands of downstream applications.

### Version 3: A Restricted PHP Dialect

Using `nikic/PHP-Parser`, the next attempt parsed agent-written PHP and rejected any AST node outside a small allowlist. Tests passed — because the tests were written against the same spec that defined the allowlist. A model that had never read that spec immediately produced valid PHP constructs (`foreach`, `if`, array appends) that fell outside the subset. A partial language is worse than no language.

### Version 4: JSON Batch Format

Dropping PHP-Parser entirely, the final version switched to a JSON format the executor supported **completely**. No hidden subset, no priors to fight. The model receives a JSON Schema that states exactly what is allowed, and there is no boundary to accidentally cross.

What Shipped: Searchable Tool Catalogs
--------------------------------------

Laravel MCP 1.0 ships two meta-tools: `search_tools` and `execute_tools`. You declare a catalog using `ToolSearch::class` as a key in your server's `$tools` array:

```php
public array $tools = [
    CurrentWeatherTool::class,
    ToolSearch::class => [
        StationReadingsTool::class,
        RainfallForecastTool::class,
        // ... more tools
    ],
];

```

Frequently used tools stay advertised directly. Everything else becomes discoverable on demand. The `tools/list` payload returns three tools instead of forty, regardless of catalog size.

Search is deterministic and lexical — no embeddings required. Exact name matches score highest, followed by terms in the name, description, and serialized input schema. Parameter names count as documentation.

Each call in a batch becomes a real `JsonRpcRequest` routed through `ToolInvoker`, the same class a normal `tools/call` uses. Conditional registration is re-checked at execution time, so a search result is never a capability grant.

Measured Results
----------------

| Tools | Direct (bytes) | Catalog (bytes) | Reduction | |-------|---------------|-----------------|----------| | 10 | 5,843 | 1,431 | 75.5% | | 20 | 11,703 | 1,431 | 87.8% | | 40 | 23,423 | 1,431 | 93.9% | | 100 | 58,585 | 1,431 | 97.6% |

The catalog column does not grow. Every tool added after the first is free at rest. The crossover pays off at as few as 10 tools.

Where This Fits
---------------

There are three points on the spectrum:

- **Advertise every tool directly** — no infrastructure, fine below ~10 tools.
- **Search and batch (what shipped)** — flat payload at any scale, no control flow, nothing to install.
- **Generated code in a sandbox** — full control flow and intermediate filtering, but requires infrastructure to operate.

The middle option is the only one a package can ship with zero installation requirements.

Key Takeaways
-------------

- Tool schema bloat degrades both token efficiency and agent accuracy at scale.
- `search_tools` + `execute_tools` keeps `tools/list` constant regardless of catalog size.
- Lexical search scores parameter names, making them first-class documentation.
- Security is enforced at execution time via `ToolInvoker`, not at search time.
- When your API surface exceeds 10–15 tools, advertising all of them needs justification, not the reverse.
- Tests written by the same author who defined the constraints are not evidence of correctness when a language model is the consumer.

---

Source: [A better way to build MCP servers with Laravel](https://laravel.com/blog/a-better-way-to-build-mcp-servers-with-laravel)

 Found this useful?

          [  ](https://twitter.com/intent/tweet?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fa-better-way-to-build-mcp-servers-with-laravel-searchable-tool-catalogs&text=A+Better+Way+to+Build+MCP+Servers+with+Laravel%3A+Searchable+Tool+Catalogs) [  ](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fmsaied.com%2Farticles%2Fa-better-way-to-build-mcp-servers-with-laravel-searchable-tool-catalogs) 

 Frequently Asked Questions 
----------------------------

  3 questions  

     Q01  Why does loading all MCP tools on every request hurt agent performance?        Every registered tool's name, description, and full JSON Schema enters the context window before the agent reads the user's message. At 50+ tools this can exceed 72,000 tokens upfront, and more definitions mean more chances for the model to select the wrong tool. Anthropic's benchmarks show accuracy dropping significantly as tool count grows. 

      Q02  How does the Laravel MCP searchable tool catalog work?        Two meta-tools — search_tools and execute_tools — are advertised instead of the full catalog. The agent searches lexically (no embeddings) and receives only the schemas it needs. Each execution call is routed through the same ToolInvoker class as a normal tools/call, and conditional registration is re-checked at execution time rather than at search time. 

      Q03  When should I use a tool catalog versus advertising tools directly?        The author's rule of thumb is that past 10–15 tools, advertising all of them is a cost that needs justification. For very small servers where every tool is used on nearly every request, direct advertising is simpler and has no overhead. A mix of both — keeping high-frequency tools advertised while placing the rest in a catalog — is also a valid approach. 

  Continue reading

 More Articles 
---------------

 [ View all    ](https://msaied.com/articles) 

 [ ![Laravel Concurrency Facade and Process Pools for Parallel Work](https://cdn.msaied.com/667/241195c7a202f534b71ced2e321e27b5.png) laravel concurrency performance 

### Laravel Concurrency Facade and Process Pools for Parallel Work

Laravel's Concurrency facade and process pools let you run independent tasks in parallel without reaching for...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 14 Sep 2026     3 min read  

  Read    

 ](https://msaied.com/articles/laravel-concurrency-facade-and-process-pools-for-parallel-work-4) [ ![Job Batching, Chaining, and Catch Callbacks: Reliable Async Workflows in Laravel](https://cdn.msaied.com/666/f8aaa3879dc7efd419291ffa3e0b15c1.png) laravel queues async 

### Job Batching, Chaining, and Catch Callbacks: Reliable Async Workflows in Laravel

Go beyond fire-and-forget jobs. Learn how to compose Laravel job batches, chains, and catch callbacks into rel...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 13 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/job-batching-chaining-and-catch-callbacks-reliable-async-workflows-in-laravel) [ ![Partial Indexes and Covering Indexes in PostgreSQL: A Laravel Developer's Guide](https://cdn.msaied.com/665/ced6904aad758906b6047d70ea25e267.png) postgresql laravel performance 

### Partial Indexes and Covering Indexes in PostgreSQL: A Laravel Developer's Guide

Learn how partial and covering indexes eliminate wasted index space and redundant heap fetches in Laravel apps...

  ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)  Mohamed Said 

 13 Sep 2026     4 min read  

  Read    

 ](https://msaied.com/articles/partial-indexes-and-covering-indexes-in-postgresql-a-laravel-developers-guide-1) 

   [  ![Mohamed Said](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png)   Mohamed Said Laravel Backend Engineer  ](https://msaied.com)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

Explore

- [Home](https://msaied.com)
- [Projects](https://msaied.com/projects)
- [Articles](https://msaied.com/articles)
- [Certificates](https://msaied.com/certificates)
- [Contact](https://msaied.com#contact-section)

Connect

- [   hello@msaied.com ](mailto:hello@msaied.com)
- [   +20 109 461 9204 ](tel:+201094619204)

© 2026 Mohamed Said. All rights reserved.

 [  ](https://github.com/EG-Mohamed) [  ](https://www.linkedin.com/in/msaiedm/) [  ](https://wa.me/201094619204) [  ](mailto:hello@msaied.com) [  ](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
