Skip to main content

agent protocol mcp server

Agent Protocol MCP Server

Package: @bluefly/agent-protocol v0.1.5 Last Updated: 2026-02-17 Status: Production Source: GitLab


Table of Contents

  1. Overview
  2. Architecture
  3. Tool Reference (88 Tools)
  4. SSE Transport
  5. OpenTelemetry Integration
  6. Config Resolution System
  7. Deployment
  8. Running Locally
  9. Environment Variables
  10. MCP Resources
  11. Related Documentation

Overview

The Agent Protocol MCP Server is the central Model Context Protocol server for the BlueFly.io infrastructure. It is a single server that exposes the entire platform through the MCP standard, making all capabilities available to MCP-compatible clients such as Claude Desktop, Cursor IDE, and custom integrations.

Key Characteristics

  • SDK-native: Built on @modelcontextprotocol/sdk v1.26.0 -- no custom HTTP framework, no Express
  • Dual transport: stdio for local development (Claude Desktop, CLI) and SSE for remote deployment at mcp.blueflyagents.com via Cloudflare tunnel
  • 88 tools organized across 12 capability groups
  • OpenTelemetry instrumentation on every tool call, reporting to GitLab Observability
  • OSSA-compliant: Follows Open Standard for Sustainable Agents specification
  • Config resolution: Dynamic token substitution from workspace.json with template-based config generation

What It Connects

IntegrationDescription
GitLab UltimateIssues, MRs, pipelines, security scanning, workspaces, KAS, model registry, value stream analytics
Agent RegistryOSSA agent registration, discovery, validation, search
Platform Agentsmesh.bluefly.internal agent lifecycle and MCP server registry
Compliance/OSSAManifest validation, Cedar policy checking, OpenAPI validation, compliance auditing
Vector Search/RAGQdrant vector database indexing, semantic search, RAG queries, embeddings
KubernetesDeploy, scale, status, logs, rollback, health for k3s/k8s clusters
Drupal LLMDrupal knowledge base queries, content migration to vector store
Workflow EngineWorkflow creation, execution, status tracking, cancellation
OSSA AgentsAgent discovery, detail retrieval, execution, sync from NAS/GitLab
Knowledge GraphGitLab entity traversal, semantic search, relationship queries, context building
Acquia SourceContent CRUD, Canvas pages, component discovery via JSON:API
Config ResolutionTemplate-based config sync, OTel config, endpoint discovery, health checks

Architecture

Class Structure

The server is implemented as a single class AgentProtocolMCPServer in src/mcp/server.ts.

src/mcp/
  server.ts              # AgentProtocolMCPServer class (entry point)
  otel.ts                # OpenTelemetry instrumentation
  services/
    index.ts             # Service factory exports
    agent-registry.service.ts
    gitlab.service.ts
    compliance.service.ts
    vector-search.service.ts
    kubernetes.service.ts
    drupal-llm.service.ts
    workflow.service.ts
    ossa-agents.service.ts
    agent-sync.service.ts
    acquia-source.service.ts
    config.service.ts
  tools/
    knowledge-graph-tools.ts    # Tool definitions + handlers
    knowledge-graph-handlers.ts # Handler dispatch

SDK Usage

The server uses only official SDK types -- no custom HTTP layer:

import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { SSEServerTransport } from '@modelcontextprotocol/sdk/server/sse.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, Tool, } from '@modelcontextprotocol/sdk/types.js';

Request Flow

MCP Client (Claude Desktop / Cursor / Custom)
   |
   | JSON-RPC (stdio or SSE)
   v
