Warning
Experimental. This extension is experimental and not yet ready for production use. It is built on top of WebMCP, which is itself an experimental, early-stage proposal. Both the underlying specification and this extension's API may change or break at any time without notice. Use at your own risk.
Quickstart
This walkthrough takes you from a freshly installed extension to a working tool
that an AI agent can call on the page. It uses the static primitive, so no
JavaScript and no external index are required.
Prerequisites
- The extension is installed and set up (see Installation).
- You have a site package where you can add PHP classes and TypoScript.
Step 1 – Write a tool provider
Create a small PHP class in your site package (or any extension). Because the
\Neoblack\ carries the
# attribute, an autoconfigured service
implementing it is picked up automatically — no Services. entry is
needed as long as your extension enables autoconfiguration.
<?php
declare(strict_types=1);
namespace Vendor\SitePackage\Tool;
use Neoblack\Webmcp\Tool\Manifest;
use Neoblack\Webmcp\Tool\Primitive;
use Neoblack\Webmcp\Tool\ToolProviderInterface;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
final class ServicesToolProvider implements ToolProviderInterface
{
public function name(): string
{
return 'list_services';
}
public function manifest(ContentObjectRenderer $cObj, array $processedData): ?Manifest
{
return new Manifest(
name: 'list_services',
description: 'List the services this company offers.',
inputSchema: ['type' => 'object', 'properties' => new \stdClass()],
primitive: Primitive::StaticList,
data: [
'items' => [
['title' => 'Consulting', 'url' => 'https://example.org/consulting'],
['title' => 'Development', 'url' => 'https://example.org/development'],
],
'resultKey' => 'services',
'text' => [
'heading' => 'Our services:',
'line' => '{n}. {title} – {url}',
],
],
);
}
}
Note
If your site package does not autoconfigure services, add the tag manually:
Vendor\SitePackage\Tool\ServicesToolProvider:
tags:
- name: webmcp.tool
Step 2 – Wire the manifest into the page
Add the three pieces described in Configuration to your site package. In short:
page.10.dataProcessing {
40 = Neoblack\Webmcp\DataProcessing\ToolManifestProcessor
40 {
endpoint = /webmcp-event
as = webmcpConfigJson
}
}
page.includeJSFooter {
webmcp = EXT:neoblack_webmcp/Resources/Public/JavaScript/webmcp.js
webmcp.defer = 1
}
Render the JSON block once in your page template:
<f:if condition="{webmcpConfigJson}">
<script type="application/json" id="webmcp-config"></script>
</f:if>
Step 3 – Verify it in the browser
Reload a frontend page and open the browser's developer console.
-
Confirm the manifest is on the page:
Console — inspect the manifestJSON.parse(document.getElementById('webmcp-config').textContent).toolsCopied!You should see your
list_tool in the returned array.services
The parsed manifest in the browser console, listing the
list_tool.services -
Confirm the runtime registered it against the
Model:Context Console — check for an agent surfacedocument.modelContext || navigator.modelContextCopied!A
Modelimplementation is only present in agent-capable browsers (for example Chrome with the WebMCP flag or origin trial, see Standards and browser support). IfContext document.andmodel Context navigator.are bothmodel Context undefined, the page is fine — there is simply no agent surface to register against. To list the tools the page actually registered, use the Model Context Tool Inspector extension (see Troubleshooting).
Tip
Once an agent operates the page, it can discover list_ and call
it; the runtime returns the curated list and (unless disabled) records one
anonymous usage row visible in the backend module.
Next steps
- Swap
staticfor another primitive —search,navigateormailto— see Writing tools. - Return
nullfrommanifestto hide a tool on pages where it does not apply.()
See also
- Writing tools – every primitive's payload and the escape hatch.
- Troubleshooting – what to check if the tool does not show up.
- Analytics – inspect usage in the System > WebMCP module.