Laravel MCP 1.0: tool search cho MCP server

Build một MCP server trong app Laravel, nối vào Claude Desktop, rồi dùng ToolSearch của Laravel MCP 1.0 để chỉ gửi hai tool và giảm token.

Đã duyệt độc lập · cập nhật 20/10/2026 · 18 min

1. Mỗi tool đều tốn token, ở mọi request

Christoph Rumpel mở đầu video bằng một câu thẳng thắn: mỗi tool trên MCP server của bạn đều làm bạn tốn token ở từng request một, kể cả những tool bạn hoàn toàn không dùng tới. Và theo anh, Laravel vừa sửa đúng chuyện đó.

Anh chào "Hello Laravel friends" rồi giới thiệu: Laravel MCP 1.0 vừa ra (tính theo video đăng ngày 20/09/2026), đây là bản stable đầu tiên của package MCP chính thức của Laravel. Theo Laravel, bản này đi kèm một tính năng làm thay đổi cách bạn nên build MCP server của mình. Anh hẹn sẽ quay lại tính năng đó sau, vì trước hết cần hiểu MCP server là gì đã.

Christoph Rumpel nói trước camera, phía sau là logo Laravel phát sáng
Christoph Rumpel ở phần mở đầu, trong phòng có logo Laravel bằng đèn neon và một màn hình hiện chữ Laravel.

2. MCP server là gì

MCP, tức Model Context Protocol, là một chuẩn cho phép các AI tool như Claude nói chuyện với ứng dụng của bạn. Ứng dụng của bạn đưa ra (expose) những thứ gọi là tool, ví dụ "liệt kê tất cả project của ứng dụng này" hay "hãy tạo một đơn hàng mới". Sau đó AI có thể gọi các tool đó, và lời gọi đi qua chính code của bạn.

Anh gợi ý hãy hình dung nó giống một REST API. Khác biệt là thay vì một developer đọc docs của bạn, thì AI đọc. AI nhận toàn bộ phần mô tả (description), rồi tự quyết định nên chạy cái gì. Anh dặn người xem hãy nhớ kỹ điểm này, vì nó sẽ quan trọng ở phần sau của video: AI phải đọc mô tả của mọi tool thì mới chọn được.

AI client(ví dụ Claude) MCP servertool + description Code của app(Laravel) gọi toolkết quả Giống REST API, nhưng người đọc docs là AI, và AI tự chọn tool để chạy
Hình 2.1Mô hình Christoph mô tả: app đưa tool ra qua MCP server, AI đọc description rồi tự quyết định gọi tool nào, và tool chạy chính code của bạn.

3. Use case: một video editor tự viết và các Linear issue

"Nói thế đủ rồi, mình build MCP server của riêng mình thôi." Nhưng trước hết cần một use case tốt, và anh có sẵn một cái: một ứng dụng video editor tự viết của chính anh. Anh nói vui rằng việc mình đang tự làm một video editor thì thật điên rồ, nhưng ngày nay chuyện đó là làm được. Công cụ này giúp anh rất nhiều khi quay video. Nó còn lâu mới xong, nhưng anh đã dùng nó cho vài việc.

Trên màn hình là ứng dụng tên Creditor, chạy ở localhost, trang "Projects" với dòng "Prepare, record and review your episodes in one place". Bên trái là danh sách episode (lúc này có một project là "MCP 1.0", 6 chapter, 5 chapter đã có take). Bên phải là khung "New project", có lựa chọn "Import an episode from Linear".

Trang Projects của ứng dụng Creditor với một project MCP 1.0 và khung New project
Video editor tự viết của Christoph: danh sách episode bên trái, khung tạo project mới bên phải, trong đó có nút nhập một episode từ Linear.

Một trong các tính năng của nó là import, hay tạo mới, một project từ một Linear issue. Anh mở một ví dụ: issue cho video "What's New in Laravel 13.30 (Demo)". Trong issue có rất nhiều thông tin về bản phát hành: các feature anh muốn giới thiệu, những người đóng góp (contributor), trong đó có một người dạo này đang "làm điên cuồng" với các PR, và anh khen đó là công việc tuyệt vời của các contributor. Issue có đủ thông tin về các pull request, về con người, họ có ở trên Twitter hay không, tức mọi thứ anh cần để dựng demo, cần cho nội dung muốn nói trong video, và để cảm ơn đúng người.