AgentProtocolMCPServer
   |
   |-- ListToolsRequestSchema --> getAllTools() --> returns 88 Tool definitions
   |
   |-- CallToolRequestSchema --> recordToolCall(name, args, fn)  [OTel traced]
   |       |
   |       v
   |   executeTool(name, args)
   |       |
   |       |-- group prefix routing (name.split('.')[0])
   |       |      agent.*    --> executeAgentTool()     --> AgentRegistryService
   |       |      platform.* --> executePlatformTool()   --> BlueFlyAgentPlatformClient
   |       |      gitlab.*   --> executeGitLabTool()     --> GitLabService
   |       |      compliance.* --> executeComplianceTool() --> ComplianceService
   |       |      vector.*   --> executeVectorTool()     --> VectorSearchService
   |       |      k8s.*      --> executeKuberneTool()    --> KubernetesService
   |       |      drupal.*   --> executeDrupalTool()     --> DrupalLLMService
   |       |      workflow.* --> executeWorkflowTool()   --> WorkflowService
   |       |      ossa.*     --> executeOSSATool()       --> OSSAAgentsService
   |       |      acquia.*   --> executeAcquiaSourceTool() --> AcquiaSourceService
   |       |      config.*   --> executeConfigTool()     --> ConfigService
   |       |      (underscore prefix) --> executeKnowledgeGraphTool()
   |       |
   |       v
   |   ToolExecutionResult { success, data, error?, metadata }
   |
   |-- ListResourcesRequestSchema --> getAllResources()
   |-- ReadResourceRequestSchema  --> readResource(uri)

Tool Dispatch

The executeTool() method routes by the prefix before the first dot:

