@@ -17,9 +17,15 @@ _Read the [official MCP specification](https://modelcontextprotocol.io/docs/conc
1717 - [ Configuration] ( #configuration )
1818- [ Tools] ( #tools )
1919 - [ Creating Tools] ( #creating-tools )
20- - [ Tool Events] ( #tool-events )
2120 - [ Tool Results] ( #tool-results )
21+ - [ Tool Events] ( #tool-events )
2222 - [ Input Schema Management] ( #input-schema-management )
23+ - [ JSON-RPC Integration] ( #json-rpc-integration )
24+ - [ Prompts] ( #prompts )
25+ - [ Creating Prompts] ( #creating-prompts )
26+ - [ Prompt Results] ( #prompt-results )
27+ - [ Prompt Events] ( #prompt-events )
28+ - [ JSON-RPC Integration] ( #json-rpc-integration-1 )
2329- [ JSON-RPC Methods] ( #json-rpc-methods )
2430 - [ Built-in Methods] ( #built-in-methods )
2531 - [ Custom Methods] ( #custom-methods )
@@ -130,29 +136,6 @@ class CreateUserTool
130136}
131137` ` `
132138
133- # ## Tool Events
134-
135- The bundle provides several events that you can listen to :
136-
137- - `ToolCallEvent` : Dispatched before a tool is called, contains the tool name and input data
138- - `ToolResultEvent` : Dispatched after a tool has been called, contains the result of the tool call
139- - `ToolCallExceptionEvent` : Dispatched when a tool throws an exception, contains the tool name, input data and throwable
140-
141- Example of event listener :
142- ` ` ` php
143- use Ecourty\M cpServerBundle\E vent\T oolCallEvent;
144- use Symfony\C omponent\E ventDispatcher\A ttribute\A sEventListener;
145-
146- #[AsEventListener(event: ToolCallEvent::class)]
147- class ToolCallListener
148- {
149- public function __invoke(ToolCallEvent $event): void
150- {
151- // Your logic here...
152- }
153- }
154- ` ` `
155-
156139# ## Tool Results
157140
158141The MCP specification states that tool results should consist of an array of objects.
@@ -225,6 +208,29 @@ The `ToolResult` class provides the following features:
225208- Automatic serialization to the correct format
226209- Type safety for all results
227210
211+ # ## Tool Events
212+
213+ The bundle provides several events that you can listen to :
214+
215+ - `ToolCallEvent` : Dispatched before a tool is called, contains the tool name and input data
216+ - `ToolResultEvent` : Dispatched after a tool has been called, contains the result of the tool call
217+ - `ToolCallExceptionEvent` : Dispatched when a tool throws an exception, contains the tool name, input data and throwable
218+
219+ Example of event listener :
220+ ` ` ` php
221+ use Ecourty\M cpServerBundle\E vent\T oolCallEvent;
222+ use Symfony\C omponent\E ventDispatcher\A ttribute\A sEventListener;
223+
224+ #[AsEventListener(event: ToolCallEvent::class)]
225+ class ToolCallListener
226+ {
227+ public function __invoke(ToolCallEvent $event): void
228+ {
229+ // Your logic here...
230+ }
231+ }
232+ ` ` `
233+
228234# ## Input Schema Management
229235
230236The bundle provides robust input validation and sanitization through schema-based deserialization.
@@ -262,6 +268,125 @@ class CreateUser
262268
263269This ensures that your tool handlers always receive properly validated and sanitized data.
264270
271+ # ## JSON-RPC Integration
272+
273+ - **`tools/list`**: Lists all available tools and their definitions.
274+ - **`tools/call`**: Executes a tool by name, with the provided input data.
275+
276+ # # Prompts
277+
278+ Prompts are reusable templates that can be dynamically generated and returned by the MCP server.
279+ They are useful for providing context, instructions, or any structured message to clients, and can accept arguments for dynamic content.
280+
281+ # ## Creating Prompts
282+
283+ 1. **Define a prompt class**
284+ - Use the `#[AsPrompt]` attribute to register your prompt.
285+ - The class should implement the `__invoke` method, which receives an `ArgumentCollection` and returns a `PromptResult`.
286+ - Arguments are defined using the `Argument` class (name, description, required, allowUnsafe), within the `#[AsPrompt]` declaration.
287+
288+ **Example:**
289+ ` ` ` php
290+ <?php
291+
292+ namespace App\P rompt;
293+
294+ use Ecourty\M cpServerBundle\A ttribute\A sPrompt;
295+ use Ecourty\M cpServerBundle\E num\P romptRole;
296+ use Ecourty\M cpServerBundle\I O\P rompt\C ontent\T extContent;
297+ use Ecourty\M cpServerBundle\P rompt\A rgument;
298+ use Ecourty\M cpServerBundle\I O\P rompt\P romptResult;
299+ use Ecourty\M cpServerBundle\I O\P rompt\P romptMessage;
300+ use Ecourty\M cpServerBundle\P rompt\A rgumentCollection;
301+
302+ #[AsPrompt(
303+ name: 'code_review', // Unique identifier for the prompt,
304+ description: 'Ask for a code review on a provided piece of code', // Description of the prompt
305+ arguments: [
306+ new Argument(name: 'code', description: 'The code snippets to review', required: true, allowUnsafe: true), // Required argument
307+ new Argument(name: 'language', description: 'The name of the person to greet', required: false), // Optional argument
308+ new Argument(name: 'reviewer_level', description: 'The level of review (senior / intermediate / junior...)', required: false), // Optional argument
309+ ],
310+ )]
311+ class CodeReviewPrompt
312+ {
313+ public function __invoke(ArgumentCollection $arguments): PromptResult
314+ {
315+ $code = $arguments->get('code');
316+ $language = $arguments->get('language');
317+ $reviewerLevel = $arguments->get('reviewer_level') ?: 'senior';
318+
319+ $systemMessage = <<<PROMPT
320+ You are a $reviewerLevel code reviewer.
321+ You will be provided with a piece of code in $language.
322+ Your task is to review the code and provide feedback on its quality, readability, and any potential issues.
323+ PROMPT;
324+
325+ $userMessage = <<<PROMPT
326+ Review the following code snippet: $code
327+ PROMPT;
328+
329+ return new PromptResult(
330+ description: 'Code Review Prompt',
331+ messages: [
332+ new PromptMessage(
333+ role: PromptRole::SYSTEM,
334+ content: new TextContent($systemMessage),
335+ ),
336+ new PromptMessage(
337+ role: PromptRole::USER,
338+ content: new TextContent($userMessage),
339+ ),
340+ ]
341+ );
342+ }
343+ }
344+ ` ` `
345+
346+ # ## Prompt Results
347+
348+ A prompt must return an instance of `PromptResult`, which contains :
349+ - A `description` (string)
350+ - An array of `PromptMessage` objects (each with a role and content)
351+
352+ **Example:**
353+ ` ` ` php
354+ return new PromptResult(
355+ description: 'Greeting',
356+ messages: [
357+ new PromptMessage(role: PromptRole::SYSTEM, content: new TextContent('You are a friendly assistant.')),
358+ new PromptMessage(role: PromptRole::USER, content: new TextContent('Hello, how are you?')),
359+ ]
360+ );
361+ ` ` `
362+
363+ # ## Prompt Events
364+
365+ The bundle provides several events for prompts :
366+ - `PromptGetEvent` : Dispatched before a prompt is generated
367+ - `PromptResultEvent` : Dispatched after a prompt is generated
368+ - `PromptExceptionEvent` : Dispatched if an error occurs during prompt generation
369+
370+ **Example of event listener:**
371+ ` ` ` php
372+ use Ecourty\M cpServerBundle\E vent\P rompt\P romptExceptionEvent;
373+ use Symfony\C omponent\E ventDispatcher\A ttribute\A sEventListener;
374+
375+ #[AsEventListener(event: PromptExceptionEvent::class)]
376+ class PromptGetListener
377+ {
378+ public function __invoke(PromptExceptionEvent $event): void
379+ {
380+ // Your logic here...
381+ }
382+ }
383+ ` ` `
384+
385+ # ## JSON-RPC Integration
386+
387+ - **`prompts/list`**: Lists all available prompts and their definitions.
388+ - **`prompts/get`**: Retrieves and generates a prompt by name, with arguments.
389+
265390# # JSON-RPC Methods
266391
267392The bundle provides a robust system for handling JSON-RPC requests.
@@ -283,6 +408,16 @@ The bundle provides a robust system for handling JSON-RPC requests.
283408 - Handles input validation and tool execution
284409 - Returns the tool's result or error information
285410
411+ 4. **`prompts/list`**
412+ - Lists all available prompts and their definitions
413+ - Returns prompt names, descriptions, and argument schemas
414+ - Useful for clients to discover available prompts
415+
416+ 5. **`prompts/get`**
417+ - Retrieves a specific prompt by its name and generates it with the provided arguments
418+ - Validates and sanitizes arguments, then returns the generated prompt content
419+ - Returns an error if the prompt is not found or arguments are invalid
420+
286421These methods are automatically registered and handled by the bundle. You don't need to implement them yourself.
287422
288423# ## Custom Methods
@@ -327,7 +462,7 @@ The bundle provides several tools to help you during development:
327462
328463# ## Debug Command
329464
330- The `debug:mcp-tools` command helps you inspect and debug your MCP tools :
465+ 1. The `debug:mcp-tools` command helps you inspect and debug your MCP tools :
331466
332467` ` ` bash
333468# List all registered tools
@@ -342,6 +477,20 @@ This command is particularly useful for:
342477- Checking input schemas
343478- Validating tool annotations
344479
480+ 2. The `debug:mcp-prompts` command helps you inspect and debug your MCP prompts :
481+
482+ ` ` ` bash
483+ # List all registered prompts
484+ php bin/console debug:mcp-prompts
485+
486+ # Get detailed information about a specific prompt
487+ php bin/console debug:mcp-prompts my_prompt_name
488+ ` ` `
489+
490+ This command is particularly useful for :
491+ - Verifying prompt registration
492+ - Checking argument
493+
345494# # Contributing
346495
347496Contributions to the MCP Server Bundle are welcome! Here's how you can help :
0 commit comments