@gala-chain/launchpad-mcp-server
Version:
MCP server for Gala Launchpad - 102 tools (pool management, event watchers, GSwap DEX trading, price history, token creation, wallet management, DEX pool discovery, liquidity positions, token locks, locked token queries, composite pool data, cross-chain b
272 lines (210 loc) • 8.58 kB
Markdown
# DRY Refactoring Guide for MCP Server Prompts
This guide documents the DRY (Don't Repeat Yourself) refactoring improvements made to the MCP server codebase.
## Overview
The refactoring reduces code duplication across 72 prompt handlers by introducing reusable utilities while maintaining 100% API compatibility.
**Potential Impact:** ~526 LOC reduction with zero breaking changes
## Utility Files Created
### 1. `src/prompts/utils/handlerHelpers.ts`
Provides reusable helpers for creating standardized MCP prompt handlers.
**Functions:**
- `createPromptResponse(text: string)` - Creates a standard MCP message response
- `createValidatedHandler<T>(validator, textGenerator)` - Creates a handler with validation + response generation
**Benefit:** Eliminates ~360 lines of boilerplate (5 lines per handler × 72 handlers)
### 2. `src/prompts/utils/textTemplates.ts`
Provides template generators for common prompt patterns.
**Functions:**
- `createSimpleOperationText(config)` - Generates text for simple operation prompts following standard format
**Benefit:** Eliminates ~120 lines of template code (~3 lines per simple prompt × 40 prompts)
### 3. Updated `src/utils/validation.ts`
Added optional validation convenience wrappers.
**New Functions:**
- `validateOptional<T>(value, validator)` - Generic optional field validator
- `validateOptionalSlippage(slippage?)` - Optional slippage validation
- `validateOptionalLimit(limit?, max)` - Optional limit validation
- `validateOptionalAddress(address?)` - Optional address validation
**Benefit:** Eliminates ~46 lines of conditional validation (2 lines × 23 instances)
## Refactoring Patterns
### Pattern 1: Standardized Handler Response
**Before:**
```typescript
handler: (args) => {
validateTokenName(args.tokenName);
return [
{
role: 'user',
content: {
type: 'text',
text: `Fetch token ${args.tokenName}...`,
},
},
];
}
```
**After:**
```typescript
import { createPromptResponse } from './utils/handlerHelpers.js';
handler: (args) => {
validateTokenName(args.tokenName);
return createPromptResponse(`Fetch token ${args.tokenName}...`);
}
```
**Where to Apply:**
- All 72 prompt handlers across all prompt files
- Any prompt file in `src/prompts/*.ts`
### Pattern 2: Optional Validation
**Before:**
```typescript
if (args.slippage) {
validateSlippage(args.slippage);
}
if (args.limit) {
validatePaginationLimit(args.limit, 100);
}
if (args.address) {
validateAddress(args.address);
}
```
**After:**
```typescript
import { validateOptionalSlippage, validateOptionalLimit, validateOptionalAddress } from '../utils/validation.js';
validateOptionalSlippage(args.slippage);
validateOptionalLimit(args.limit, 100);
validateOptionalAddress(args.address);
```
**Where to Apply:**
- `trading.ts` - 6 slippage validations
- `portfolio.ts` - 3 limit validations
- `analysis.ts` - 4 limit validations, 3 tokenName optional checks
- `balances.ts` - 4 address validations
- Other prompt files with optional parameters
### Pattern 3: Simple Operation Text Templates
**Before:**
```typescript
text: `Fetch GALA balance for wallet.
${args.address ? `Address: ${args.address}` : 'Using default wallet'}
Use ${MCP_TOOLS.FETCH_GALA_BALANCE} to retrieve the GALA balance.
Display the balance in a clear format.`
```
**After:**
```typescript
import { createSimpleOperationText } from './utils/textTemplates.js';
text: createSimpleOperationText({
operation: 'Fetch GALA balance for wallet.',
parameters: {
address: args.address ? `Address: ${args.address}` : 'Using default wallet'
},
toolName: MCP_TOOLS.FETCH_GALA_BALANCE,
actionDescription: 'retrieve the GALA balance',
displayFormat: 'Display the balance in a clear format.'
})
```
**Where to Apply:**
- All 40+ simple operation prompts across prompt files
- Prompts that follow the operation → parameters → tool usage → display format structure
## Implementation Checklist
### Phase 1: Handler Boilerplate (Highest Priority)
- [ ] Update all imports in prompt files to include `createPromptResponse`
- [ ] Replace all `return [{ role: 'user', content: { type: 'text', text: ... } }]` with `return createPromptResponse(...)`
- [ ] Files to update:
- [ ] `pools.ts` (14 handlers)
- [ ] `trading-calculations.ts` (11 handlers)
- [ ] `balances.ts` (4 handlers)
- [ ] `creation-utils.ts` (3 handlers)
- [ ] `transfers.ts` (2 handlers)
- [ ] `utility-tools.ts` (12 handlers)
- [ ] All other prompt files (existing, not listed)
### Phase 2: Optional Validation (High Priority)
- [ ] Update imports in prompt files
- [ ] Replace conditional validation patterns with new optional validators
- [ ] High-impact files:
- [ ] `trading.ts` (6 instances)
- [ ] `portfolio.ts` (7 instances)
- [ ] `analysis.ts` (7 instances)
- [ ] `balances.ts` (4 instances)
### Phase 3: Text Templates (Medium Priority)
- [ ] Identify all simple operation prompts
- [ ] Update imports
- [ ] Replace template code with `createSimpleOperationText()`
- [ ] Estimated 40 prompts across multiple files
### Phase 4: Verification
- [ ] Run TypeScript compilation: `npx tsc --noEmit`
- [ ] Run tests: `npm test`
- [ ] Run linting: `npm run lint`
- [ ] Verify no regression in test count (should remain 1401+ passing)
- [ ] Verify all prompts produce identical output
## Code Sample: Complete Refactored Handler
### Before:
```typescript
export const fetchGalaSpotPricePrompt: MCPPrompt = {
name: 'galachain-launchpad:fetch-gala-spot-price',
description: 'Fetch current GALA USD spot price',
handler: () => {
return [
{
role: 'user',
content: {
type: 'text',
text: `Fetch the current GALA USD spot price.
Use ${MCP_TOOLS.FETCH_GALA_SPOT_PRICE} to get the latest GALA price in USD.
Display the price in a clear format.`,
},
},
];
},
};
```
### After:
```typescript
import { createPromptResponse } from './utils/handlerHelpers.js';
import { createSimpleOperationText } from './utils/textTemplates.js';
export const fetchGalaSpotPricePrompt: MCPPrompt = {
name: 'galachain-launchpad:fetch-gala-spot-price',
description: 'Fetch current GALA USD spot price',
handler: () =>
createPromptResponse(
createSimpleOperationText({
operation: 'Fetch the current GALA USD spot price.',
toolName: MCP_TOOLS.FETCH_GALA_SPOT_PRICE,
actionDescription: 'get the latest GALA price in USD',
displayFormat: 'Display the price in a clear format.'
})
),
};
```
## Benefits
| Aspect | Benefit |
|--------|---------|
| **Maintainability** | Single point of change for response structure, validation logic, and text formatting |
| **Consistency** | All prompts follow identical patterns, easier to understand and predict behavior |
| **Testability** | Utility functions can be tested independently |
| **Scalability** | Adding new prompts is faster and less error-prone |
| **LOC Reduction** | ~526 lines of boilerplate eliminated |
| **API Compatibility** | Zero breaking changes, 100% backward compatible |
## Testing Strategy
1. **Unit Tests:** Add tests for utility functions if not present
2. **Integration Tests:** Verify all 72 prompts still produce identical output
3. **Regression Tests:** Ensure no prompt behavior changes
4. **Type Safety:** Full TypeScript compilation with strict checks
## Timeline
- **Phase 1 (Handler Boilerplate):** ~1 hour (72 handlers, mechanical change)
- **Phase 2 (Optional Validation):** ~30 minutes (23 instances)
- **Phase 3 (Text Templates):** ~45 minutes (40 prompts)
- **Phase 4 (Testing/Verification):** ~15 minutes
- **Total:** ~2.5 hours for complete refactoring
## Risk Assessment
| Phase | Risk | Mitigation |
|-------|------|-----------|
| 1 | **LOW** | Pure mechanical change, output unchanged | Full test coverage |
| 2 | **LOW** | Logic preservation via wrappers | Verify validation behavior |
| 3 | **LOW** | Template-based generation | Compare output strings |
| Overall | **LOW** | No API changes, well-tested utilities | Comprehensive testing |
## Notes
- All changes are internal implementation details
- No MCP tool signatures change
- All changes follow DRY principle without adding unnecessary complexity
- Utilities are properly documented with JSDoc comments
- Both new utility files include comprehensive examples
## See Also
- `src/prompts/utils/handlerHelpers.ts` - Handler utilities
- `src/prompts/utils/textTemplates.ts` - Template utilities
- `src/utils/validation.ts` - Validation utilities (updated)