Skip to content

Work with MCP servers

The MCP Servers LTS Update includes several built-in tools. Additionally, you can create your own capabilities (tools, prompts, and resources) to expose custom features to AI agents through your MCP servers.

MCP server capabilities

The Ibexa DXP MCP server framework (ibexa/mcp) is built on top of the official PHP SDK for MCP (mcp/sdk).

A PHP class that implements MCP server capabilities such as tools, prompts, or resources, must:

Tools

The Ibexa\Contracts\Mcp\Attribute\McpTool attribute declares a method as an MCP tool. It accepts the following optional arguments:

  • servers - array of server identifiers the tool is assigned to
    For more information, see tools configuration.
  • name - tool codename - if not set, function name is used
  • title - tool title for user interfaces - if not set, the name is used
  • description - tool description, used by AI agents to understand the tool's purpose
  • icons - array of Mcp\Schema\Icon instances
    For more information, see the icons specification.
  • outputSchema - associative array describing a JSON object response
  • annotations - Mcp\Schema\ToolAnnotations instance
    For more information, see the ToolAnnotations specification.
  • meta - free-form array for additional metadata
    For more information, see the _meta specification.

The framework automatically builds an inputSchema from the method arguments and their types. To customize or extend the generated schema, you can:

If an argument is an enum, its possible values are listed in the schema (UntitledSingleSelectEnumSchema).

Prompts

MCP servers can also provide prompt templates to help users interact with AI agents connected to the server.

Methods that return a prompt are marked with the Ibexa\Contracts\Mcp\Attribute\McpPrompt attribute.

It accepts several arguments that describe how the prompt is used:

  • servers - array of server identifiers exposing this prompt - required for prompts
  • name (optional) - prompt codename - if not set, method name is used
  • title (optional) - prompt title - if not set, name is used
  • description (optional) - human-readable prompt description
  • icons (optional) - array of Mcp\Schema\Icon instances
    For more information, see the icons specification.
  • meta (optional) - rarely used free-form array for additional metadata
    For more information, see the _meta specification.

The framework automatically builds the arguments array from the method arguments and their types. Prompt method arguments must be strings to comply with the GetPromptRequestParams schema. To add argument descriptions, use DocBlock @param tags, it's mapped to the description defined by the PromptArgument schema.

Example

To keep the example focused on MCP server configuration and capability creation, it doesn't interact with the Ibexa DXP repository.

Create user account

In this example, the MCP server uses JWT tokens created with a dedicated user account.

In Ibexa DXP's back office, create a user in the Guest accounts user group, with login ibexa-example and password Ibexa-3xample.

Configure MCP server

This example introduces an MCP server named example, with a single tool called greet. The server:

  • is enabled on the default repository
  • is available in all SiteAccesses
  • is accessible with the path /mcp/example
    For example:
    • http://localhost/mcp/example
    • http://localhost/admin/mcp/example
  • uses file storage for both discovery cache and sessions

Storage choice recommendations

Filesystem storage is convenient for the sake of this example and for testing. For production, it is recommended that you use Redis or Valkey.

In a new config/packages/mcp.yaml file, define a new MCP server for the default repository and assign it to all SiteAccesses:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
ibexa:
    repositories:
        default:
            mcp:
                example:
                    path: /mcp/example
                    enabled: true
                    description: 'Example MCP Server'
                    instructions: 'Use this server to greet someone.'
                    discovery_cache: cache.tagaware.filesystem
                    session:
                        type: psr16
                        service: cache.tagaware.filesystem
                    allowed_hosts:
                        - '127.0.0.1'
    system:
        default:
            mcp:
                servers:
                    - example

Adapt the allowed_hosts to your case, for example, if you want to use the DDEV .ddev.site domain instead of its 127.0.0.1 address equivalent.

An ibexa.mcp.example route is now available:

1
php bin/console debug:router ibexa.mcp.example

Create capability class

Create an ExampleCapabilities class that implements McpCapabilityInterface.

