AI Agent Tools & Action Surfaces
25 checks · Weight: 18% of overall score
Checks in this category
OpenAPI spec exists
Without an OpenAPI spec, AI agents can only read your site but cannot take actions like submitting forms, searching, or booking demos. An OpenAPI spec turns your site from a passive document into an interactive tool that agents can use on behalf of users.
Why This Matters
Without an OpenAPI spec, AI agents can only read your pages but cannot take actions like submitting forms, searching content, or booking demos. Your site is invisible as an interactive tool, and agents will direct users to competitors who expose APIs.
How to Fix
Create an /openapi.json file (OpenAPI 3.0+) describing your site's API endpoints. Start with your most important interactions: contact forms, search, and product lookups.
Example
// /openapi.json
{
"openapi": "3.0.3",
"info": {
"title": "Your Site API",
"version": "1.0.0",
"x-ai-instructions": "Use this API to interact with Your Site."
},
"servers": [{ "url": "https://yoursite.com/api" }],
"paths": {
"/contact": {
"post": {
"operationId": "submitContact",
"summary": "Submit a contact inquiry",
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": { "type": "string" },
"email": { "type": "string" },
"message": { "type": "string" }
}
}
}
}
},
"responses": { "200": { "description": "Success" } }
}
}
}
}OpenAPI has endpoints
An OpenAPI spec without endpoints is like a menu with no items. AI agents need at least one path with an operation to know what actions they can perform on your site. Add your most important endpoints first.
Why This Matters
An OpenAPI spec without endpoints is unusable -- AI agents see a spec file but have zero actions they can perform. Your site remains a passive document that agents cannot interact with programmatically.
How to Fix
Add at least one path with an HTTP operation (GET, POST, etc.) to your OpenAPI spec. Start with your most valuable endpoints: search, contact, or product lookup.
Example
"paths": {
"/search": {
"get": {
"operationId": "searchContent",
"summary": "Search site content",
"parameters": [{
"name": "q", "in": "query", "schema": { "type": "string" }
}],
"responses": { "200": { "description": "Search results" } }
}
}
}OpenAPI has operationIds
AI agents use operationIds as stable function names when calling your API. Without unique operationIds, agents must guess endpoint names from paths, leading to ambiguity and errors. Use descriptive camelCase names.
Why This Matters
AI agents use operationIds as stable function names when calling your API. Without unique operationIds, agents must infer endpoint names from URL paths, leading to ambiguous calls, naming collisions, and broken integrations.
How to Fix
Add a unique, descriptive operationId (camelCase) to every operation in your OpenAPI spec. Use verb-noun format like "searchContent", "submitContactForm", or "getProductDetails".
Example
"paths": {
"/contact": {
"post": {
"operationId": "submitContactForm",
"summary": "Submit a contact inquiry"
}
},
"/search": {
"get": {
"operationId": "searchContent",
"summary": "Search site content"
}
}
}x-ai-instructions in OpenAPI
The x-ai-instructions field lets you give natural-language guidance to AI agents about how to use your API. This is your chance to explain business logic, rate limits, authentication flow, and common use cases in plain English.
Why This Matters
Without x-ai-instructions, AI agents must infer your API's business logic, usage patterns, and constraints from endpoint names alone. This leads to incorrect API usage, violated rate limits, and poor user experiences.
How to Fix
Add an x-ai-instructions string to the info object of your OpenAPI spec. Describe common workflows, rate limits, authentication requirements, and any sequencing constraints in plain English.
Example
"info": {
"title": "Your Site API",
"version": "1.0.0",
"x-ai-instructions": "This API lets you search content, submit contact forms, and retrieve product details. Always call searchContent before submitContact. Rate limit: 10 requests/minute. No authentication required for read endpoints."
}OpenAPI servers array valid
Without a servers array, AI agents do not know the base URL for your API. They cannot construct valid request URLs, rendering the entire spec unusable. Add at least your production server URL.
Why This Matters
Without a servers array, AI agents cannot determine the base URL for your API. Even if your endpoints are perfectly documented, agents cannot construct valid request URLs, rendering the entire OpenAPI spec unusable.
How to Fix
Add a servers array to your OpenAPI spec with at least your production server URL. Include a description for clarity.
Example
"servers": [
{
"url": "https://yoursite.com/api",
"description": "Production server"
}
]OpenAPI request/response schemas
Without request/response schemas, AI agents must guess the data format for your endpoints. This leads to malformed requests and failed API calls. Define JSON schemas for all request bodies and responses.
Why This Matters
Without request/response schemas, AI agents must guess what data to send and what to expect back. This leads to malformed requests, failed API calls, and agents that cannot reliably use your endpoints.
How to Fix
Define JSON Schema for all request bodies (POST/PUT/PATCH) and response bodies in your OpenAPI spec. Include property types, required fields, and format hints (e.g., "format": "email").
Example
"post": {
"operationId": "submitContact",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["email", "message"],
"properties": {
"name": { "type": "string" },
"email": { "type": "string", "format": "email" },
"message": { "type": "string" }
}
}
}
}
},
"responses": {
"200": {
"description": "Success",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": { "type": "boolean" },
"id": { "type": "string" }
}
}
}
}
}
}
}AI Catalog exists
The AI catalog is the central discovery file that tells AI agents what capabilities your site offers. Think of it as a table of contents for your APIs, tools, and services. Without it, agents must probe multiple endpoints to understand what your site can do.
Why This Matters
Without an AI catalog, agents must probe multiple endpoints to discover your services. This wastes time, increases error rates, and often results in agents skipping your site entirely in favor of competitors with clear service listings.
How to Fix
Create a /.well-known/ai-catalog.json file listing your site name, description, capabilities, and a services array with each service's name, description, URL, and type.
Example
// /.well-known/ai-catalog.json
{
"version": "1.0",
"name": "Your Site",
"description": "What your site does",
"capabilities": ["search", "contact", "product-info"],
"services": [
{
"name": "Search",
"description": "Search our content",
"url": "https://yoursite.com/api/search",
"type": "rest"
}
]
}AI Catalog complete metadata
Complete metadata helps AI agents understand who owns the service, when it was last updated, and what it can do. Missing fields reduce agent confidence in your services and may cause them to skip your site in favor of better-documented alternatives.
Why This Matters
Incomplete metadata reduces agent confidence in your services. Agents may skip your site when fields like owner, contact, or lastUpdated are missing because they cannot verify freshness or accountability.
How to Fix
Add all required metadata fields to your ai-catalog.json: version, name, description, capabilities, owner, contact, and lastUpdated.
Example
{
"version": "1.0",
"name": "Your Site",
"description": "Brief description of your site and services",
"capabilities": ["search", "contact", "product-info"],
"owner": "Your Company Name",
"contact": "[email protected]",
"lastUpdated": "2026-01-01",
"services": []
}AI Catalog service URLs valid
Broken service URLs in your AI catalog cause agents to fail when trying to use your services, creating a poor user experience. Verify all URLs are correct, deployed, and returning HTTP 200.
Why This Matters
Broken service URLs in your AI catalog cause agents to fail mid-task. Users who asked the agent to interact with your site get errors instead of results, creating a poor experience and lost business.
How to Fix
Verify every service URL in your ai-catalog.json is deployed, returns HTTP 200, and matches your current production endpoints. Remove or update any stale entries.
Example
"services": [
{
"name": "Search",
"description": "Search site content",
"url": "https://yoursite.com/api/search",
"type": "rest"
}
]agents.json exists
agents.json declares what AI agents can do on your site, including authentication methods, rate limits, and supported protocols. It helps agents self-configure before interacting with your services.
Why This Matters
Without agents.json, AI agents have no way to discover your site's capabilities, authentication requirements, or rate limits. They must probe endpoints blindly, leading to errors and skipped interactions.
How to Fix
Create a /.well-known/agents.json file that declares your site name, supported protocols, authentication method, rate limits, and available endpoints.
Example
// /.well-known/agents.json
{
"name": "Your Site",
"description": "Your site description for AI agents",
"protocols": ["rest", "mcp"],
"authentication": { "type": "none" },
"rate_limits": { "requests_per_minute": 60 },
"endpoints": [
{
"url": "/api/search",
"method": "GET",
"description": "Search content"
}
]
}ai-plugin.json exists
ai-plugin.json is the ChatGPT plugin manifest format. Even if you do not build a ChatGPT plugin, having this file helps AI agents understand your site as a tool with human-readable and model-readable names, logos, and API references.
Why This Matters
ai-plugin.json is the standard manifest used by ChatGPT and other AI platforms to register your site as a tool. Without it, your site cannot be installed as a plugin, and agents lose the human-readable and model-readable names needed for reliable interactions.
How to Fix
Create a /.well-known/ai-plugin.json with at minimum schema_version, name_for_human, name_for_model, description_for_human, description_for_model, auth, and an api reference pointing to your OpenAPI spec.
Example
// /.well-known/ai-plugin.json
{
"schema_version": "v1",
"name_for_human": "Your Site Name",
"name_for_model": "your_site",
"description_for_human": "What your site does for users.",
"description_for_model": "Use this plugin to search content and submit inquiries.",
"auth": { "type": "none" },
"api": {
"type": "openapi",
"url": "https://yoursite.com/openapi.json"
},
"logo_url": "https://yoursite.com/logo.png",
"contact_email": "[email protected]"
}MCP server discovery file
MCP (Model Context Protocol) lets AI assistants like Claude and ChatGPT directly integrate your site as a tool. Publishing an MCP discovery file means users can add your site as a tool in their AI assistant with a single URL, enabling rich interactions beyond simple browsing.
Why This Matters
MCP (Model Context Protocol) is how AI assistants like Claude and ChatGPT register your site as an interactive tool. Without a discovery file, users cannot add your site as an MCP server in their AI assistant, missing out on rich tool-based interactions.
How to Fix
Create a /.well-known/mcp/servers.json file listing your MCP server(s) with name, description, URL, transport type, and capabilities.
Example
// /.well-known/mcp/servers.json
{
"servers": [
{
"name": "Your Site MCP",
"description": "Search content and submit inquiries",
"url": "https://yoursite.com/mcp",
"transport": "streamable-http",
"capabilities": {
"tools": true,
"resources": true
}
}
]
}MCP endpoint functional
Your MCP server must respond to JSON-RPC 2.0 initialize requests for AI assistants to connect. If the endpoint is down or misconfigured, agents cannot use your MCP tools. Verify the server is running and accepts POST requests with Content-Type: application/json.
Why This Matters
If your MCP endpoint does not respond to JSON-RPC 2.0 initialize requests, AI assistants cannot connect to your server at all. Users who try to add your site as a tool will see connection failures, and agents will permanently skip your server.
How to Fix
Ensure your MCP server is running, accepts POST requests with Content-Type: application/json, and correctly handles the JSON-RPC 2.0 "initialize" method by returning a valid response with protocolVersion, serverInfo, and capabilities.
Example
// Expected request:
POST /mcp
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": { "name": "test", "version": "1.0.0" }
}
}
// Expected response:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"serverInfo": { "name": "your-server", "version": "1.0.0" },
"capabilities": { "tools": {} }
}
}MCP server advertises capabilities
Without declared capabilities, AI agents do not know whether your MCP server offers tools, resources, or prompts. Declaring capabilities upfront lets agents decide if your server is relevant before connecting, saving time and reducing unnecessary requests.
Why This Matters
Without declared capabilities, AI agents cannot determine whether your MCP server offers tools, resources, or prompts. They must attempt connections and probe blindly, wasting time and often skipping your server entirely.
How to Fix
Add a capabilities object to each server entry in your servers.json, declaring which capability types (tools, resources, prompts) your server supports.
Example
{
"servers": [
{
"name": "Your Site MCP",
"url": "https://yoursite.com/mcp",
"capabilities": {
"tools": true,
"resources": true,
"prompts": false
}
}
]
}Contact/lead form endpoint
AI agents increasingly handle tasks like "contact this company for a quote" on behalf of users. Without a machine-submittable contact form, agents cannot complete these requests, sending users to competitors who have one. Provide an HTML form or an API endpoint.
Why This Matters
When users ask AI agents to "contact this company for a quote" or "send a message to their support team," the agent needs a machine-submittable form or API endpoint. Without one, the agent cannot complete the request and users turn to competitors.
How to Fix
Add an HTML <form> with a standard action and method attribute for contact/inquiry submission, or expose a POST endpoint in your OpenAPI spec for contact requests.
Example
<!-- HTML form approach -->
<form action="/api/contact" method="POST">
<input type="text" name="name" placeholder="Name" required />
<input type="email" name="email" placeholder="Email" required />
<textarea name="message" placeholder="Message" required></textarea>
<button type="submit">Send</button>
</form>
<!-- Or OpenAPI approach -->
"paths": {
"/api/contact": {
"post": {
"operationId": "submitContact",
"summary": "Submit a contact inquiry"
}
}
}Search endpoint functional
A search endpoint lets AI agents find specific content on your site without crawling every page. When a user asks an agent "find pricing info on Example.com," the agent can use your search API directly. Add a Schema.org SearchAction or an OpenAPI search endpoint.
Why This Matters
Without a search endpoint, AI agents must crawl every page to find specific content. When a user asks "find pricing info on Example.com," the agent has no efficient way to locate it, resulting in slow or failed responses.
How to Fix
Add a Schema.org SearchAction to your homepage JSON-LD, or expose a GET search endpoint in your OpenAPI spec. Ensure the endpoint returns results for a test query.
Example
<!-- Schema.org SearchAction in JSON-LD -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"url": "https://yoursite.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://yoursite.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}
</script>data-action attributes on CTAs
data-action attributes help AI browser agents (like ChatGPT Browse and Google Mariner) identify clickable CTAs and understand what each button does. Without these hints, agents must guess which elements are interactive based on text alone.
Why This Matters
Without data-action attributes, AI browser agents like ChatGPT Browse and Google Mariner must guess which elements are clickable and what they do. This leads to missed conversions when agents cannot reliably identify your "Book a Demo" or "Add to Cart" buttons.
How to Fix
Add data-action, data-action-type, and data-action-label attributes to your key CTA buttons and links. Use descriptive action names and categorize them (e.g., "conversion", "navigation").
Example
<button data-action="book-demo" data-action-type="conversion"
data-action-label="Book a Demo">
Book a Demo
</button>
<a href="/pricing" data-action="view-pricing" data-action-type="navigation"
data-action-label="See Pricing">
See Pricing
</a>Forms don't use blocking CAPTCHA
Blocking CAPTCHAs like reCAPTCHA and hCaptcha prevent AI agents from completing forms on behalf of users. When someone asks an AI assistant to "fill out the contact form on Example.com," the CAPTCHA blocks the action entirely. Use honeypot fields or invisible server-side validation instead.
Why This Matters
Blocking CAPTCHAs completely prevent AI agents from submitting forms on behalf of users. When a user asks an agent to "fill out the contact form," the CAPTCHA blocks the action entirely, forcing the user to do it manually or go to a competitor.
How to Fix
Replace visible CAPTCHAs (reCAPTCHA, hCaptcha, Turnstile) with invisible bot-detection methods such as honeypot fields, server-side rate limiting, or invisible reCAPTCHA v3 score-based checks that do not require user interaction.
Example
<!-- Replace CAPTCHA with a honeypot field -->
<form action="/api/contact" method="POST">
<!-- Hidden honeypot field - bots fill this, humans don't -->
<input type="text" name="website_url" style="display:none"
tabindex="-1" autocomplete="off" />
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>
<!-- Server-side: reject if website_url is filled -->Forms work without JavaScript
Many AI agents do not execute JavaScript, so forms that rely on JS for submission are invisible to them. Adding standard HTML action and method attributes ensures forms work via simple HTTP requests, making them accessible to all AI agents.
Why This Matters
Most AI agents do not execute JavaScript. If your forms rely on JS for submission (e.g., React/Vue event handlers with no HTML action), agents cannot submit them at all. This blocks lead capture, contact requests, and any form-based interaction.
How to Fix
Ensure every <form> element has a standard HTML action attribute pointing to a server endpoint and a method attribute (typically POST). This allows forms to work via plain HTTP requests without JavaScript.
Example
<!-- Use standard HTML form attributes -->
<form action="/api/contact" method="POST">
<input type="text" name="name" required />
<input type="email" name="email" required />
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>WebMCP discovery manifest
WebMCP is a proposed W3C standard (Chrome 146+) that lets websites expose structured tools to AI agents. A /.well-known/webmcp manifest is an emerging convention (not yet in the formal spec) that enables agentic crawlers to discover your site's capabilities before visiting, similar to how robots.txt works for search engines.
Why This Matters
Without a WebMCP manifest, AI agents cannot pre-discover what actions your site supports. Agents must fall back to scraping or vision-based interaction, which is slower, less reliable, and may miss key capabilities like product search or checkout.
How to Fix
Create a /.well-known/webmcp manifest file describing your site's available tools, their parameters, and capabilities.
Example
// /.well-known/webmcp
{
"name": "Your Store",
"description": "E-commerce store with product search and checkout",
"tools": [
{
"name": "searchProducts",
"description": "Search the product catalog by keyword, category, or filters",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search keywords" },
"category": { "type": "string", "description": "Product category" }
},
"required": ["query"]
}
}
]
}WebMCP declarative form tools
WebMCP's Declarative API lets you expose HTML forms as agent-callable tools by adding toolname and tooldescription attributes. AI agents can then discover and invoke these forms without JavaScript, using standard HTML semantics.
Why This Matters
Without WebMCP declarative attributes, AI agents cannot discover your forms as structured tools. They must rely on heuristics or vision to identify interactive elements, leading to unreliable agent interactions.
How to Fix
Add toolname and tooldescription attributes to your <form> elements to expose them as WebMCP tools.
Example
<!-- WebMCP declarative form -->
<form toolname="searchProducts"
tooldescription="Search the product catalog by keyword"
action="/search" method="GET">
<input type="text" name="q" placeholder="Search products..." />
<button type="submit">Search</button>
</form>
<!-- Checkout form -->
<form toolname="addToCart"
tooldescription="Add a product to the shopping cart"
action="/cart/add" method="POST">
<input type="hidden" name="product_id" />
<input type="number" name="quantity" value="1" min="1" />
<button type="submit">Add to Cart</button>
</form>WebMCP tool input quality
For AI agents to correctly invoke WebMCP tools, form inputs must have descriptive name attributes, appropriate type attributes, and associated labels or descriptions. Poor input quality leads to agents guessing parameter values or skipping the tool entirely.
Why This Matters
AI agents map form inputs to tool parameters. Inputs without meaningful names (e.g., "field1"), missing types, or no labels force agents to guess what data to provide, resulting in failed submissions or incorrect values.
How to Fix
Ensure every input in a WebMCP-declared form has a descriptive name, an appropriate type, and an associated label element or aria-label.
Example
<form toolname="searchProducts"
tooldescription="Search products by keyword and filters">
<label for="search-query">Search query</label>
<input id="search-query" type="text" name="query"
placeholder="e.g., red running shoes" required />
<label for="price-max">Maximum price</label>
<input id="price-max" type="number" name="maxPrice"
placeholder="100" min="0" />
<label for="category">Category</label>
<select id="category" name="category">
<option value="">All categories</option>
<option value="shoes">Shoes</option>
</select>
</form>WebMCP tool naming conventions
WebMCP tools should follow verb-based camelCase naming (e.g., searchProducts, addToCart) and have descriptions of at least 20 characters. This helps AI agents understand the tool's purpose and invoke the correct one.
Why This Matters
Poorly named tools (e.g., "form1", "action") make it harder for AI agents to select the right tool for a user's intent. Agents rely heavily on tool names and descriptions to decide which actions to take.
How to Fix
Use verb-based camelCase names that describe the action (e.g., searchProducts, addToCart, submitInquiry) and descriptions of at least 20 characters explaining what the tool does.
Example
<!-- Good naming -->
<form toolname="searchProducts"
tooldescription="Search the product catalog by keyword, category, price range, and other filters">
...
</form>
<!-- Bad naming -->
<form toolname="form1"
tooldescription="Search">
...
</form>WebMCP tool safety annotations
WebMCP tools should include the readOnlyHint annotation (defined in the WebMCP spec) and ideally MCP-compatible annotations like destructiveHint and idempotentHint, so AI agents can make informed decisions about when to invoke tools and whether to ask for user confirmation.
Why This Matters
Without safety annotations, AI agents treat all tools equally — a "delete account" tool looks the same as a "search products" tool. Annotations let agents automatically request user confirmation for destructive actions and freely use read-only tools, improving both safety and user experience.
How to Fix
Add annotation properties to your WebMCP tool definitions in the manifest or as data attributes on declarative forms.
Example
// In /.well-known/webmcp manifest
{
"tools": [
{
"name": "searchProducts",
"description": "Search the product catalog",
"annotations": {
"readOnlyHint": true,
"destructiveHint": false,
"idempotentHint": true
},
"inputSchema": { ... }
},
{
"name": "addToCart",
"description": "Add a product to the cart",
"annotations": {
"readOnlyHint": false,
"destructiveHint": false,
"idempotentHint": false
},
"inputSchema": { ... }
}
]
}
<!-- Or on declarative forms -->
<form toolname="addToCart"
tooldescription="Add a product to the shopping cart"
data-readonly="false"
data-destructive="false">WebMCP commerce action coverage
For e-commerce sites, WebMCP tools should cover key commerce actions: product search, product detail, add to cart, checkout, and contact/support. Broader action coverage means AI agents can complete more user tasks without falling back to manual browsing.
Why This Matters
AI shopping agents need to complete full purchase journeys — search, view, add to cart, checkout. If your WebMCP tools only cover search but not checkout, agents abandon the flow and users turn to competitors with full coverage.
How to Fix
Expose WebMCP tools for the key commerce actions: product search, product detail/view, add to cart, checkout/purchase, and contact/support.
Example
// /.well-known/webmcp — full commerce coverage
{
"tools": [
{
"name": "searchProducts",
"description": "Search the product catalog by keyword, category, or filters",
"annotations": { "readOnlyHint": true },
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string" },
"category": { "type": "string" },
"maxPrice": { "type": "number" }
},
"required": ["query"]
}
},
{
"name": "getProductDetails",
"description": "Get full details for a specific product by ID or URL",
"annotations": { "readOnlyHint": true },
"inputSchema": {
"type": "object",
"properties": { "productId": { "type": "string" } },
"required": ["productId"]
}
},
{
"name": "addToCart",
"description": "Add a product to the shopping cart with quantity",
"annotations": { "readOnlyHint": false, "idempotentHint": false },
"inputSchema": {
"type": "object",
"properties": {
"productId": { "type": "string" },
"quantity": { "type": "integer", "minimum": 1 }
},
"required": ["productId"]
}
},
{
"name": "checkout",
"description": "Initiate checkout for the current cart",
"annotations": { "readOnlyHint": false, "confirmationRequired": true },
"inputSchema": {
"type": "object",
"properties": { "shippingMethod": { "type": "string" } }
}
}
]
}