Fast reference for extending vCon MCP Server functionality.
Want to extend the server?
│
├─ Need to add data browsing?
│ └─ Use: RESOURCES
│ └─ Guide: [Custom Resources](#resources)
│
├─ Want to guide users through queries?
│ └─ Use: PROMPTS
│ └─ Guide: [Custom Prompts](#prompts)
│
├─ Need to add executable operations?
│ └─ Use: TOOLS
│ └─ Guide: [Custom Tools](#tools)
│
├─ Want to package multiple features?
│ └─ Use: PLUGINS
│ └─ Guide: [Plugins](#plugins)
│
└─ Need to modify existing behavior?
└─ Use: HOOKS (via plugins)
└─ Guide: [Lifecycle Hooks](#hooks)
| Feature | Resources | Prompts | Tools | Plugins | Hooks |
|---|---|---|---|---|---|
| Purpose | Browse data | Guide queries | Execute ops | Package features | Modify behavior |
| Complexity | Low | Low | Medium | High | High |
| Read/Write | Read only | N/A | Read/Write | Both | Both |
| Parameters | In URI | In template | In schema | All methods | Via context |
| Discovery | Auto listed | Auto listed | Auto listed | Auto loaded | N/A |
| Packaging | Direct or plugin | Direct only | Direct or plugin | Module | Plugin only |
Purpose: Provide URI-based access to data (read-only).
// 1. Define resource
{
uri: 'vcon://v1/stats',
name: 'Statistics',
description: 'Overall vCon statistics',
mimeType: 'application/json'
}
// 2. Handle resolution
if (uri === 'vcon://v1/stats') {
return {
mimeType: 'application/json',
content: { total: 100, recent: 10 }
};
}- ✅ Browsing data
- ✅ Simple queries
- ✅ Dashboard stats
- ❌ Complex filtering
- ❌ Write operations
src/resources/index.ts- Add togetCoreResources()andresolveCoreResource()
Full Guide: Extending - Custom Resources
Purpose: Provide template-based guidance for queries.
// 1. Define prompt
export const myPrompt: PromptDefinition = {
name: 'find_customers',
description: 'Find customers by criteria',
arguments: [
{
name: 'criteria',
description: 'Search criteria',
required: true
}
]
};
// 2. Generate message
function generateMessage(args: Record<string, string>): string {
return `Find customers: ${args.criteria}
## Step 1: Parse criteria...
## Step 2: Choose search tool...
## Step 3: Execute search...`;
}
// 3. Add to exports
export const allPrompts = [
// ... existing ...
myPrompt
];- ✅ Guided workflows
- ✅ Complex query patterns
- ✅ Teaching users
- ❌ Simple operations
- ❌ Direct execution
src/prompts/index.ts- Add prompt definition and generator function
Full Guide: Extending - Custom Prompts
Purpose: Implement executable operations with parameters.
// 1. Define tool
export const myTool = {
name: 'analyze_sentiment',
description: 'Analyze sentiment in vCons',
inputSchema: {
type: 'object' as const,
properties: {
start_date: { type: 'string' },
end_date: { type: 'string' }
},
required: ['start_date', 'end_date']
}
};
// 2. Implement handler
export async function handleAnalyzeSentiment(
input: SentimentInput
): Promise<ToolResponse> {
const result = await performAnalysis(input);
return {
content: [{
type: 'text',
text: JSON.stringify({ success: true, result })
}]
};
}
// 3. Register in src/index.ts
switch (name) {
case 'analyze_sentiment':
return handleAnalyzeSentiment(args);
// ...
}- ✅ CRUD operations
- ✅ Complex queries
- ✅ Data transformations
- ✅ External integrations
- ❌ Simple data browsing
src/tools/my-tools.ts- Define and implementsrc/index.ts- Register in switch statement
Full Guide: Custom Tools
Purpose: Package resources, prompts, tools, and hooks as reusable modules.
// plugins/my-plugin/index.ts
import { VConPlugin } from '@vcon/mcp-server/hooks';
export default class MyPlugin implements VConPlugin {
name = 'my-plugin';
version = '1.0.0';
async initialize(config: any): Promise<void> {
console.error('✅ Plugin initialized');
}
registerTools(): Tool[] {
return [/* tools */];
}
registerResources(): Resource[] {
return [/* resources */];
}
async handleToolCall(name: string, args: any): Promise<any> {
// Handle tool execution
}
// Lifecycle hooks
async afterCreate(vcon: VCon): Promise<void> {
// Do something after vCon creation
}
}- ✅ Multiple related features
- ✅ Reusable functionality
- ✅ Distributable modules
- ✅ Proprietary features
- ❌ Quick prototypes
- ❌ Core modifications
# 1. Create plugin directory
mkdir -p plugins/my-plugin
# 2. Create plugin file
# (code above)
# 3. Load plugin
export VCON_PLUGINS_PATH=./plugins/my-plugin/index.js
# 4. Start server
npm startFull Guide: Plugin Development
Purpose: Intercept and modify operations (via plugins only).
| Hook | When Called | Can Block | Can Modify |
|---|---|---|---|
beforeCreate |
Before vCon created | ✅ Yes | ✅ vCon |
afterCreate |
After vCon created | ❌ No | ❌ No |
beforeRead |
Before vCon read | ✅ Yes | ❌ No |
afterRead |
After vCon read | ❌ No | ✅ vCon |
beforeUpdate |
Before vCon updated | ✅ Yes | ✅ Updates |
afterUpdate |
After vCon updated | ❌ No | ❌ No |
beforeDelete |
Before vCon deleted | ✅ Yes | ❌ No |
afterDelete |
After vCon deleted | ❌ No | ❌ No |
beforeSearch |
Before search | ❌ No | ✅ Criteria |
afterSearch |
After search | ❌ No | ✅ Results |
export default class AuditPlugin implements VConPlugin {
name = 'audit';
version = '1.0.0';
// Log all operations
async afterCreate(vcon: VCon, context: RequestContext): Promise<void> {
await this.logAudit('create', vcon.uuid, context.userId);
}
async afterRead(vcon: VCon, context: RequestContext): Promise<VCon> {
await this.logAudit('read', vcon.uuid, context.userId);
return vcon;
}
async beforeDelete(uuid: string, context: RequestContext): Promise<void> {
// Check if deletion is allowed
if (!await this.canDelete(uuid, context.userId)) {
throw new Error('Deletion not permitted');
}
}
// Modify search results
async afterSearch(results: VCon[], context: RequestContext): Promise<VCon[]> {
// Filter based on permissions
return results.filter(v => this.canAccess(v, context.userId));
}
}- ✅ Audit logging
- ✅ Access control
- ✅ Data transformation
- ✅ Validation rules
- ❌ New operations (use tools)
- ❌ Data browsing (use resources)
Full Guide: Plugin Development - Hooks
Resource: vcon://v1/analytics/summary
└─> Quick stats display
Tools:
└─> analyze_trends (detailed analysis)
└─> export_report (data export)
Prompt: analyze_conversation_patterns
└─> Guides users through analysis
Plugin: customer-intelligence
├─> Resources:
│ ├─> customer://profiles (browse)
│ └─> customer://profile/{id} (detail)
│
├─> Tools:
│ ├─> identify_segment (classify)
│ ├─> get_insights (analyze)
│ └─> find_similar (compare)
│
└─> Hooks:
├─> afterCreate (update profiles)
└─> afterRead (enrich data)
Plugin: compliance
├─> Tools:
│ ├─> check_compliance (validate)
│ ├─> generate_audit (report)
│ └─> apply_retention (cleanup)
│
└─> Hooks:
├─> beforeCreate (validate)
├─> beforeRead (check permissions)
├─> afterRead (redact PII)
└─> beforeDelete (check retention)
src/
├── resources/
│ └── index.ts # Add resources here
├── prompts/
│ └── index.ts # Add prompts here
├── tools/
│ ├── my-tools.ts # Create tool files
│ └── index.ts # Export tools
└── index.ts # Register tools
plugins/
└── my-plugin/
├── package.json # Plugin metadata
├── index.ts # Plugin class
├── tools.ts # Tool definitions
├── resources.ts # Resource handlers
└── hooks.ts # Lifecycle hooks
# Via MCP Inspector
npm run test:console
# Access resource
resources/list
resources/read vcon://v1/stats# Via MCP Inspector
npm run test:console
# Then use:
tools/list
tools/call my_tool {"param": "value"}
# Via test script
npm run test:tools# Via MCP Inspector
npm run test:console
# Then use:
prompts/list
prompts/get my_prompt {"arg": "value"}# Set plugin path
export VCON_PLUGINS_PATH=./plugins/my-plugin/index.js
# Start server (check logs)
npm start
# Verify plugin loaded
# Look for: "📦 Registering plugin: my-plugin"# Core configuration
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-key
# Plugin loading (comma-separated)
VCON_PLUGINS_PATH=./plugin1.js,@vendor/plugin2,./plugin3.js
# Plugin configuration
VCON_LICENSE_KEY=your-license-key
VCON_OFFLINE_MODE=falseChoose your extension approach:
-
Quick Prototype → Add directly to core
-
Reusable Module → Create plugin
-
Modify Behavior → Use hooks
- Extension Guide - Comprehensive guide with examples
- Plugin Development - Complete plugin documentation
- Custom Tools - Tool development guide
- Architecture - System design and internals
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions and community support
- Examples Directory:
examples/for reference implementations - Source Code:
src/for core implementation details
Ready to extend? Pick an approach above and start building!