The class contains:

  • a method marked with an McpTool attribute that associates it to the example server as greet tool
  • a method marked with an McpPrompt attribute that provides a prompt template to users
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php declare(strict_types=1);

namespace App\Mcp;

use Ibexa\Contracts\Mcp\Attribute\McpPrompt;
use Ibexa\Contracts\Mcp\Attribute\McpTool;
use Ibexa\Contracts\Mcp\McpCapabilityInterface;
use Mcp\Schema\Icon;
use Mcp\Schema\ToolAnnotations;

final readonly class ExampleCapabilities implements McpCapabilityInterface
{
    /**
     * @param string $name The name of the person to greet
     *
     * @return array<string, string>
     */
    #[McpTool(
        servers: ['example'],
        name: 'greet',
        title: 'User greeting',
        description: 'Greet a user by name',
        annotations: new ToolAnnotations(
            readOnlyHint: true,
            destructiveHint: false,
            idempotentHint: true,
            openWorldHint: false,
        ),
        icons: [new Icon(
            src: 'https://openmoji.org/data/color/svg/1F44B.svg',
        )],
        outputSchema: [
            'type' => 'object',
            'properties' => [
                'general' => [
                    'type' => 'string',
                    'description' => 'the safe way to greet someone',
                ],
                'close' => [
                    'type' => 'string',
                    'description' => 'when you\'re close to the person, like friends or relatives',
                ],
                'morning' => [
                    'type' => 'string',
                    'description' => 'when it\'s in the morning',
                ],
                'afternoon' => [
                    'type' => 'string',
                    'description' => 'when it\'s the afternoon',
                ],
                'evening' => [
                    'type' => 'string',
                    'description' => 'when it\'s late in the day',
                ],
            ],
        ],
    )]
    public function greetByName(string $name): array
    {
        return [
            'general' => sprintf('Hello, %s!', $name),
            'close' => sprintf('Hey, %s!', $name),
            'morning' => sprintf('Good morning, %s!', $name),
            'afternoon' => sprintf('Good afternoon, %s!', $name),
            'evening' => sprintf('Good evening, %s!', $name),
        ];
    }

    /**
     * @param string $name The name you want to be greeted by
     *
     * @return array<string, mixed>
     */
    #[McpPrompt(
        servers: ['example'],
        name: 'greet',
        title: 'Be greeted',
        description: 'Prompt to invoke the `greet` tool',
        icons: [new Icon(
            src: 'https://openmoji.org/data/color/svg/1F91D.svg',
        )],
    )]
    public function getGreetPrompt(string $name): array
    {
        return [
            'role' => 'user',
            'content' => [
                'type' => 'text',
                'text' => "Hi. My name is $name. Please, greet me.",
            ],
        ];
    }
}

In this example, the servers attribute parameter associates only this tool with the example server. Alternatively, you can assign all tools from the class to a server by using the tools parameter in server configuration. For more information, see tools configuration.

For the prompt, the servers parameter is required. Therefore, the example prompt must use it to be associated with the example server.

During development and testing, you may need to clear the cache to ensure that new or modified capabilities are properly re-discovered. In this example, use the following command:

1
php bin/console cache:pool:clear cache.tagaware.filesystem

Cache clearing

During development, clear caches aggressively. The following commands clear all cache types, regardless of where they are stored:

1
2
php bin/console cache:clear
php bin/console cache:pool:clear --all

Create MCP server list command

To check the MCP server configuration, create a small command that uses the MCP server configuration registry injected through McpServerConfigurationRegistryInterface and autowiring:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php declare(strict_types=1);

namespace App\Command;

use Ibexa\Contracts\Mcp\McpServerConfigurationRegistryInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(name: 'app:mcp:server_list', description: 'List MCP servers')]
class McpServerListCommand
{
    public function __construct(private readonly McpServerConfigurationRegistryInterface $configRegistry)
    {
    }

    public function __invoke(SymfonyStyle $io): int
    {
        foreach($this->configRegistry->getServerConfigurations() as $serverConfiguration) {
            $io->title($serverConfiguration->identifier);
            dump($serverConfiguration);
        }

        return Command::SUCCESS;
    }
}

