-
Notifications
You must be signed in to change notification settings - Fork 61
Description
Laravel Package Version
0.5.1
Laravel Version
12.43.1
PHP Version
8.4.8
Database Driver & Version
N/A
Description
Explicit Tool Annotations for MCP
Context
While submitting my MCP server as an app to OpenAI
(https://openai.com/index/developers-can-now-submit-apps-to-chatgpt/), I noticed that several tools were being interpreted with incorrect annotations.
Specifically, when annotation attributes are not explicitly defined, OpenAI falls back to default values as described in the MCP documentation:
https://modelcontextprotocol.io/legacy/concepts/tools#available-tool-annotations
This default behavior caused tools to be classified incorrectly during the review process.
Issue
If a Tool class does not explicitly define annotation attributes, OpenAI treats all unspecified annotations as their default values.
In practice, this means properties like destructiveHint default to true, even when the tool is not destructive.
The current documentation explains how to enable annotations (set them to true), but it does not explain how to explicitly set annotations to false.
As a result, there is no obvious or documented way to override default behavior for tools that are safe, read-only, or non–open-world.
This creates ambiguity and leads to incorrect tool classification during MCP inspection and OpenAI app review.
Solution
There are two viable ways to address this:
1. Documentation improvement (upstream)
Update the MCP documentation to explicitly show how to set annotation attributes to false, for example:
#[IsOpenWorld(false)]This would make it clear that annotations are not binary “present or absent”, but configurable, and would prevent incorrect defaults from being inferred.
2. Implementation workaround (what I did)
To avoid relying on implicit defaults, I introduced a BaseTool that explicitly defines all annotation hints as false unless overridden.
All tools extend this base class, ensuring consistent and explicit annotation behavior.
<?php
namespace App\Mcp\Tools;
use Laravel\Mcp\Server\Tool;
abstract class BaseTool extends Tool
{
public function annotations(): array
{
return array_merge([
'readOnlyHint' => false,
'openWorldHint' => false,
'destructiveHint' => false,
'idempotentHint' => false,
], parent::annotations());
}
}This approach removes ambiguity, aligns tool behavior with reality, and avoids accidental misclassification during inspection or review.
Steps To Reproduce
- Create a tool (
php artisan make:mcp-tool ToolName) - Add annotation, something like
#[IsReadOnly] - Add tool to server
- Run
php artisan mcp:inspector MCPServerNameand open MCP Inspector - Click on button Connect
- Click on tab Tools
- Click on List Tools
- Click in panel History on
tools/list - Look as response, expand annotations
- Not set annotations are missing
