Skip to content

Commit a289692

Browse files
committed
feat: Implement advanced tool management system with execution strategies, middleware, and factory patterns
- Added common imports for tool utilities. - Introduced execution strategies: Standard, Cached, and Batched. - Created a generic tool factory for flexible tool creation. - Developed middleware pipeline for tool execution with authentication, validation, and caching middleware. - Implemented an advanced tool builder with fluent API for tool configuration. - Enhanced tool metadata handling to support factory-created tools. - Updated tool registrar to register tools with the MCP server using modern SDK. - Established a tool registry for managing registered tools and their metadata. - Updated dependencies to ensure compatibility with new features.
1 parent 1c7d96f commit a289692

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+4656
-1149
lines changed

.vscode/mcp.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"servers": {
3+
"backstage": {
4+
"command": "node",
5+
"args": ["dist/index.cjs"],
6+
"env": {
7+
"BACKSTAGE_BASE_URL": "http://localhost:7007",
8+
"BACKSTAGE_TOKEN": "eyJ0eXAiOiJ2bmQuYmFja3N0YWdlLnVzZXIiLCJhbGciOiJFUzI1NiIsImtpZCI6Ijc2MjRjZmQxLWE1ZDgtNGJhNC1hYjFmLWU1M2I2NWRlZTIzNSJ9.eyJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjcwMDcvYXBpL2F1dGgiLCJzdWIiOiJ1c2VyOmRldmVsb3BtZW50L2d1ZXN0IiwiZW50IjpbInVzZXI6ZGV2ZWxvcG1lbnQvZ3Vlc3QiXSwiYXVkIjoiYmFja3N0YWdlIiwiaWF0IjoxNzU4MjkxMjQxLCJleHAiOjE3NTgyOTQ4NDEsInVpcCI6IkJ1aWltMzh0Z1RXWjgzY2JSTUk4UDhZdHEtTUlVdGlOSG0wOVZXR2MzQ2RmR3pCZVVIbDNyUVdWMk93NEhjSm9LSUlfU3dtTG03XzNvUzZGazM1T1lBIn0.i9JPDXMeO-N5O1XeuVjzpexekcU2ryjfdvy56Ur1QExjuk0pat2awyfJ5XPljKJ1sGLKwIy92yE-rvOdB44AxQ"
9+
}
10+
}
11+
}
12+
}