Perform curl test

To test the example MCP server, a sequence of curl commands is used to simulate the communication between an AI client and the MCP server.

  • Ask for a JWT token through REST.
  • Initialize a connection to the MCP server.
  • Validate the MCP Session ID.
  • List the available tools.
  • Call a tool.

jq, grep, and sed are also used to parse or display outputs.

First, use the shell script to set the Ibexa DXP's base URL and user credentials as variables for easier reuse:

1
2
3
baseUrl='http://localhost' # Adapt to your test case
username='ibexa-example'
password='Ibexa-3xample'

Before you can communicate with the MCP server, you must first request a JWT token through the REST API:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
curl -s -X 'POST' \
  "$baseUrl/api/ibexa/v2/user/token/jwt" \
  -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
  -H 'Accept: application/vnd.ibexa.api.JWT+json' \
  -d "{
        \"JWTInput\": {
          \"_media-type\": \"application/vnd.ibexa.api.JWTInput+json\",
          \"username\": \"$username\",
          \"password\": \"$password\"
        }
      }" > response.tmp.txt

cat response.tmp.txt | jq
jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
rm response.tmp.txt
1
2
3
4
5
6
7
{
  "JWT": {
    "_media-type": "application/vnd.ibexa.api.JWT+json",
    "_token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890",
    "token": "1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz1234567890ABCD.EFGHIJKL-MNOPQRSTUVWXYZ12345678901234567890"
  }
}

Then, perform initialization to get an MCP session ID:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cat response.tmp.txt | jq
jwtToken=$(cat response.tmp.txt | jq -r .JWT.token)
rm response.tmp.txt

curl -s -i -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -d '{
        "jsonrpc": "2.0",
        "id": 1,
        "method": "initialize",
        "params": {
          "protocolVersion": "2025-03-26",
          "capabilities": {},
          "clientInfo": {
            "name": "test-curl-client",
            "version": "1.0.0"
          }
        }
      }' > response.tmp.txt

sed '$d' response.tmp.txt
tail -n 1 response.tmp.txt | jq
mcpSessionId=$(cat response.tmp.txt | grep -i 'Mcp-Session-Id:' | sed 's/Mcp-Session-Id: \([0-9a-f-]*\).*/\1/i')
rm response.tmp.txt
1
2
3
4
5
6
7
8
9
HTTP/1.1 200 OK
Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Mcp-Session-Id
Cache-Control: no-cache, private
Content-Type: application/json
Date: Tue, 28 Apr 2026 09:53:27 GMT
Mcp-Session-Id: 12345678-9abc-def0-1234-56789abcdef0
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "logging": {},
      "completions": {},
      "prompts": {
        "listChanged": true
      },
      "resources": {
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      }
    },
    "serverInfo": {
      "name": "example",
      "version": "1.0.0",
      "description": "Example MCP Server"
    },
    "instructions": "Use this server to greet someone."
  }
}

Validate the initialization:

1
2
3
4
5
6
7
curl -s -i -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -H "Mcp-Session-Id: $mcpSessionId" \
  -d '{
        "jsonrpc": "2.0",
        "method": "notifications/initialized"
      }'
1
2
3
4
5
HTTP/1.1 202 Accepted
Access-Control-Allow-Headers: Content-Type, Mcp-Session-Id, Mcp-Protocol-Version, Last-Event-ID, Authorization, Accept
Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Mcp-Session-Id

Get the list of tools:

