MCP Registry Architecture
Model Context Protocol hub for tool and context sharing
Overview
The MCP Registry provides centralized management for Model Context Protocol (MCP) servers, enabling standardized tool registration, discovery, and context sharing across AI agents and applications.
Technology: TypeScript, JSON-RPC 2.0, Drupal Module Protocol: MCP v1.0
Architecture
graph TB
subgraph "Client Layer"
Agents[AI Agents]
Drupal[Drupal Platform]
CLI[BuildKit CLI]
end
subgraph "MCP Registry Core"
API[MCP Registry API]
Discovery[Server Discovery]
Validation[Protocol Validation]
Routing[Request Routing]
end
subgraph "MCP Servers"
FS[Filesystem Server<br/>Port 3001]
DB[PostgreSQL Server<br/>Port 3002]
Mem[Memory Server<br/>Port 3003]
Git[Git Server<br/>Port 3004]
Custom[Custom Servers]
end
subgraph "Storage"
Redis[(Redis<br/>Server Registry)]
Postgres[(PostgreSQL<br/>Metadata)]
end
Agents --> API
Drupal --> API
CLI --> API
API --> Discovery
API --> Validation
API --> Routing
Routing --> FS
Routing --> DB
Routing --> Mem
Routing --> Git
Routing --> Custom
Discovery --> Redis
Validation --> Postgres
Core Components
MCP Server Registry
import { MCPRegistry } from '@bluefly/mcp-registry'
const registry = new MCPRegistry({
storage: 'redis://localhost:6379',
ttl: 300000 // 5 minutes
})
// Register MCP server
await registry.register({
name: 'filesystem-server',
url: 'http://localhost:3001',
protocol: 'json-rpc-2.0',
version: '1.0',
capabilities: {
tools: ['read_file', 'write_file', 'list_directory', 'search_files'],
resources: ['file://', 'directory://'],
prompts: ['code_review', 'documentation']
},
metadata: {
author: 'Bluefly',
description: 'Filesystem operations via MCP',
tags: ['filesystem', 'io']
}
})
// List all registered servers
const servers = await registry.list({
filter: {
capabilities: ['tools'],
tags: ['filesystem']
}
})
// Get specific server
const server = await registry.get('filesystem-server')
Server Discovery
import { MCPDiscovery } from '@bluefly/mcp-registry/discovery'
const discovery = new MCPDiscovery({
interval: 60000, // 1 minute
healthCheck: true
})
// Auto-discover MCP servers
discovery.on('server-found', async (server) => {
console.log(`Discovered MCP server: ${server.name}`)
await registry.register(server)
})
discovery.on('server-lost', async (serverName) => {
console.log(`MCP server lost: ${serverName}`)
await registry.deregister(serverName)
})
// Start discovery
await discovery.start()
Protocol Validation
import { MCPValidator } from '@bluefly/mcp-registry/validator'
const validator = new MCPValidator()
// Validate server compliance
const result = await validator.validate({
serverUrl: 'http://localhost:3001',
tests: [
'handshake',
'list-tools',
'invoke-tool',
'error-handling'
]
})
// {
// compliant: true,
// version: '1.0',
// results: {
// handshake: { passed: true },
// 'list-tools': { passed: true, tools: 4 },
// 'invoke-tool': { passed: true },
// 'error-handling': { passed: true }
// }
// }
MCP Server Types
Filesystem Server
Port: 3001 Capabilities: File I/O operations
// Available tools
const tools = [
'read_file', // Read file contents
'write_file', // Write to file
'list_directory', // List directory contents
'search_files', // Search files by pattern
'file_info' // Get file metadata
]
// Example: Read file
const response = await mcpClient.invokeTool('read_file', {
path: '/path/to/file.ts'
})
PostgreSQL Server
Port: 3002 Capabilities: Database operations
// Available tools
const tools = [
'query', // Execute SQL query (read-only)
'describe_table', // Get table schema
'list_tables', // List all tables
'list_schemas' // List all schemas
]
// Example: Query database
const response = await mcpClient.invokeTool('query', {
sql: 'SELECT * FROM users WHERE active = true LIMIT 10'
})
Memory Server
Port: 3003 Capabilities: Knowledge graph operations
// Available tools
const tools = [
'create_entities', // Create knowledge entities
'create_relations', // Create relationships
'add_observations', // Add observations to entities
'search_nodes', // Search knowledge graph
'read_graph' // Read entire graph
]
// Example: Create entity
const response = await mcpClient.invokeTool('create_entities', {
entities: [
{
name: 'LLM Platform',
entityType: 'software',
observations: ['Enterprise AI orchestration system']
}
]
})
Git Server
Port: 3004 Capabilities: Git operations
// Available tools
const tools = [
'clone', // Clone repository
'commit', // Create commit
'push', // Push changes
'pull', // Pull changes
'branch', // Create/switch branch
'status' // Get git status
]
// Example: Create commit
const response = await mcpClient.invokeTool('commit', {
message: 'feat: add new feature',
files: ['src/**/*.ts']
})
Client Integration
TypeScript Client
import { MCPClient } from '@bluefly/mcp-registry/client'
const client = new MCPClient({
registryUrl: 'http://localhost:3000/api/v1/mcp'
})
// Connect to server
await client.connect('filesystem-server')
// List available tools
const tools = await client.listTools()
// Invoke tool
const result = await client.invokeTool('read_file', {
path: 'src/api/users.ts'
})
// Disconnect
await client.disconnect()
Drupal Module
<?php
namespace Drupal\mcp_registry;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
class MCPClient implements ContainerInjectionInterface {
public function invokeTool(string $server, string $tool, array $args): array {
$registry = \Drupal::service('mcp_registry.registry');
$server_config = $registry->get($server);
$client = new \GuzzleHttp\Client();
$response = $client->post($server_config['url'], [
'json' => [
'jsonrpc' => '2.0',
'method' => "tools/{$tool}",
'params' => $args,
'id' => uniqid()
]
]);
return json_decode($response->getBody(), TRUE);
}
}
API Reference
List Servers
GET /api/v1/mcp/servers
Authorization: Bearer YOUR_API_KEY
Response:
{
"servers": [
{
"name": "filesystem-server",
"url": "http://localhost:3001",
"capabilities": {
"tools": ["read_file", "write_file"],
"resources": ["file://"],
"prompts": []
},
"status": "healthy"
}
]
}
Get Server
GET /api/v1/mcp/servers/filesystem-server
Authorization: Bearer YOUR_API_KEY
List Tools
GET /api/v1/mcp/servers/filesystem-server/tools
Authorization: Bearer YOUR_API_KEY
Invoke Tool
POST /api/v1/mcp/invoke
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY
{
"server": "filesystem-server",
"tool": "read_file",
"args": {
"path": "/path/to/file.ts"
}
}
Configuration
# config/mcp.yaml
mcp:
registry:
storage: redis://localhost:6379
ttl: 300000
discovery:
enabled: true
interval: 60000
healthCheck: true
servers:
filesystem:
url: http://localhost:3001
enabled: true
auth:
type: bearer
token: ${MCP_FILESYSTEM_TOKEN}
postgres:
url: http://localhost:3002
enabled: true
auth:
type: basic
username: ${MCP_POSTGRES_USER}
password: ${MCP_POSTGRES_PASSWORD}
memory:
url: http://localhost:3003
enabled: true
validation:
enabled: true
strict: true
tests:
- handshake
- list-tools
- invoke-tool