ADVANCED_PATTERNS.md

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# Advanced MCP Server Patterns
2+
3+
This document demonstrates advanced design patterns implemented in the Backstage MCP Server for enhanced tool templating, type safety, and extensibility.
4+
5+
## 🎯 Implemented Patterns
6+
7+
### 1. Generic Base Classes (`BaseTool<TParams, TResult>`)
8+
9+
**Location:** `src/utils/tools/base-tool.ts`
10+
11+
Provides type-safe tool implementation with automatic schema validation:
12+
13+
```typescript
14+
export abstract class BaseTool<TParams = Record<string, unknown>, TResult = unknown> implements ITool {
15+
protected abstract readonly paramsSchema: z.ZodSchema<TParams>;
16+
abstract executeTyped(params: TParams, context: IToolExecutionContext): Promise<TResult>;
17+
protected abstract formatResult(result: TResult): CallToolResult;
18+
}
19+
```
20+
21+
**Benefits:**
22+
- ✅ Full TypeScript IntelliSense
23+
- ✅ Automatic parameter validation
24+
- ✅ Type-safe result formatting
25+
- ✅ Consistent error handling
26+
27+
### 2. Enhanced Decorator System
28+
29+
**Location:** `src/decorators/enhanced-tool.decorator.ts`
30+
31+
Advanced decorators with automatic categorization and metadata:
32+
33+
```typescript
34+
@ReadTool({
35+
name: 'get-entity',
36+
description: 'Retrieve entity data',
37+
paramsSchema: entitySchema,
38+
cacheable: true,
39+
tags: ['entity', 'read']
40+
})
41+
export class GetEntityTool extends BaseTool<EntityParams, Entity> {
42+
// Fully type-safe implementation
43+
}
44+
```
45+
46+
**Decorator Types:**
47+
- `@ReadTool` - GET operations with caching
48+
- `@WriteTool` - POST/PUT with confirmation
49+
- `@AuthenticatedTool` - Requires authentication
50+
- `@BatchTool` - Batch operations with size limits
51+
52+
### 3. Strategy Pattern for Execution Contexts
53+
54+
**Location:** `src/utils/tools/execution-strategies.ts`
55+
56+
Different execution strategies for various scenarios:
57+
58+
```typescript
59+
// Standard execution
60+
const standardTool = ToolFactory.create()
61+
.withStrategy(new StandardExecutionStrategy())
62+
.build();
63+
64+
// Cached execution
65+
const cachedTool = ToolFactory.create()
66+
.withStrategy(new CachedExecutionStrategy(5 * 60 * 1000)) // 5 min TTL
67+
.build();
68+
69+
// Batched execution
70+
const batchTool = ToolFactory.create()
71+
.withStrategy(new BatchedExecutionStrategy())
72+
.build();
73+
```
74+
75+
### 4. Middleware Pipeline Pattern
76+
77+
**Location:** `src/utils/tools/middleware.ts`
78+
79+
Extensible middleware system for cross-cutting concerns:
80+
81+
```typescript
82+
export const AuthenticatedTool = ToolFactory
83+
.create()
84+
.use(new AuthenticationMiddleware())
85+
.use(new ValidationMiddleware())
86+
.use(new LoggingMiddleware())
87+
.build();
88+
```
89+
90+
**Built-in Middleware:**
91+
- `AuthenticationMiddleware` - Handles auth requirements
92+
- `ValidationMiddleware` - Input validation
93+
- `CachingMiddleware` - Response caching
94+
95+
### 5. Builder Pattern for Tool Configuration
96+
97+
**Location:** `src/utils/tools/tool-builder.ts`
98+
99+
Fluent API for tool creation and configuration:
100+
101+
```typescript
102+
export const MyTool = ToolFactory
103+
.createReadTool()
104+
.name('my-tool')
105+
.description('A powerful tool')
106+
.schema(mySchema)
107+
.version('1.0.0')
108+
.tags('category', 'type')
109+
.cacheable(true)
110+
.requiresConfirmation(false)
111+
.use(new ValidationMiddleware())
112+
.withStrategy(new CachedExecutionStrategy())
113+
.withClass(MyToolImplementation)
114+
.build();
115+
```
116+
117+
### 6. Plugin Architecture
118+
119+
**Location:** `src/utils/plugins/plugin-manager.ts`
120+
121+
Extensible plugin system for server enhancements:
122+
123+
```typescript
124+
export class MyPlugin implements IMcpPlugin {
125+
name = 'my-plugin';
126+
version = '1.0.0';
127+
128+
async initialize(context: IToolRegistrationContext): Promise<void> {
129+
// Register tools, add middleware, etc.
130+
}
131+
132+
async destroy(): Promise<void> {
133+
// Cleanup resources
134+
}
135+
}
136+
```
137+
138+
## 🚀 Usage Examples
139+
140+
### Basic Tool with Type Safety
141+
142+
```typescript
143+
import { BaseTool } from '../utils/tools/base-tool.js';
144+
import { ReadTool } from '../decorators/enhanced-tool.decorator.js';
145+
146+
const paramsSchema = z.object({
147+
entityRef: z.string(),
148+
fields: z.array(z.string()).optional(),
149+
});
150+
151+
@ReadTool({
152+
name: 'get-entity',
153+
description: 'Get entity by reference',
154+
paramsSchema,
155+
cacheable: true,
156+
})
157+
export class GetEntityTool extends BaseTool<z.infer<typeof paramsSchema>, Entity> {
158+
protected readonly paramsSchema = paramsSchema;
159+
160+
async executeTyped(params: z.infer<typeof paramsSchema>, context: IToolExecutionContext): Promise<Entity> {
161+
// params.entityRef is fully typed - IntelliSense works!
162+
return await context.catalogClient.getEntityByRef(params.entityRef);
163+
}
164+
165+
protected formatResult(result: Entity): CallToolResult {
166+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
167+
}
168+
}
169+
```
170+
171+
### Advanced Tool with Middleware and Strategy
172+
173+
```typescript
174+
export const AdvancedTool = ToolFactory
175+
.createWriteTool()
176+
.name('advanced-tool')
177+
.description('Advanced tool with full feature set')
178+
.schema(advancedSchema)
179+
.requiresConfirmation(true)
180+
.requiresScopes('write', 'admin')
181+
.use(new AuthenticationMiddleware())
182+
.use(new ValidationMiddleware())
183+
.use(new AuditMiddleware())
184+
.withStrategy(new CachedExecutionStrategy(10 * 60 * 1000))
185+
.withClass(AdvancedToolImpl)
186+
.build();
187+
```
188+
189+
### Plugin-Based Extensions
190+
191+
```typescript
192+
export class MetricsPlugin implements IMcpPlugin {
193+
name = 'metrics-plugin';
194+
version = '1.0.0';
195+
196+
async initialize(context: IToolRegistrationContext): Promise<void> {
197+
// Add metrics middleware to all tools
198+
context.toolRegistrar.register(
199+
ToolFactory.create()
200+
.use(new MetricsMiddleware())
201+
.build()
202+
);
203+
}
204+
}
205+
```
206+
207+
## 📊 Benefits Achieved
208+
209+
| Pattern | Benefit | Implementation |
210+
|---------|---------|----------------|
211+
| **Generics** | Type safety, IntelliSense | `BaseTool<TParams, TResult>` |
212+
| **Decorators** | Metadata, categorization | `@ReadTool`, `@WriteTool` |
213+
| **Strategy** | Execution flexibility | `CachedExecutionStrategy` |
214+
| **Middleware** | Cross-cutting concerns | Pipeline architecture |
215+
| **Builder** | Fluent configuration | `ToolFactory.create()` |
216+
| **Plugin** | Extensibility | `PluginManager` |
217+
218+
## 🔄 Migration Guide
219+
220+
### From Legacy Tools
221+
222+
```typescript
223+
// Before (Legacy)
224+
export class LegacyTool {
225+
static async execute(request, context) {
226+
// Manual validation, no type safety
227+
return result;
228+
}
229+
}
230+
231+
// After (Modern)
232+
@ReadTool({
233+
name: 'legacy-tool',
234+
description: 'Modernized legacy tool',
235+
paramsSchema: legacySchema,
236+
})
237+
export class ModernTool extends BaseTool<LegacyParams, LegacyResult> {
238+
// Full type safety, automatic validation
239+
}
240+
```
241+
242+
### Using Migration Helper
243+
244+
```typescript
245+
import { ToolMigrationHelper } from './utils/tools/migration-helper.js';
246+
247+
const modernTool = ToolMigrationHelper.migrateLegacyTool(
248+
LegacyTool,
249+
legacyMetadata,
250+
{ addCaching: true, addValidation: true }
251+
);
252+
```
253+
254+
## 🎯 Best Practices
255+
256+
1. **Use BaseTool for new implementations** - Provides type safety and consistency
257+
2. **Leverage decorators** - Automatic categorization and metadata
258+
3. **Apply middleware strategically** - Authentication, validation, caching
259+
4. **Choose execution strategies** - Standard, cached, or batched based on needs
260+
5. **Use builder pattern** - Fluent, readable tool configuration
261+
6. **Create plugins for extensions** - Keep core server clean and extensible
262+
263+
## 🔧 Configuration
264+
265+
### Environment Variables
266+
267+
```bash
268+
# Enable advanced patterns
269+
ENABLE_ADVANCED_PATTERNS=true
270+
271+
# Cache settings
272+
TOOL_CACHE_TTL=300000
273+
TOOL_CACHE_MAX_SIZE=1000
274+
275+
# Plugin settings
276+
PLUGIN_PATH=./plugins
277+
ENABLE_PLUGIN_AUTO_LOAD=true
278+
```
279+
280+
### Server Configuration
281+
282+
```typescript
283+
const server = new McpServer({
284+
// ... server config
285+
});
286+
287+
// Register advanced patterns
288+
const pluginManager = new PluginManager();
289+
pluginManager.register(new MetricsPlugin());
290+
pluginManager.register(new SecurityPlugin());
291+
292+
// Use advanced tool factory
293+
const advancedTool = ToolFactory.createReadTool()
294+
.withStrategy(new CachedExecutionStrategy())
295+
.build();
296+
```
297+
298+
This implementation provides a solid foundation for scalable, maintainable, and extensible MCP server development with modern TypeScript patterns.

0 commit comments

Comments
 (0)