1
2
3
4
5
6
7
8
curl -s -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -H "Mcp-Session-Id: $mcpSessionId" \
  -d '{
        "jsonrpc": "2.0",
        "id": 2,
        "method": "tools/list"
      }' | jq
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "tools": [
      {
        "name": "greet",
        "inputSchema": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "description": "The name of the person to greet"
            }
          },
          "required": [
            "name"
          ]
        },
        "description": "Greet a user by name",
        "annotations": {
          "readOnlyHint": true,
          "destructiveHint": false,
          "idempotentHint": true,
          "openWorldHint": false
        },
        "icons": [
          {
            "src": "https://openmoji.org/data/color/svg/1F44B.svg"
          }
        ],
        "outputSchema": {
          "type": "object",
          "properties": {
            "general": {
              "type": "string",
              "description": "the safe way to greet someone"
            },
            "close": {
              "type": "string",
              "description": "when you're close to the person, like friends or relatives"
            },
            "morning": {
              "type": "string",
              "description": "when it's in the morning"
            },
            "afternoon": {
              "type": "string",
              "description": "when it's the afternoon"
            },
            "evening": {
              "type": "string",
              "description": "when it's late in the day"
            }
          }
        }
      }
    ]
  }
}

Call the greet tool:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
curl -s -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -H "Mcp-Session-Id: $mcpSessionId" \
  -d '{
        "jsonrpc": "2.0",
        "id": 3,
        "method": "tools/call",
        "params": {
          "name": "greet",
          "arguments": {
            "name": "World"
          }
        }
      }' | jq
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "{\n    \"general\": \"Hello, World!\",\n    \"close\": \"Hey, World!\",\n    \"morning\": \"Good morning, World!\",\n    \"afternoon\": \"Good afternoon, World!\",\n    \"evening\": \"Good evening, World!\"\n}"
      }
    ],
    "isError": false,
    "structuredContent": {
      "general": "Hello, World!",
      "close": "Hey, World!",
      "morning": "Good morning, World!",
      "afternoon": "Good afternoon, World!",
      "evening": "Good evening, World!"
    }
  }
}

Get the list of prompts:

1
2
3
4
5
6
7
8
curl -s -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -H "Mcp-Session-Id: $mcpSessionId" \
  -d '{
        "jsonrpc": "2.0",
        "id": 4,
        "method": "prompts/list"
      }' | jq
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "prompts": [
      {
        "name": "greet",
        "description": "Prompt to be greeted by the `greet` tool",
        "arguments": [
          {
            "name": "name",
            "description": "The name you want to be greeted by",
            "required": true
          }
        ],
        "icons": [
          {
            "src": "https://openmoji.org/data/color/svg/1F91D.svg"
          }
        ]
      }
    ]
  }
}

Get the prompt of the greet method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
curl -s -X 'POST' "$baseUrl/mcp/example" \
  -H "Authorization: Bearer $jwtToken" \
  -H "Mcp-Session-Id: $mcpSessionId" \
  -d '{
        "jsonrpc": "2.0",
        "id": 5,
        "method": "prompts/get",
        "params": {
          "name": "greet",
          "arguments": {
            "name": "Firstname Lastname"
          }
        }
      }' | jq
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "Hi. My name is Firstname Lastname. Please, greet me."
        }
      }
    ]
  }
}

Perform MCP Inspector test

You can test your server with the MCP Inspector. You can even use the inspector as a DDEV add-on with michtio/ddev-mcp-inspector. You still need to ask for a JWT token through REST or GraphQL APIs, and use it in the MCP Inspector configuration to connect to the server.

You can use a Web interface to obtain the JWT token:

MCP server settings

In this example, the settings needed to use the MCP Inspector are as follows:

  • Transport Type: Streamable HTTP
  • URL: actual domain and server path, for example http://localhost/mcp/example
  • Connection Type: Via Proxy
  • Authentication:
    • Custom Headers:
      • Authorization
      • Bearer <JWT token>
    • OAuth 2.0 Flow: left unedited

Left panel of MCP Inspector with connection settings for MCP server

Test MCP server within MCP Inspector

In the right panel, in the Tools tab, click List Tools in the left column. The greet tool appears, preceded by its icon. You can select and test it in the right column.

Right panel of MCP Inspector with a list of tools obtained from MCP server, and the test of the greet tool

In the Prompts tab, in the left column, click List Prompts. The greet prompt appears, preceded by its icon. You can select and test it in the right column.

