作者将产品数据通过 Model Context Protocol 暴露给 AI 代理,用一个下午完成了 ChatGPT/Claude 读取实时产品目录的能力,附完整 Laravel 代码示例。
ChatGPT 和 Claude 正在成为一个真正的流量来源。人们不再用 Google 搜索,而是直接问 AI"我应该在哪里发布我的 SaaS?"如果 AI 无法读取你的数据,你的答案就不会出现在结果里。
所以我给我的发布平台 Noonlaunch 添加了一个 MCP server。现在任何 AI agent 都可以搜索产品目录、获取每周获胜者、查询我精心整理的 333 个发布目录列表,实时访问 https://noonlaunch.com/mcp。整个过程花了一个下午。下面是完整的内容。
Model Context Protocol 是一个标准,允许 AI 客户端(Claude、Cursor 以及越来越多的其他工具)调用你定义的、通过 HTTP 传输的工具。你为每个工具提供名称、描述和输入的 JSON schema,然后由 AI 决定何时调用它们并获得结构化的数据返回。可以把它想象成"API 端点,只不过消费者是语言模型,它通过阅读描述来决定调用什么"。
Laravel 有一个官方包来处理这个:
composer require laravel/mcp
Requires Laravel 12 / PHP 8.2+. I'm on laravel/mcp ^0.9.3.
在 routes/ai.php 中注册一个 server 只需要一行:
use App\Mcp\NoonlaunchServer;
use Laravel\Mcp\Facades\Mcp;
Mcp::web('/mcp', NoonlaunchServer::class)
->middleware('throttle:60,1')
->name('mcp.noonlaunch');
注意这个 throttle。Agent 可能会很热情;rate limiting 不是可选项。
Server 声明它的工具,以及至关重要的 instructions。这些 instructions 是对每个连接的 AI 的提示,所以要把它们当作文档来对待:
#[Name('Noonlaunch')]
#[Version('1.0.0')]
#[Instructions('Noonlaunch is a product launch platform: makers launch products, the community votes, and the weekly top 3 win a badge and a dofollow backlink. Use search-directory to find products, get-weekly-winners for a week\'s launch board... All data is public and read-only.')]
class NoonlaunchServer extends Server
{
protected array $tools = [
SearchDirectory::class,
GetProduct::class,
GetWeeklyWinners::class,
ListLaunchDirectories::class,
];
}
这是搜索工具,做了精简。有两点需要注意:输入通过 Laravel 正常的 validate() 处理,以及 schema 描述是为 AI 读者编写的:
#[Description('Search the Noonlaunch product directory. Returns approved products matching the query, ordered by community votes.')]
class SearchDirectory extends Tool
{
public function handle(Request $request): Response
{
$args = $request->validate([
'query' => ['required', 'string', 'min:2', 'max:100'],
'limit' => ['nullable', 'integer', 'min:1', 'max:25'],
]);
$products = Product::approved()
->where('name', 'like', "%{$args['query']}%")
->orderByDesc('vote_count')
->limit($args['limit'] ?? 10)
->get();
return Response::json($products->map(fn ($p) => [
'name' => $p->name,
'tagline' => $p->tagline,
'votes' => $p->vote_count,
'noonlaunch_url' => route('product.show', $p),
])->values()->all());
}
public function schema(JsonSchema $schema): array
{
return [
'query' => $schema->string()->description('Search term matched against product names, taglines and descriptions.'),
'limit' => $schema->integer()->description('Max results to return (1-25, default 10).'),
];
}
}
在真正实现认证之前,保持只读。我的四个工具只做 SELECT。MCP 端点是一个公共 API;关于暴露 API 的每一条规则都适用,此外你的消费者是一个很容易被说服的机器人。
像对待用户输入一样做验证,因为它就是。AI 构造了参数。min/max 长度、限制上限、查询附近没有原始输入。
在每个 payload 中返回 URL。我在每个产品上都包含 noonlaunch_url。当 AI 引用你的数据时,你希望它链接回你。这是整个增长循环。
空结果应该用文字而不是 []。返回"No products found, try a broader query"教会 agent 合理地重试。空数组什么都教不了它。
添加一个 discovery card。我提供 /.well-known/mcp/server-card.json 来描述 server,这样 agent 和注册表无需阅读我的文档就能找到它。
如果你使用 Claude Code:
claude mcp add --transport http noonlaunch
然后问它"上周 Noonlaunch 上什么获胜了?"
还有别人通过 MCP 暴露他们应用的数据吗?我特别好奇大家在允许写操作方面是什么态度。