Skip to content

MCP Providers For Developers

QUIQQER packages can add their own MCP tools. Use this when a module provides domain behavior that should be available to AI clients, for example content helpers, product tools, import helpers, search tools, or project-specific automation.

MCP tools are part of a package API. Keep them small, permission-checked, and explicit about the project and language they operate on.

Requirements

A package that provides MCP tools needs:

  • quiqqer/ai-mcp installed in the target system
  • a provider class that implements QUI\AI\MCP\ProviderInterface
  • a provider entry in package.xml
  • permissions that control who may use the tools
  • clear tool names, descriptions, and input schemas

Register The Provider

Register the MCP provider in package.xml:

xml
<quiqqer>
    <package>
        <provider>
            <mcp src="\Vendor\Package\MCP\Provider"/>
        </provider>
    </package>
</quiqqer>

During setup, QUIQQER imports package providers. The MCP server discovers installed MCP providers and registers their tools.

Provider Class

Create a provider class that implements ProviderInterface:

php
<?php

namespace Vendor\Package\MCP;

use Mcp\Server\Builder;
use QUI\AI\MCP\ProviderInterface;
use QUI\AI\MCP\Server;
use QUI\AI\MCP\ToolHelper;
use QUI\Permissions\Permission;
use Throwable;

final class Provider implements ProviderInterface
{
    public function register(Builder $serverBuilder): void
    {
        if (!$this->canUseTools()) {
            return;
        }

        $serverBuilder->addTool(
            function (string $project, string $lang): mixed {
                try {
                    Permission::checkPermission(
                        'vendor.package.mcp',
                        Server::getRequestUser()
                    );

                    return [
                        'project' => $project,
                        'lang' => $lang
                    ];
                } catch (Throwable $Exception) {
                    return ToolHelper::parseExceptionToResult($Exception);
                }
            },
            name: 'vendor_package_example',
            description: 'Example MCP tool for this package.',
            inputSchema: [
                'type' => 'object',
                'additionalProperties' => false,
                'required' => ['project', 'lang'],
                'properties' => [
                    'project' => [
                        'type' => 'string',
                        'description' => 'QUIQQER project name.'
                    ],
                    'lang' => [
                        'type' => 'string',
                        'description' => 'Project language.'
                    ]
                ]
            ]
        );
    }

    private function canUseTools(): bool
    {
        try {
            Permission::checkPermission(
                'vendor.package.mcp',
                Server::getRequestUser()
            );

            return true;
        } catch (Throwable) {
            return false;
        }
    }
}

For larger packages, create separate tool classes and let the provider register them. This keeps permissions, parsing, and test coverage easier to maintain.

Permissions

Every tool provider should define a package-specific MCP permission. Use a dedicated permission instead of relying only on a broad administrator role.

Example permissions.xml:

xml
<?xml version="1.0" encoding="UTF-8"?>
<permissions>
    <permission name="vendor.package.mcp" type="bool">
        <defaultvalue>0</defaultvalue>
        <rootPermission>1</rootPermission>
        <everyonePermission>0</everyonePermission>
        <guestPermission>0</guestPermission>
    </permission>
</permissions>

The tool should also check normal domain permissions. For example, a tool that updates a site should check the relevant project and site edit permissions. A tool that changes media should check media permissions.

Tool Design Rules

  • Use stable, namespaced tool names such as vendor_package_action.
  • Write descriptions for AI clients, not for PHP developers.
  • Require project and lang when the tool acts on project data.
  • Use strict input schemas with additionalProperties: false.
  • Return structured arrays instead of formatted strings.
  • Catch exceptions and return MCP-compatible error results.
  • Never expose secrets, raw credentials, or internal paths.
  • Prefer separate read and write tools over one broad tool that does everything.
  • Keep delete and publish operations behind explicit permissions.

Project And Language Inputs

For project data, include project and language parameters explicitly:

json
{
  "project": "default",
  "lang": "en",
  "siteId": 12
}

Do not infer the language from the prompt. AI clients can be wrong about the target language; tools should require the context when content can be changed.

Cache And Setup

Provider registration is imported through package setup. Run setup after adding or changing the MCP provider declaration in package.xml:

shell
./console setup

If the MCP tool list does not change after setup, clear the relevant caches and retry the client connection.

Testing Checklist

Before publishing a package MCP provider:

  • The provider is registered in package.xml.
  • The provider class exists and implements ProviderInterface.
  • Every tool checks a package-specific MCP permission.
  • Write tools check normal domain permissions.
  • Tool names are stable and namespaced.
  • Inputs are documented through inputSchema.
  • Project tools require project and language context.
  • The tool works with a restricted AI account, not only with a superuser.

Released under GPL-3.0-or-later.