Right panel of MCP Inspector with a list of prompts obtained from the MCP server, and the test of the greet prompt

Perform Copilot or Claude Code test

You can use your MCP with Copilot CLI or Claude Code CLI like illustrated here, or any agent with any interface to test your MCP server.

Add MCP server to agent CLI

For the sake of the agent test, in this example, you configure the MCP server in an .mcp.json file at the Ibexa DXP project root. This way it is only available for a session opened from there.

You can handle the JWT token for this test in the following ways:

Hard coded variant

The hard coded JWT token configuration in .mcp.json looks as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  "mcpServers": {
    "ibexa-example": {
      "type": "http",
      "url": "http://localhost/mcp/example",
      "headers": {
        "Authorization": "Bearer <JWT token>"
      },
      "tools": ["*"]
    }
  }
}

The .mcp.json file must be edited to update the JWT token each time it expires. You can request a token by using the GraphiQL web interface or a curl command, and then edit the file manually. Alternatively, you can configure a shell script to request the JWT token, extract it from the response, and replace it in the file.

When Copilot or Claude Code complains that it can't communicate with the MCP server:

  • Update the JWT token in the .mcp.json file.
  • Reload the MCP servers in Copilot CLI with one of these methods:
    • Run /mcp reload command to reload all MCP servers.
    • Run /mcp disable ibexa-example and /mcp enable ibexa-example to only reload the ibexa-example server.
  • Update the JWT token in the .mcp.json file.
  • Reload the MCP servers in Copilot CLI with one of these methods:
    • Run /mcp reload command to reload all MCP servers.
    • Run /mcp disable ibexa-example and /mcp enable ibexa-example to only reload the ibexa-example server.

Reloading multiple MCP servers

If you have several MCP servers enabled globally, reloading all of them at the same time can be time consuming. Consider reloading them one by one.

  • Update the JWT token in the .mcp.json file.
  • Run /mcp reconnect ibexa-example command to reconnect the ibexa-example MCP server.
Fully scripted variant

The wrapping script configuration in .mcp.json looks as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
  "mcpServers": {
    "ibexa-example": {
      "type": "stdio",
      "command": "bash",
      "args": ["mcp-ibexa-example-wrapper.sh"],
      "tools": ["*"]
    }
  }
}

mcp-ibexa-example-wrapper.sh is a script that requests a JWT token and establishes a connection with the MCP server.

For example, thanks to npx, you can do it with Supergateway without a local installation:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/bash
set -e

baseUrl='http://localhost' # Adapt to your test case

jwtToken=$(curl -s -X 'POST' \
  "$baseUrl/api/ibexa/v2/user/token/jwt" \
  -H 'Content-Type: application/vnd.ibexa.api.JWTInput+json' \
  -H 'Accept: application/vnd.ibexa.api.JWT+json' \
  -d '{
        "JWTInput": {
          "_media-type": "application/vnd.ibexa.api.JWTInput+json",
          "username": "ibexa-example",
          "password": "Ibexa-3xample"
        }
      }' | jq -r .JWT.token)

exec npx -y supergateway \
  --streamableHttp "$baseUrl/mcp/example" \
  --oauth2Bearer "$jwtToken" \
  --logLevel none

When the agent complains that it can't communicate with the MCP server, reload it:

Reload the MCP servers in Copilot CLI with one of these methods:

  • Run /mcp reload command to reload all MCP servers.
  • Run /mcp disable ibexa-example and /mcp enable ibexa-example to only reload the ibexa-example server.

Reloading multiple MCP servers

If you have several MCP servers enabled globally, reloading all of them at the same time can be time consuming. Consider reloading them one by one.

Run /mcp reconnect ibexa-example command to reconnect the ibexa-example MCP server.

Run MCP server test with Copilot CLI or Claude Code CLI

Launch the agent CLI at the project root, where the .mcp.json file is located:

1
2
cd /path/to/project
copilot
1
2
cd /path/to/project
claude

If prompted, confirm that you trust the files in this folder. You may choose to have your choice remembered for the future.

