← Documentation Home

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