Ngoài ra issue còn có một dạng script, với chi tiết cho từng section anh muốn dùng, kèm code example để anh xem lại, v.v. Anh thấy làm được việc này qua Linear thì khá hay.

Rồi anh nghĩ: sẽ hay biết mấy nếu cũng làm được việc này qua Claude Desktop. Tức là trong Claude, anh chỉ cần nói "hãy tạo một project mới cho video What's New này, từ Linear issue cụ thể này". Đây là việc một MCP server làm được, và đó là thứ anh sẽ build trong video.

4. Cài package, publish route và tạo MCP server

Bước đầu tiên là require package Laravel MCP vào project, việc chỉ mất vài giây. Trên terminal, Composer cài xong các package và báo đang dùng phiên bản ^0.9.5 của laravel/mcp. Docs Laravel MCP ghi lệnh cài là composer require laravel/mcp.

Tiếp theo anh cần publish một số asset, cụ thể là phần AI routes. Có một file route riêng cho MCP server, cần có nó thì server mới truy cập được. Trên màn hình anh gõ lệnh bằng alias art vendor:p (art là viết tắt cho php artisan). Trong docs, lệnh này có dạng php artisan vendor:publish --tag=ai-routes, và nó tạo file routes/ai.php.

Sau đó là tạo MCP server. Có một lệnh make mới là make:mcp-server, và anh đặt tên server là VideoEditorServer:

php artisan make:mcp-server VideoEditorServer

Terminal báo "Server [app/Mcp/Servers/VideoEditorServer.php] created successfully." Giờ project có một folder MCP mới chứa server vừa tạo.

Terminal chạy php artisan make:mcp-server VideoEditorServer và bắt đầu gõ make:mcp-tool
Lệnh tạo server thành công, file nằm ở app/Mcp/Servers/VideoEditorServer.php; dòng dưới anh đã bắt đầu gõ lệnh tạo tool.

Mở file server ra, có tên (name), phiên bản (version), một phần instructions mà bạn có thể điền. Và về cơ bản có ba thứ quan trọng: bạn có thể cung cấp tools, resources và prompts. Trong video này anh chỉ dùng tools.

5. Tool đầu tiên: ListProjectsTool

Anh tạo tool bằng lệnh php artisan make:mcp-tool, bắt đầu với một tool để liệt kê, cho phép anh xem mọi project của ứng dụng này ngay trong Claude. Tool tên là ListProjectsTool. Giờ có một folder Tools mới chứa tool này.

Anh đặt description cho tool: "List editor projects", khá đơn giản. Trong method handle, tool cần trả về text, và text đó được gửi tới client, trong trường hợp này là Claude Desktop.

Phần lấy dữ liệu rất thẳng: anh viết một query lấy các project mới nhất, sắp xếp theo mới nhất trước, rồi lấy vài field: id, name, status và linear issue ("tôi nghĩ thế là đủ"). Việc còn lại là trả kết quả về dưới dạng text: anh chỉ gọi toJson là có text, và đó đúng là thứ client muốn nhận làm response.

Method handle của ListProjectsTool query Project rồi trả Response::text
Method handle của ListProjectsTool: query các project mới nhất với vài cột, rồi trả về Response::text với dữ liệu dạng JSON.

Đoạn code trên màn hình (dòng query bị cắt ở mép phải, sau 'status' là cột linear issue anh vừa nói):