const [group] = name.split('.'); switch (group) { case 'agent': return this.executeAgentTool(name, args); case 'platform': return this.executePlatformTool(name, args); case 'gitlab': return this.executeGitLabTool(name, args); case 'compliance': return this.executeComplianceTool(name, args); case 'vector': return this.executeVectorTool(name, args); case 'k8s': return this.executeKuberneTool(name, args); case 'drupal': return this.executeDrupalTool(name, args); case 'workflow': return this.executeWorkflowTool(name, args); case 'ossa': return this.executeOSSATool(name, args); case 'acquia': return this.executeAcquiaSourceTool(name, args); case 'config': return this.executeConfigTool(name, args); default: // Knowledge graph tools use underscores (query_knowledge_graph_*) if (name.startsWith('query_knowledge_graph_') || ...) return this.executeKnowledgeGraphTool(name, args); throw new Error(`Unknown tool: ${name}`); }

Each group handler uses a dedicated service obtained via factory functions (getGitLabService(), getConfigService(), etc.) from src/mcp/services/index.ts.


Tool Reference (88 Tools)

Agent Registry (6 tools)

ToolDescriptionRequired Params
agent.registerRegister a new agent with OSSA manifestmanifest
agent.get_manifestRetrieve OSSA manifest for a registered agentagentId
agent.validate_manifestValidate OSSA compliance of an agent manifestmanifest
agent.searchSearch registry by name, tags, or capabilitiesquery
agent.listList all registered agents with pagination--
agent.updateUpdate an existing agent manifestagentId, updates

Platform Agents (6 tools)

These tools interact with the platform-agents service at mesh.bluefly.internal.

ToolDescriptionRequired Params
platform.register_agentRegister OSSA agent with platform-agents servicegaid, manifest
platform.discover_agentsDiscover registered agents by capability or provider--
platform.resolve_agentResolve agent details by GAIDgaid
platform.register_mcp_serverRegister MCP server with Drupal mcp_registry modulename, url, tools
platform.discover_mcp_serversDiscover registered MCP servers from Drupal--
platform.health_checkCheck platform-agents service health--

GitLab Ultimate (23 tools)

Core (7):

ToolDescriptionRequired Params
gitlab.create_issueCreate a new GitLab issueproject, title
gitlab.create_mrCreate a new merge requestproject, sourceBranch, title
gitlab.trigger_pipelineTrigger a CI/CD pipelineproject, ref
gitlab.get_pipeline_statusCheck pipeline statusproject, pipelineId
gitlab.list_issuesList issues with filters (state, labels)--
gitlab.update_issueUpdate an existing issueproject, issueId, updates
gitlab.merge_mrMerge an approved MRproject, mrId

Observability (6):

ToolDescriptionRequired Params
gitlab.list_deploymentsList deployments with environment/status filtersproject
gitlab.list_environmentsList environments (production, staging, etc.)project
gitlab.get_error_trackingGet error tracking configuration and client keysproject
gitlab.list_audit_eventsList audit events (GitLab Ultimate)project
gitlab.get_pipeline_metricsGet pipeline success rate, avg duration, recent pipelinesproject
gitlab.get_value_streamGet Value Stream Analytics summary (Ultimate)project

Workspaces (3):

ToolDescriptionRequired Params
gitlab.list_workspacesList remote development workspaces--
gitlab.create_workspaceCreate a workspace from a projectproject
gitlab.stop_workspaceStop a running workspaceworkspaceId

Security (2):

ToolDescriptionRequired Params
gitlab.get_vulnerabilitiesGet vulnerability findings (SAST, DAST, container, dependency)project
gitlab.get_security_reportGet security report for a pipelineproject, pipelineId, reportType

Model Registry (2):

ToolDescriptionRequired Params
gitlab.list_modelsList ML models in GitLab Model Registryproject
gitlab.get_model_versionsGet model versionsproject, modelId

KAS - Kubernetes Agent Server (2):

ToolDescriptionRequired Params
gitlab.list_agentsList GitLab Agents (KAS) for k3s/k8s cluster managementproject
gitlab.get_agent_tokensGet agent connection tokens for k3s clustersproject, agentId

Protected Environments (1):

ToolDescriptionRequired Params
gitlab.get_protected_environmentsGet protected environment configs with approval gatesproject

Compliance/OSSA (5 tools)

ToolDescriptionRequired Params
compliance.validate_ossaValidate OSSA manifest against v0.1.9 specificationmanifest
compliance.generate_manifestGenerate OSSA manifest from template (worker/orchestrator/router)template, metadata
compliance.check_policyCheck Cedar policy compliancepolicy
compliance.validate_openapiValidate OpenAPI 3.1 specificationspec
compliance.audit_complianceRun comprehensive compliance audittarget

Vector Search / RAG (5 tools)

ToolDescriptionRequired Params
vector.indexIndex documents into Qdrant vector databasecollection, documents
vector.searchSemantic search across indexed documentscollection, query
vector.queryRAG-powered query with context retrievalcollection, question
vector.embedGenerate embeddings for texttext
vector.retrieveRetrieve specific documents by IDcollection, ids

Kubernetes (6 tools)

ToolDescriptionRequired Params
k8s.deployDeploy service to Kubernetes clusternamespace, manifest
k8s.scaleScale deployment replicasnamespace, deployment, replicas
k8s.statusGet deployment statusnamespace, deployment
k8s.logsGet pod logsnamespace, pod
k8s.rollbackRollback to previous revisionnamespace, deployment
k8s.healthCheck cluster health status--

Drupal LLM (5 tools)

ToolDescriptionRequired Params
drupal.queryQuery Drupal knowledge basequery
drupal.migrateMigrate Drupal content to vector storesource, contentTypes
drupal.validateValidate Drupal migration configurationconfig
drupal.syncSync Drupal content with vector storesource
drupal.checkCheck Drupal-LLM integration statussite

Workflow (5 tools)

ToolDescriptionRequired Params
workflow.createCreate a new workflow definitionname, definition
workflow.executeExecute a workflow instanceworkflowId
workflow.statusGet workflow execution statusexecutionId
workflow.cancelCancel a running workflow executionexecutionId
workflow.listList all workflows with status filter--

OSSA Agents (4 tools)

ToolDescriptionRequired Params
ossa.list_agentsList all OSSA agents from platform-agents registry--
ossa.get_agentGet detailed information about a specific OSSA agentagentId
ossa.executeExecute an OSSA agent with operation and contextagentId, operation
ossa.sync_agentsSync OSSA agents from NAS/GitLab to local machine--

Knowledge Graph (6 tools)

These tools use underscore naming (not dot notation) and query the GitLab Knowledge Graph service.

ToolDescriptionRequired Params
query_knowledge_graph_entitiesQuery entities by type, pagination, and natural language search--
query_knowledge_graph_relationshipsQuery relationships between entities (HAS_ISSUE, AUTHORED_BY, CLOSES, etc.)--
traverse_knowledge_graphTraverse graph from an entity following relationshipsstartEntityId
get_related_entities_with_contextGet entities related to a specific entity with full contextentityId
search_knowledge_graph_semanticAI-powered semantic search across the knowledge graphquery
build_agent_context_graphBuild comprehensive context graph for agent decision-makingrootEntityId

Supported entity types: project, issue, merge_request, user, commit, milestone, label

Supported relationship types: HAS_ISSUE, HAS_MERGE_REQUEST, AUTHORED_BY, ASSIGNED_TO, CLOSES, REVIEWED_BY, TAGGED_WITH, HAS_COMMIT, HAS_MILESTONE, HAS_LABEL

Acquia Source (11 tools)

Integrates with Acquia Source (Drupal JSON:API) including Canvas page and component support.

ToolDescriptionRequired Params
acquia.list_contentList content, optionally filter by title--
acquia.get_contentGet single content by UUIDtype, uuid
acquia.create_contentCreate content on Acquia Sourcetype, attributes
acquia.update_contentUpdate content by UUIDtype, uuid, attributes
acquia.delete_contentDelete content by UUIDtype, uuid
acquia.search_contentSearch content with JSON:API filters--
acquia.list_content_typesList all resource types on Source--
acquia.get_content_with_relationshipsGet content with included relationshipstype, uuid
acquia.list_canvas_pagesList Canvas pages with component counts--
acquia.get_canvas_pageGet Canvas page with full component treeuuid
acquia.list_componentsDiscover all Code Components by introspecting Canvas pages--

Requires: ACQUIA_SOURCE_URL, ACQUIA_SOURCE_CLIENT_ID, ACQUIA_SOURCE_CLIENT_SECRET environment variables.

Config Resolution (6 tools)

ToolDescriptionRequired Params
config.syncResolve ALL config templates for a developer (one call = all configs)--
config.getResolve a single config template by IDid
config.listList all available config templates with descriptions--
config.healthCheck config service health (token resolver, template availability)--
config.endpointsGet public endpoint URLs (mcp.$DOMAIN, dmcp.$DOMAIN)--
config.otelGet OpenTelemetry config for GitLab observability (HTTP/gRPC endpoints, env vars)--

SSE Transport

The SSE (Server-Sent Events) transport enables remote MCP connections, primarily for the Oracle Cloud deployment at mcp.blueflyagents.com.

HTTP Endpoints

MethodPathDescription
GET/sseEstablishes SSE connection. Creates SSEServerTransport with /message path, connects to MCP server.
POST/messageJSON-RPC message endpoint (handled by SSEServerTransport).
GET/healthReturns JSON health status including tool count and OTel status.
OPTIONS*CORS preflight handler (returns 204).

Health Check Response

{ "status": "healthy", "transport": "sse", "tools": 88, "otel": { "enabled": true, "endpoint": "http://87749026.otel.gitlab-o11y.com:4318", "serviceName": "agent-protocol" }, "timestamp": "2026-02-17T12:00:00.000Z" }

Connection Lifecycle

  1. Client sends GET /sse to establish SSE stream
  2. Server creates SSEServerTransport with /message as the post-back path
  3. Server connects the MCP Server instance to the transport
  4. Client sends JSON-RPC tool calls via POST /message
  5. Server responds via the SSE stream

OpenTelemetry Integration

Module: src/mcp/otel.ts

Initialization

export async function initTracing(): Promise<void> { // Dynamically imports @opentelemetry/sdk-node and @opentelemetry/exporter-trace-otlp-http // If not installed, gracefully no-ops (api package provides no-op tracer) const sdk = new NodeSDK({ serviceName: process.env.OTEL_SERVICE_NAME ?? 'agent-protocol', traceExporter: new OTLPTraceExporter({ url: `${endpoint}/v1/traces` }), }); sdk.start(); }

Tool Call Tracing

Every tool execution is wrapped via recordToolCall():

export async function recordToolCall<T>( toolName: string, args: Record<string, unknown>, result: () => Promise<T> ): Promise<T> { return withSpan(`mcp.tool.${toolName}`, async (span) => { span.setAttribute('mcp.tool.name', toolName); span.setAttribute('mcp.tool.group', toolName.split('.')[0]); const start = performance.now(); try { const value = await result(); span.setAttribute('mcp.tool.success', true); return value; } finally { span.setAttribute('mcp.tool.duration_ms', Math.round(performance.now() - start)); } }); }

Span Attributes

AttributeExampleDescription
mcp.tool.namegitlab.create_issueFully-qualified tool name
mcp.tool.groupgitlabCapability group prefix
mcp.tool.successtrue / falseWhether execution succeeded
mcp.tool.duration_ms142Execution time in milliseconds

Configuration

  • Endpoint: http://87749026.otel.gitlab-o11y.com:4318/v1/traces (GitLab Observability)
  • Required packages (optional -- gracefully no-ops if missing):
    • @opentelemetry/sdk-node
    • @opentelemetry/exporter-trace-otlp-http
  • Always present: @opentelemetry/api (provides no-op tracer when SDK not installed)
  • Shutdown: Hooks into SIGTERM for graceful SDK shutdown

Config Resolution System

The config resolution system provides template-based configuration with dynamic token substitution.

Token Resolver

The token resolver reads workspace.json from NAS (/Volumes/AgentPlatform/config/workspace.json) and substitutes $TOKEN placeholders in templates with actual values from the tokens section.

Config Templates

Located in src/config/templates/:

TemplateIDDescription
settings.jsonsettingsGeneral platform settings
claude-desktop.jsonclaude-desktopClaude Desktop MCP server config
identities.jsonidentitiesDeveloper identity mappings
mcp-servers/(directory)MCP server connection configs
agents-index.jsonagents-indexAgent registry index
slash-commands.jsonslash-commandsCLI slash command definitions
iterm2-config.jsoniterm2-configiTerm2 terminal configuration
buildkit-state.jsonbuildkit-stateBuildKit CLI state
tdd-state.jsontdd-stateTDD workflow state
manifest.jsonmanifestProject manifest template

Merge Strategies

When syncing configs that may have local modifications, the system supports these merge strategies:

  • preserve-secrets: Preserves locally-set secret values (tokens, keys)
  • preserve-preferences: Preserves user-specific preferences
  • preserve-hooks-plugins: Preserves custom hooks and plugin configurations

CLI Commands

# Sync all configs (resolve templates, write to output paths) npx agent-protocol config sync npx agent-protocol config sync --dry-run # List available templates npx agent-protocol config list # Get a specific template resolved npx agent-protocol config get settings npx agent-protocol config get claude-desktop # Check config service health npx agent-protocol config health # Get OTel configuration npx agent-protocol config otel

Deployment

Docker Image

Dockerfile: infrastructure/Dockerfile.mcp-sse

Multi-stage build:

  1. Build stage (node:20-alpine): Installs all dependencies, compiles TypeScript
  2. Runtime stage (node:20-alpine): Production dependencies only, non-root user, tini as init, curl for healthcheck
FROM node:20-alpine AS builder # ... npm ci, tsc ... FROM node:20-alpine AS runtime RUN apk add --no-cache curl tini RUN addgroup -g 1001 -S appgroup && adduser -u 1001 -S appuser -G appgroup # ... production npm ci, copy dist/ ... USER appuser HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \ CMD curl -f http://localhost:3100/health || exit 1 ENTRYPOINT ["/sbin/tini", "--"] CMD ["node", "dist/mcp/server.js"]

Docker Compose

File: infrastructure/docker-compose.mcp-sse.yml

Two services:

  1. mcp-sse: The MCP SSE server on port 3100
  2. cloudflared: Cloudflare tunnel sidecar that exposes mcp.blueflyagents.com
services: mcp-sse: build: context: .. dockerfile: infrastructure/Dockerfile.mcp-sse image: registry.gitlab.com/blueflyio/agent-platform/agent-protocol/mcp-sse:latest ports: - "3100:3100" environment: - MCP_TRANSPORT=sse - MCP_PORT=3100 - OTEL_EXPORTER_OTLP_ENDPOINT=http://87749026.otel.gitlab-o11y.com:4318 - OTEL_SERVICE_NAME=agent-protocol volumes: - /Volumes/AgentPlatform/config/workspace.json:/app/config/workspace.json:ro - ~/.tokens/:/run/secrets/:ro healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3100/health"] cloudflared: image: cloudflare/cloudflared:latest command: tunnel run environment: - TUNNEL_TOKEN=${CLOUDFLARE_TUNNEL_TOKEN} depends_on: mcp-sse: condition: service_healthy

Public URL

mcp.blueflyagents.com via Cloudflare tunnel, pointing to the SSE server on port 3100.

CI/CD Pipeline

The .gitlab-ci.yml defines these stages:

StageDescription
validateLint, type-check, schema validation
testUnit tests, integration tests
buildTypeScript compilation, Docker image build
securitySAST, Container Scanning, Dependency Scanning, Secret Detection
publishnpm package publish to GitLab registry, Docker image push
deploykubectl rolling update to Oracle k3s cluster with OTel deploy trace

Container Registry

registry.gitlab.com/blueflyio/agent-platform/agent-protocol/mcp-sse:latest

Running Locally

stdio Transport (Claude Desktop, CLI)

# Run directly with tsx (development) npm run start:mcp-server # Which executes: tsx src/mcp/server.ts

This starts the MCP server on stdio transport, suitable for Claude Desktop's mcpServers configuration:

{ "mcpServers": { "agent-protocol": { "command": "node", "args": ["${packagePath}/dist/mcp/server.js"], "env": { "NODE_ENV": "production" } } } }

SSE Transport (Oracle mode testing)

# Run SSE server with verbose logging npm run start:mcp-sse # Which executes: MCP_TRANSPORT=sse MCP_PORT=3100 MCP_VERBOSE=true tsx src/mcp/server.ts

Docker Build

# Build the SSE Docker image npm run build:mcp-sse # Which executes: docker build -t agent-protocol-mcp-sse -f infrastructure/Dockerfile.mcp-sse .

Docker Compose (Full Stack)

# Start MCP SSE server + Cloudflare tunnel sidecar docker compose -f infrastructure/docker-compose.mcp-sse.yml up -d # View logs docker compose -f infrastructure/docker-compose.mcp-sse.yml logs -f # Stop docker compose -f infrastructure/docker-compose.mcp-sse.yml down

Config Sync

# Sync all configs (resolve templates from workspace.json) npx agent-protocol config sync # Preview without writing npx agent-protocol config sync --dry-run # List available config templates npx agent-protocol config list # Resolve a single template npx agent-protocol config get settings # Check health npx agent-protocol config health # Get OpenTelemetry configuration npx agent-protocol config otel

Environment Variables

VariableDefaultDescription
MCP_TRANSPORTstdioTransport mode: stdio or sse
MCP_PORT3100SSE server port
MCP_VERBOSEfalseEnable debug logging
GITLAB_TOKEN~/.tokens/gitlabGitLab API token (Personal Access Token)
OTEL_EXPORTER_OTLP_ENDPOINThttp://87749026.otel.gitlab-o11y.com:4318OpenTelemetry OTLP collector endpoint
OTEL_SERVICE_NAMEagent-protocolService name for OTel spans
AGENT_PLATFORM_CONFIG/Volumes/AgentPlatform/config/workspace.jsonPath to workspace.json for config resolution
ACQUIA_SOURCE_URL--Acquia Source instance URL (required for acquia.* tools)
ACQUIA_SOURCE_CLIENT_ID--Acquia Source OAuth client ID
ACQUIA_SOURCE_CLIENT_SECRET--Acquia Source OAuth client secret
GITLAB_PROJECT_ID--Default GitLab project ID for knowledge graph tools
NODE_ENVdevelopmentNode environment (production in Docker)

MCP Resources

In addition to tools, the server exposes MCP resources that can be read by clients:

URINameDescription
agent://agents/registryAgent RegistryComplete list of registered agents
agent://agents/{id}Agent ManifestIndividual agent manifest data
gitlab://observabilityGitLab UltimateObservability, security scanning, model registry, KAS
compliance://policies/{id}Compliance PolicyCedar policy document
vector://collections/{name}Vector CollectionQdrant collection metadata
k8s://deployments/{namespace}/{name}K8s DeploymentKubernetes deployment details
workflow://workflows/{id}Workflow DefinitionWorkflow configuration
workflow://executions/{id}Workflow ExecutionExecution status and history
config://templatesConfig TemplatesAvailable config templates with IDs and descriptions
config://endpointsPublic EndpointsPublic MCP and dashboard endpoint URLs
config://healthConfig HealthConfig service health status