Skip to content

Commit ff8e1a0

Browse files
author
klapaudius
committed
#33 Expand documentation with sampling support details and interfaces
- Updated sampling documentation to include `SamplingAwareToolInterface`, `SamplingAwarePromptInterface`, and `SamplingAwareResourceInterface`. - Added examples and best practices for tools, prompts, and resources leveraging sampling. - Enhanced `building_prompts.md`, `building_tools.md`, and `building_resources.md` with more detailed usage cases. - Introduced links to sampling-specific content in index and relevant sections.
1 parent bb6983e commit ff8e1a0

File tree

5 files changed

+367
-11
lines changed

5 files changed

+367
-11
lines changed

docs/building_prompts.md

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ This guide provides a comprehensive walkthrough for creating MCP prompts in the
66
1. [Understanding MCP Prompts](#understanding-mcp-prompts)
77
2. [Quick Start with make:mcp-prompt](#quick-start-with-makemcp-prompt)
88
3. [Basic Prompt Implementation](#basic-prompt-implementation)
9-
4. [Advanced Prompt Features](#advanced-prompt-features)
10-
5. [Multi-Modal Prompts](#multi-modal-prompts)
11-
6. [Dynamic Prompts with Arguments](#dynamic-prompts-with-arguments)
12-
7. [Best Practices](#best-practices)
9+
4. [SamplingAwarePromptInterface](#samplingawarepromptinterface)
10+
5. [Advanced Prompt Features](#advanced-prompt-features)
11+
6. [Multi-Modal Prompts](#multi-modal-prompts)
12+
7. [Dynamic Prompts with Arguments](#dynamic-prompts-with-arguments)
13+
8. [Best Practices](#best-practices)
1314

1415
## Understanding MCP Prompts
1516

@@ -146,6 +147,92 @@ klp_mcp_server:
146147
class: App\Mcp\Prompts\BlogPostPrompt
147148
```
148149
150+
151+
152+
## SamplingAwarePromptInterface
153+
154+
For prompts that need to make LLM sampling requests during message generation, implement the `SamplingAwarePromptInterface`. This interface extends `PromptInterface` and provides access to a `SamplingClient` for creating nested LLM calls.
155+
156+
### When to Use Sampling
157+
158+
Use sampling in prompts that need:
159+
- Dynamic question generation based on input content
160+
- Context-specific prompt adaptation
161+
- AI-enhanced prompt customization
162+
- Analysis of user input to tailor prompt messages
163+
164+
### Implementation
165+
166+
```php
167+
use KLP\KlpMcpServer\Services\PromptService\SamplingAwarePromptInterface;
168+
use KLP\KlpMcpServer\Services\SamplingService\SamplingClient;
169+
use KLP\KlpMcpServer\Services\SamplingService\ModelPreferences;
170+
171+
class AdaptiveReviewPrompt implements SamplingAwarePromptInterface
172+
{
173+
private ?SamplingClient $samplingClient = null;
174+
175+
public function setSamplingClient(SamplingClient $samplingClient): void
176+
{
177+
$this->samplingClient = $samplingClient;
178+
}
179+
180+
public function getMessages(array $arguments = []): CollectionPromptMessage
181+
{
182+
$content = $arguments['content'] ?? '';
183+
184+
$collection = new CollectionPromptMessage([
185+
new TextPromptMessage('system', 'You are an expert reviewer.')
186+
]);
187+
188+
// Generate dynamic questions if sampling is available
189+
if ($this->samplingClient !== null && $this->samplingClient->canSample()) {
190+
$dynamicQuestions = $this->generateQuestions($content);
191+
if ($dynamicQuestions) {
192+
$collection->addMessage(
193+
new TextPromptMessage('user', $dynamicQuestions)
194+
);
195+
}
196+
}
197+
198+
$collection->addMessage(
199+
new TextPromptMessage('user', "Please review: {$content}")
200+
);
201+
202+
return $collection;
203+
}
204+
205+
private function generateQuestions(string $content): ?string
206+
{
207+
try {
208+
$prompt = "Generate specific review questions for: " . $content;
209+
210+
$response = $this->samplingClient->createTextRequest(
211+
$prompt,
212+
new ModelPreferences(
213+
hints: [['name' => 'claude-3-haiku']],
214+
speedPriority: 0.8
215+
),
216+
null,
217+
300
218+
);
219+
220+
return $response->getContent()->getText();
221+
} catch (\Exception $e) {
222+
return null; // Fallback gracefully
223+
}
224+
}
225+
}
226+
```
227+
228+
### Best Practices
229+
230+
- Always check if sampling is available with `canSample()`
231+
- Handle sampling failures gracefully with fallbacks
232+
- Use faster models for prompt generation (like Haiku)
233+
- Keep token limits reasonable for prompt generation
234+
- Cache results when appropriate to avoid repeated calls
235+
149236
## Advanced Prompt Features
150237

151238
### Content Strategy Prompt with Multiple Messages

docs/building_resources.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
# Building MCP Resources - Complete Walkthrough
22

3+
## Table of Contents
4+
1. [Introduction to Resources in Model Context Protocol (MCP)](#introduction-to-resources-in-model-context-protocol-mcp)
5+
2. [What are MCP Resources?](#what-are-mcp-resources)
6+
3. [Types of Resources](#types-of-resources)
7+
4. [Creating Your First MCP Resource](#creating-your-first-mcp-resource)
8+
5. [Understanding the Resource Interfaces](#understanding-the-resource-interfaces)
9+
6. [SamplingAwareResourceInterface](#samplingawareresourceinterface)
10+
7. [Using the Resource Class](#using-the-resource-class)
11+
8. [Advanced Resource Development](#advanced-resource-development)
12+
9. [Best Practices for MCP Resource Development](#best-practices-for-mcp-resource-development)
13+
10. [Example Resources](#example-resources)
14+
11. [Conclusion](#conclusion)
15+
316
## Introduction to Resources in Model Context Protocol (MCP)
417

518
Resources in the Model Context Protocol (MCP) are data objects that can be accessed by Large Language Models (LLMs) through the MCP server. Unlike tools, which provide functionality, resources provide data that LLMs can reference or use in their processing. Resources enable LLMs to:
@@ -155,6 +168,79 @@ Resource templates must implement the `ResourceTemplateInterface`, which extends
155168
- Checks if a resource with the given URI exists
156169
- Returns true if the resource exists, false otherwise
157170

171+
## SamplingAwareResourceInterface
172+
173+
For resources that need to make LLM sampling requests during data generation, implement the `SamplingAwareResourceInterface`. This interface extends `ResourceInterface` and provides access to a `SamplingClient` for creating nested LLM calls.
174+
175+
### When to Use Sampling
176+
177+
Use sampling in resources that need:
178+
- Dynamic content generation based on project data
179+
- AI-enhanced summaries or analysis
180+
- Content that adapts based on context
181+
- Natural language processing of existing data
182+
183+
### Implementation
184+
185+
```php
186+
use KLP\KlpMcpServer\Services\ResourceService\SamplingAwareResourceInterface;
187+
use KLP\KlpMcpServer\Services\SamplingService\SamplingClient;
188+
use KLP\KlpMcpServer\Services\SamplingService\ModelPreferences;
189+
190+
class ProjectAnalysisResource implements SamplingAwareResourceInterface
191+
{
192+
private ?SamplingClient $samplingClient = null;
193+
private ?string $cachedData = null;
194+
195+
public function setSamplingClient(SamplingClient $samplingClient): void
196+
{
197+
$this->samplingClient = $samplingClient;
198+
$this->cachedData = null; // Clear cache when client changes
199+
}
200+
201+
public function getData(): string
202+
{
203+
if ($this->cachedData !== null) {
204+
return $this->cachedData;
205+
}
206+
207+
if ($this->samplingClient === null || !$this->samplingClient->canSample()) {
208+
return 'Static fallback content when sampling is not available';
209+
}
210+
211+
try {
212+
$projectInfo = $this->gatherProjectInfo();
213+
$prompt = "Analyze this project: " . json_encode($projectInfo);
214+
215+
$response = $this->samplingClient->createTextRequest(
216+
$prompt,
217+
new ModelPreferences(
218+
hints: [['name' => 'claude-3-sonnet']],
219+
intelligencePriority: 0.8
220+
),
221+
null,
222+
2000 // max tokens
223+
);
224+
225+
$this->cachedData = $response->getContent()->getText() ?? 'No analysis generated';
226+
return $this->cachedData;
227+
} catch (\Exception $e) {
228+
return 'Error generating analysis: ' . $e->getMessage();
229+
}
230+
}
231+
232+
// ... other required interface methods
233+
}
234+
```
235+
236+
### Best Practices
237+
238+
- Always check if sampling is available with `canSample()`
239+
- Implement caching to avoid repeated expensive LLM calls
240+
- Provide fallback content when sampling fails
241+
- Handle sampling failures gracefully
242+
- Clear cache when sampling client changes
243+
158244
## Using the Resource Class
159245

160246
For simple resources, you can use the provided `Resource` class instead of implementing the interface from scratch:

docs/building_tools.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Building MCP Tools - Complete Walkthrough
22

3+
## Table of Contents
4+
1. [Introduction to Model Context Protocol (MCP)](#introduction-to-model-context-protocol-mcp)
5+
2. [What are MCP Tools?](#what-are-mcp-tools)
6+
3. [Creating Your First MCP Tool](#creating-your-first-mcp-tool)
7+
4. [Understanding the Tool Interface](#understanding-the-tool-interface)
8+
5. [Tool Result Types](#tool-result-types)
9+
6. [Testing Your MCP Tools](#testing-your-mcp-tools)
10+
7. [Streaming Tools with Progress Notifications](#streaming-tools-with-progress-notifications)
11+
8. [SamplingAwareToolInterface](#samplingawaretoolinterface)
12+
9. [Advanced Tool Development](#advanced-tool-development)
13+
10. [Best Practices for MCP Tool Development](#best-practices-for-mcp-tool-development)
14+
11. [Example Tools](#example-tools)
15+
12. [Conclusion](#conclusion)
16+
317
## Introduction to Model Context Protocol (MCP)
418

519
The Model Context Protocol (MCP) is a standardized communication protocol that enables Large Language Models (LLMs) to interact with external systems and services. MCP allows LLMs to:
@@ -696,6 +710,64 @@ class FileProcessingTool implements StreamableToolInterface
696710
}
697711
```
698712

713+
## SamplingAwareToolInterface
714+
715+
For tools that need to make LLM sampling requests during execution, implement the `SamplingAwareToolInterface`. This interface extends `StreamableToolInterface` and provides access to a `SamplingClient` for creating nested LLM calls.
716+
717+
### When to Use Sampling
718+
719+
Use sampling in tools that need:
720+
- Code analysis and recommendations
721+
- Content generation or transformation
722+
- Complex reasoning tasks
723+
- Natural language processing
724+
725+
### Implementation
726+
727+
```php
728+
use KLP\KlpMcpServer\Services\SamplingService\SamplingClient;
729+
use KLP\KlpMcpServer\Services\SamplingService\ModelPreferences;
730+
use KLP\KlpMcpServer\Services\ToolService\SamplingAwareToolInterface;
731+
732+
class MyAnalysisTool implements SamplingAwareToolInterface
733+
{
734+
private ?SamplingClient $samplingClient = null;
735+
736+
public function setSamplingClient(SamplingClient $samplingClient): void
737+
{
738+
$this->samplingClient = $samplingClient;
739+
}
740+
741+
public function execute(array $arguments): ToolResultInterface
742+
{
743+
if ($this->samplingClient === null || !$this->samplingClient->canSample()) {
744+
return new TextToolResult('This tool requires LLM sampling capability');
745+
}
746+
747+
$prompt = "Analyze this data: " . $arguments['data'];
748+
749+
$response = $this->samplingClient->createTextRequest(
750+
$prompt,
751+
new ModelPreferences(
752+
hints: [['name' => 'claude-3-sonnet']],
753+
intelligencePriority: 0.8
754+
),
755+
null,
756+
2000 // max tokens
757+
);
758+
759+
return new TextToolResult($response->getContent()->getText() ?? 'No response');
760+
}
761+
}
762+
```
763+
764+
### Best Practices
765+
766+
- Always check if sampling is available with `canSample()`
767+
- Handle sampling failures gracefully
768+
- Use appropriate model preferences for your use case
769+
- Set reasonable token limits to control costs
770+
699771
## Advanced Tool Development
700772

701773
### Handling Complex Inputs

docs/index.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Welcome to the Symfony MCP Server documentation. This bundle enables developers
3333
- [Transport Layer](../README.md#why-not-stdio) - SSE vs StreamableHTTP vs STDIO
3434
- [Pub/Sub Architecture](../README.md#pubsub-architecture-with-adapters) - Message broker and adapter system
3535
- [Progress Notifications](building_tools.md#progress-notifications) - Real-time updates for long-running operations
36+
- [Sampling Feature](sampling.md) - Enable tools to make nested LLM calls for enhanced AI capabilities
3637

3738
### Configuration
3839
- [Configuration Reference](../src/Resources/config/packages/klp_mcp_server.yaml) - Complete configuration options
@@ -47,14 +48,15 @@ Welcome to the Symfony MCP Server documentation. This bundle enables developers
4748
## API Reference
4849

4950
### Interfaces
50-
- **Tools**: `StreamableToolInterface`, `BaseToolInterface` (deprecated)
51-
- **Prompts**: `PromptInterface`, `PromptMessageInterface`
52-
- **Resources**: `ResourceInterface`, `ResourceTemplateInterface`
51+
- **Tools**: `StreamableToolInterface`, `SamplingAwareToolInterface`, `ToolInterface` (deprecated)
52+
- **Prompts**: `PromptInterface`, `SamplingAwarePromptInterface`, `PromptMessageInterface`
53+
- **Resources**: `ResourceInterface`, `SamplingAwareResourceInterface`, `ResourceTemplateInterface`
5354
- **Results**: `ToolResultInterface` with Text, Image, Audio, Resource types
5455

5556
### Services
5657
- **ProgressNotifier**: Real-time progress updates
5758
- **PromptRepository**: Prompt management and retrieval
59+
- **SamplingClient**: Interface for making nested LLM calls
5860
- **MCPProtocol**: Core protocol implementation
5961

6062
## Requirements & Compatibility

0 commit comments

Comments
 (0)