public function handle(Request $request): Response
{
    $projects = Project::query()->latest()->get(['id', 'name', 'status', 'li...

    return Response::text($projects->toJson());
}

Có tool rồi, anh quay lại file server và liệt kê ListProjectsTool trong mảng tools.

6. Đăng ký server local trong routes/ai.php

Tới đây đã có server và có tool. Giờ cần làm cho MCP server có thể truy cập được, và việc này làm trong file routes/ai.php, nơi bạn công khai MCP server. Có vài cách khác nhau: qua web, hoặc local. Trong trường hợp của anh là server local.

Chọn cách nào còn tùy client bạn dùng: Claude Code CLI, Codex CLI hay app desktop chính. Anh khuyên kiểm tra cách thêm MCP server của đúng ứng dụng bạn đang dùng. Còn nếu dùng local thì làm như anh. Anh đặt tên cho server, chỉ đơn giản là video editor, rồi truyền vào class server tên VideoEditorServer.

File routes/ai.php với use Laravel\Mcp\Facades\Mcp và dòng Mcp::local
File routes/ai.php lúc anh bắt đầu sửa: dòng Mcp::local ban đầu còn trỏ tới một server mẫu, anh thay bằng tên video editor và class VideoEditorServer.

Theo docs Laravel MCP, một server local được đăng ký bằng Mcp::local('weather', WeatherServer::class);, tức tên server trước, class server sau. Sau đó anh chạy Pint cho code gọn gàng: "Pint vui, mọi người đều vui."

7. Nối MCP server vào Claude Desktop

Đến lúc báo cho Claude biết có MCP server mới. Lại có nhiều cách. Anh làm thế này: trong Claude Desktop vào phần Developer trong settings, mở config và sửa nó (màn hình "Local MCP servers" có nút "Edit config"). File config đã có sẵn, anh cần chỉnh phần mcpServers, và anh đã chuẩn bị trước.

Server tên video-editor. Lệnh chạy là PHP: "command": "/opt/homebrew/bin/php". Các argument gồm đường dẫn tới file artisan của project, rồi mcp:start, rồi tên MCP server video-editor. Tức là chạy php artisan mcp:start để khởi động MCP server. Bạn có thể tự chạy lệnh đó trong terminal, nhưng ở đây nó được chạy bên trong app Claude.

File claude_desktop_config.json với mục mcpServers video-editor, command php và args mcp:start
Mục video-editor trong claude_desktop_config.json: command trỏ tới PHP, args là file artisan của project, mcp:start và tên server.

Docs Laravel MCP cũng nói điều tương tự: khi server đã được đăng ký, thường bạn không cần tự chạy mcp:start, mà cấu hình MCP client để nó tự khởi động server.

8. Thử lần đầu: liệt kê project từ Claude

Việc còn lại là khởi động lại Claude. "Giờ với một chút may mắn, đi thôi." Trong mục Connectors, phần đã kết nối, giờ thấy có video editor, anh khen khá hay. Server đã kết nối, giờ phải chắc là nó chạy được.

Anh gõ vào Claude:

Good morning. Please show me all the projects that I have in my custom video editor.

Lẽ ra Claude giờ dùng được một tool từ MCP server của anh. Đúng vậy, tool hiện ra là List Projects Tool. Anh bấm cho phép (allow), và hy vọng nhận được kết quả. Có kết quả: Claude trả lời rằng anh đang có một project trong video editor là "MCP 1.0", chính là video hiện có trong ứng dụng.

Claude Desktop trả lời có một project MCP 1.0 sau khi dùng video-editor integration
Câu trả lời của Claude sau dòng "Loaded tools, used video-editor integration": hiện có một project là MCP 1.0.

Vậy là, theo anh, thật tuyệt khi đã tạo xong một MCP server và nối nó với Claude Desktop. Đã có một tool, và đã dùng được app Claude Desktop để nói chuyện với ứng dụng thông qua MCP server. MCP là như vậy đó.

9. Tool thứ hai và Linear MCP server

Nhưng tất nhiên đó chưa phải thứ anh muốn. Anh muốn tạo một project từ một Linear issue. Nên anh tạo thêm một MCP tool, đặt tên là CreateProjectFromLinearIssueTool, rồi dán vào một tool anh đã chuẩn bị sẵn.

Tool có tên create_project_from_linear_issue và description bắt đầu bằng "Creates a new video project from a Linear issue identifier such a...", tức "tạo một video project mới từ một mã Linear issue", kèm một mã ví dụ để AI hiểu cách dùng. Bên trong, anh dùng vài class đã có sẵn trong ứng dụng để import một issue, một Linear issue, v.v. Có vài thứ diễn ra để luồng này chạy được.

File CreateProjectFromLinearIssueTool.php với các use và attribute Name, Description
Đầu file CreateProjectFromLinearIssueTool: các class import Linear issue có sẵn trong app, các class của Laravel MCP, và hai attribute Name và Description của tool.

Phần cuối của method trên màn hình trả về một Response::text gồm câu "Created project ... from ..." và một link tới trang studio của project đó (route studio.show với trang prepare).

Quay lại Claude Desktop, anh nghĩ thế là đủ, thậm chí không cần khởi động lại. Nhưng trước khi thử, anh muốn cho thấy Linear MCP server cũng đã được tích hợp sẵn. Anh hỏi Claude cho xem Linear issue đứng tên anh, tên là "What's New 13.30 Demo", và chỉ cần cho thấy có issue với mã đó. Claude dùng tool list issues và tìm thấy issue.

Như vậy giờ có hai MCP server khác nhau đang bật: một cho Linear, chịu trách nhiệm lấy một Linear issue cụ thể; và một của chính anh, chịu trách nhiệm tạo project mới dựa trên thông tin có trong Linear issue. Anh nói đây là chỗ bắt đầu thú vị.

Claude Desktop Linear MCP server1. tìm và lấy issue Video editor MCP server2. create_project_from_linear_issue
Hình 9.1Hai MCP server cùng làm việc: Linear MCP server lấy issue, MCP server tự viết dùng mã issue đó để tạo project.

10. Chạy cả luồng qua hai MCP server

Anh thử cả luồng: "hãy dùng Linear issue What's New in Laravel 13.30 này để tạo một project mới trong video editor của tôi, dựa trên Linear issue này." Nhưng Claude chỉ thấy có tool list projects. Anh nhận ra: "Ồ, đúng rồi." Quay lại file server, anh đã quên liệt kê tool mới CreateProjectFromLinearIssueTool vào mảng tools.

Sửa xong, anh hỏi lại:

Please grab the linear issue What's New 13.30 Demo from Linear, and please use it in order to create a new project in my video editor based on this issue.

Lần này Claude phải lấy Linear issue trước. Đúng vậy: Claude chạy list issues để tìm, nghĩa là Linear MCP server đang được dùng để tìm issue. Tìm thấy rồi. Tiếp theo Claude hỏi anh có cho phép dùng tool create project from linear issue với issue cụ thể này không. Anh đồng ý.

Claude báo đã tìm thấy MENG-635 và đã tạo project mới kèm Studio link
Claude báo tìm thấy issue MENG-635 "What's New in Laravel 13.30 (Demo)", rồi dùng video-editor integration tạo project và đưa link tới studio.

"Done": Claude báo đã kéo Linear issue về và dùng nó để tạo một project mới, có cả link. Trên màn hình Claude còn tóm tắt rằng issue có đủ script (intro, queue worker stop output, Collection::chunkBy(), dev command opt-outs, outro), gợi ý tiêu đề và mô tả YouTube, bản nháp bài đăng mạng xã hội, nên các chapter của project được dựng theo cấu trúc script đó. Có vẻ nó đã chạy được.

11. Kết quả trong video editor

Anh mở ra xem. Trong danh sách giờ có hai project: "What's New in Laravel 13.30 (Demo)" (Version 13.30, 7 chapter, chưa có take) và "MCP 1.0".

Trang Projects giờ có hai project: What's New in Laravel 13.30 (Demo) và MCP 1.0
Project mới do Claude tạo xuất hiện trong video editor, với version 13.30 và 7 chapter.

Đây là trạng thái "prepare". Có một loạt chapter được tạo dựa trên script trong Linear issue, và mỗi chapter có ghi chú riêng. Ví dụ ở phần intro, anh ghi rằng mình không được quên cảm ơn một contributor. Ở một demo khác có vài ví dụ về cách tính năng chạy, những gì anh muốn nhắc trong video. Rất nhiều chi tiết anh cần trong lúc quay các demo đó.

Trang Prepare của project mới với danh sách chapter Intro, Animated intro, Better queue worker stop output, Collection Chunk
Tab Prepare: cột Episode order liệt kê các chapter (Intro, Animated intro, Better queue worker stop output, Collection Chunk, Dev command opt-outs...), giữa là chapter script, bên phải là chi tiết chapter.

Và nó đã chạy. Anh hỏi: có hay không khi giờ ta dùng được thứ như Claude Desktop để nói chuyện với một ứng dụng và làm một việc mà bình thường sẽ mất nhiều thời gian hơn? Nhất là khi bạn vốn đã dùng các ứng dụng như Claude Desktop, thì rất hợp lý khi tạo một MCP server dễ dàng để làm được nhiều hơn nữa.

Đó là MCP, và tới đây chưa có gì mới lắm liên quan tới bản 1.0. Giờ anh mới cho xem bản phát hành mới có gì.

12. Nhiều tool hơn và MCP Inspector

Anh bỏ các thay đổi vừa làm và chuyển sang một branch khác đã chuẩn bị sẵn (trên terminal là mcp-final-state). Mở file server, đây là trạng thái có rất nhiều tool cho video editor: ListProjectsTool, SearchProjectsTool, GetProjectTool, CreateProjectFromLinearIssueTool, RenameProjectTool, SetEpisodeVersionTool, ArchiveProjectTool, RestoreProjectTool và còn nữa. Anh nói khi nghĩ kỹ, một ứng dụng như thế sẽ có rất nhiều tool.

VideoEditorServer với defaultPaginationLength 50 và mảng tools dài
VideoEditorServer trên branch đã chuẩn bị: mảng $tools liệt kê thẳng từng tool một, mọi tool đều được quảng bá cho AI.

Rồi anh quay lại terminal. Có một lệnh MCP inspector, cần truyền vào tên MCP server. Lần đầu anh gõ thiếu tên và bị báo lỗi "Not enough arguments (missing: "handle")."; lần sau anh thêm tên server:

php artisan mcp:inspector video-editor

Lệnh này khởi động một ứng dụng mới cho thêm thông tin về MCP server: MCP Inspector (trên màn hình là bản v1.0.2). Anh bấm connect, vào tab Tools, bấm List Tools. Một lời gọi được gửi đi để lấy mọi tool, và danh sách toàn bộ tool hiện ra.

Kéo xuống phần history là request "đưa tôi mọi tool" và response từ MCP server. Response này gồm mọi tool với name, title, description, schema, v.v. Và đây là rất nhiều thông tin.

Khi MCP server được nối vào một client như Claude Desktop, chừng đó thông tin được gửi đi mỗi lần. Vì với mỗi tin nhắn đều có khả năng ta cần một thứ từ MCP server, nên client Claude Desktop cần biết về mọi tool hiện có. Thế thì ổn nếu chỉ có hai tool. Nhưng nếu có 18 tool ở đây, thêm vài tool khác và các MCP server khác, thì là rất nhiều.

Tin nhắn mới Gửi kèm mỗi lần: name, title, description, schema tool 1tool 2tool 3 ...tool 18+ MCP server khác kể cả các tool không dùng tới
Hình 12.1Vấn đề Christoph chỉ ra: client cần biết mọi tool để có thể gọi khi cần, nên toàn bộ định nghĩa tool đi theo từng tin nhắn.

13. ToolSearch: chỉ còn hai tool, search và execute

Anh kể nhóm đã nghĩ cách sửa chuyện này và tìm ra một giải pháp mà anh thấy rất hay. Trong mảng tools giờ có một tool mới là class ToolSearch. Gán cho nó một mảng, và cho mọi tool khác vào mảng đó. Anh kéo các tool xuống dưới, chạy Pint cho code gọn. Vậy là toàn bộ tool giờ được liệt kê dưới một tool duy nhất này.

Christoph gõ Server\Tools\ToolSearch::class lên đầu mảng tools
Anh gõ Server\Tools\ToolSearch::class vào đầu mảng $tools; ngay sau đó các tool còn lại được đưa vào trong mảng của ToolSearch.

Dạng code theo docs Laravel MCP (mục "Searchable Tool Catalogs"), với ví dụ server thời tiết của docs:

protected array $tools = [
    CurrentWeatherTool::class,

    ToolSearch::class => [
        HistoricalWeatherTool::class,
        WeatherAlertsTool::class,
    ],
];

Để cho thấy khác biệt, anh khởi động lại inspector, refresh mọi thứ, connect lại, vào Tools và gọi List Tools. "Nhìn này": giờ các tool duy nhất có sẵn là search tools và execute tools. Trong request cũng thấy thứ duy nhất được gửi tới client giờ là hai tool đó. Theo anh như vậy rất hay, vì cần ít token hơn hẳn để gửi so với trước.

Giờ các AI agent có hai tool để dùng: tìm một tool cụ thể, và nếu tìm thấy tool cần chạy thì execute nó. Anh nói "cái này giờ nhanh hơn trước rất nhiều", rồi tự sửa: không phải nhanh hơn, mà rẻ hơn trước rất nhiều, vì nó tiết kiệm cho bạn rất nhiều token, và đây là một ý tưởng khá thông minh.

Docs Laravel MCP mô tả: một searchable catalog đưa ra hai tool, search_tools tìm trong catalog theo tên tool, description và input schema; execute_tools gọi một hoặc nhiều tool trả về từ một lần search. Tool nào để ngoài ToolSearch (như CurrentWeatherTool trong ví dụ) vẫn được quảng bá trực tiếp như cũ.

Trước: tools/list gửi mọi toolSau: chỉ hai tool được gửi list_projectssearch_projects get_projectcreate_project... rename_projectarchive_project restore_project... 18 tool search_toolsexecute_tools Catalog ToolSearchtool chỉ được nạp khi AI tìm tới
Hình 13.1Trước và sau khi dùng ToolSearch: client chỉ còn thấy search_tools và execute_tools; các tool thật nằm trong catalog và được tìm, rồi chạy, khi cần.

14. Linear MCP server: 79 tool và con số 90%

Anh còn cho xem một điểm thú vị khác. Trong Claude Desktop, vào phần extension và connectors, mở Linear connector đang dùng. Nhìn vào đó thấy có 40 read-only tools, "nhưng chưa hết": còn "chỉ" 39 write/delete tools. Nghĩa là riêng Linear MCP server đã có khoảng 80 tool (trên màn hình là 40 cộng 39, số liệu theo video đăng ngày 20/09/2026). Anh chắc rằng nếu nhìn vào mọi MCP server bạn đang kết nối, sẽ có cả đống tool trong đó.

Trang Linear connector trong Claude Desktop với Read-only tools 40 và Write/delete tools 39
Phần Tool permissions của Linear connector trong Claude Desktop: 40 read-only tools và 39 write/delete tools.

Vì vậy, nếu tiết kiệm được như cách họ làm với bản Laravel MCP 1.0, thì đây là chỗ tính năng thật sự tỏa sáng. Anh kể đã tự tính riêng cho Linear MCP server: theo phép tính của anh, bạn có thể tiết kiệm khoảng 90% token nếu dùng cách như trong video. Anh gọi đó là khá ấn tượng.

15. Tóm tắt lại

Anh tổng kết những gì đã làm:

  • Build một MCP server vào một ứng dụng Laravel. Tool là các class, gần giống controller, nhưng ở đây là cho AI.
  • Claude dùng nó để tạo một video project thật từ một Linear issue thật, điều mà anh thấy khá hay.
  • Rồi tới tính năng lớn của bản 1.0: catalog. Server chỉ đưa ra hai tool, để search và để execute, và AI chỉ nạp tool khi thật sự cần.

Anh nhắc lại ý ở đầu video: mọi thứ bạn quảng bá ra như một tool đều được gửi kèm mỗi request tới AI. Theo đo đạc của nhóm (theo video đăng ngày 20/09/2026), tính năng mới này giúp giảm hơn 90% số token mỗi request.

Anh nói thêm rằng bản 1.1 còn mang theo testing tốt hơn và OAuth flow được gia cố (hardened), mọi thứ có trong release notes, link nằm ở phần mô tả video. Anh mời ai thấy video hữu ích thì bấm like, subscribe, và hẹn gặp lại lần sau.

Nguồn và liên kết 7 nguồn

  1. Tên gốc: Laravel MCP 1.0: Tool Search Is a Game Changer for MCP Servers
  2. Sự kiện: YouTube
  3. Video gốc: https://www.youtube.com/watch?v=IAT4SKeRvQo youtube.com
  4. Kênh YouTube Laravel (Christoph Rumpel): youtube.com/channel/UCfO2GiQwb-cwJTb1CuRSkwg youtube.com
  5. Docs Laravel MCP (cài đặt, publish routes/ai.php, đăng ký server local, tạo tool, MCP Inspector): laravel.com/docs/mcp laravel.com
  6. Docs Laravel MCP, mục Searchable Tool Catalogs (ToolSearch, search_tools, execute_tools): laravel.com/docs/mcp#searchable-tool-catalogs laravel.com
  7. Repo package Laravel MCP trên GitHub (có release notes các bản 1.0.x): github.com/laravel/mcp github.com