You can check the MCP server status and details with the /mcp command:

Run the /mcp show ibexa-example to check the MCP server status and details:

1
2
3
4
5
6
7
8
9
MCP Server: ibexa-example

Type:     stdio
Command:  bash
Status:   ✓ Connected
Source:   /path/to/project/.mcp.json

Tools (1/1 enabled):
 ✓ greet: Greet a user by name (70 tokens)

Run the /mcp command and select ibexa-example to check the MCP server status and details:

1
2
3
4
5
6
7
8
Ibexa-example MCP Server                                                                                                                                                                                    

Status:           ✔ connected                                                                                                                                                                               
Command:          bash                                                                                                                                                                                      
Args:             mcp-ibexa-example-wrapper.sh                                                                                                                                                              
Config location:  /path/to/project/.mcp.json                                                                                                                                          
Capabilities: tools                                                                                                                                                                                         
Tools: 1 tool

You can prompt the agent to greet you. It should use the greet tool to do so.

  • You can ask it "Please, greet me." and it might respond with a request for your name if it doesn't already know it.
  • You can also give it another name to greet, like in the prompt template.

During a morning session, the interaction could look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
❯ Hi. Please, greet me.

◐ The user wants to be greeted. I'll use the ibexa-example-greet tool, but I don't know their name. Let me ask them first... actually, the tool requires a name. Let me ask the user for their name.

  Wait, actually I can just greet them without knowing their name using a general greeting, but the tool requires a name parameter. Let me ask for their name.

● Asked user What's your name?
  └ Pulley

● Greet a user (MCP: ibexa-example) · name: "Pulley"
  └ {"general":"Hello, Pulley!","close":"Hey, Pulley!","morning":"Good morning, P...

● Good morning, Pulley! ☀️

❯ Hi. Please, greet me. We're close friends.

◐ The user wants a close friend greeting. From the previous response, I can see the "close" greeting is "Hey, Pulley!"

● Greet a user (MCP: ibexa-example) · name: "Pulley"
  └ {"general":"Hello, Pulley!","close":"Hey, Pulley!","morning":"Good morning, P...

● Hey, Pulley! 😄

❯ Please, greet someone named "ElePHPant" in a general way (so I could reuse it at any time)

◐ The user wants a general greeting for someone named "ElePHPant".

● greet (MCP: ibexa-example) · name: "ElePHPant"
  └ {"general":"Hello, ElePHPant!","close":"Hey, ElePHPant!","morning":"Good morn...

● Hello, ElePHPant! 🐘

❯ Please, greet someone named "ElePHPant" like it's 22:30

◐ 22:30 is evening time, so I'll use the evening greeting.

● greet (MCP: ibexa-example) · name: "ElePHPant"
  └ {"general":"Hello, ElePHPant!","close":"Hey, ElePHPant!","morning":"Good morn...

● Good evening, ElePHPant! 🌙

❯ Hi. Please, greet me.

⏺ What's your name?

✻ Worked for 3s

❯ Pulley

Called ibexa-example

⏺ Hello, Pulley! 👋

✻ Churned for 4s

❯ Hi. Please, greet me. We're close friends now.

Called ibexa-example

⏺ Hey, Pulley! 👋

✻ Baked for 4s

❯ Please, greet someone named "ElePHPant" in a general way (so I could reuse it at any time)

Called ibexa-example

⏺ Hello, ElePHPant!

✻ Brewed for 5s

❯ Please, greet someone named "ElePHPant" like it's 22:30

⏺ That falls under the "evening" variant: Good evening, ElePHPant!

✻ Sautéed for 2s

The agent's reflections, reaction times, and final responses, including the improvised emojis, may differ from those examples. The key point is that the agent decides to use the greet tool, calls it with the right argument, displays the call result, and then uses it in its final output.

You can fine-tune the prompt or remove unnecessary variants if needed. For example, you could instruct to always use the time of the day variants, or simply remove the general and close variants. To remove the unnecessary is more efficient that extending the instruction.