Skip to content

feat: MCP Ecosystem Compatibility - Graceful Startup, Static Manifest, and Release Pipeline Improvements #210

@polaz

Description

@polaz

Problem

The server currently has limited compatibility with MCP ecosystem tooling and marketplaces due to several technical limitations that affect automated validation systems.

Root Causes

  1. Server fails to start without GitLab token

    • Automated validation systems attempt to start the server and call tools/list to extract metadata
    • Without a valid GITLAB_TOKEN, the server crashes or refuses to start
    • This results in "Installation Issue" status in various MCP marketplaces
  2. No static metadata in package.json

    • MCP tooling extracts tools/resources/prompts from static manifests
    • Our server registers tools dynamically at startup
    • package.json lacks an mcp section with metadata
    • Result: tooling shows "0 tools, 0 prompts, 0 resources"
  3. Release pipeline doesn't update version in package.json

    • During semver release, version is only updated in git tag
    • package.json retains the old version
    • npm publish happens with outdated version

Proposed Solution

1. Graceful Startup Without Token

// src/index.ts - modify initialization logic

const server = new MCPServer();

// Register tools ALWAYS, even without token
registerAllTools(server);

// When calling a tool without token - return clear error
async function handleToolCall(name: string, args: any) {
  if (!process.env.GITLAB_TOKEN) {
    return {
      error: "GITLAB_TOKEN environment variable is required. See https://gitlab-mcp.sw.foundation/guide/configuration"
    };
  }
  // ... normal handling
}

// tools/list should work ALWAYS
server.setRequestHandler(ListToolsRequestSchema, async () => {
  return { tools: getAllToolDefinitions() }; // Static list, no token required
});

Benefits:

  • Validation systems can extract tool list via tools/list
  • Users see clear error when token is missing
  • Server successfully passes health checks

2. Static Manifest in package.json

Add mcp section to package.json:

{
  "name": "@structured-world/gitlab-mcp",
  "version": "6.46.0",
  "mcp": {
    "name": "GitLab MCP Server",
    "description": "Model Context Protocol server for GitLab API - 44 tools across 18 entity types with CQRS architecture, OAuth 2.1, and multiple transport modes",
    "repository": "https://github.com/structured-world/gitlab-mcp",
    "homepage": "https://gitlab-mcp.sw.foundation",
    "author": "Dmitry Prudnikov",
    "license": "Apache-2.0",
    "runtime": "node",
    "minNodeVersion": "24.0.0",
    "transports": ["stdio", "sse", "streamable-http"],
    "authentication": {
      "required": true,
      "methods": ["token", "oauth2"],
      "envVars": ["GITLAB_TOKEN", "GITLAB_PERSONAL_ACCESS_TOKEN"]
    },
    "meta": {
      "avatar": "https://about.gitlab.com/images/press/press-kit-icon.png",
      "tags": ["gitlab", "devops", "ci-cd", "merge-requests", "issues", "pipelines", "developer-tools"],
      "categories": ["Developer Tools", "Version Control", "CI/CD"]
    },
    "tools": [
      {
        "name": "browse_projects",
        "description": "Search and browse GitLab projects with filtering options",
        "category": "Projects"
      }
      // ... remaining tools (auto-generated)
    ],
    "featureFlags": {
      "USE_PIPELINE": "Enable pipeline and CI/CD tools",
      "USE_MILESTONE": "Enable milestone management tools",
      "USE_GITLAB_WIKI": "Enable wiki page tools",
      "GITLAB_READ_ONLY_MODE": "Restrict to read-only operations"
    }
  }
}

3. Automatic Manifest Generation

Create script for MCP metadata generation:

# scripts/generate-mcp-manifest.sh
yarn list-tools --json > /tmp/tools.json
node scripts/update-package-mcp.js /tmp/tools.json
// scripts/update-package-mcp.js
const fs = require('fs');
const pkg = require('../package.json');
const tools = JSON.parse(fs.readFileSync(process.argv[2]));

pkg.mcp = pkg.mcp || {};
pkg.mcp.tools = tools.map(t => ({
  name: t.name,
  description: t.description,
  category: t.entity || 'General',
  tier: t.tier || 'free',
  readOnly: t.readOnly || false
}));

fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');

4. Improved Semver Release Pipeline

Update .releaserc.json:

{
  "branches": ["main"],
  "plugins": [
    "@semantic-release/commit-analyzer",
    "@semantic-release/release-notes-generator",
    "@semantic-release/changelog",
    [
      "@semantic-release/npm",
      {
        "npmPublish": true
      }
    ],
    [
      "@semantic-release/exec",
      {
        "prepareCmd": "yarn generate-mcp-manifest && yarn build"
      }
    ],
    [
      "@semantic-release/git",
      {
        "assets": ["package.json", "CHANGELOG.md"],
        "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
      }
    ],
    "@semantic-release/github"
  ]
}

Key changes:

  • @semantic-release/npm automatically updates version in package.json
  • @semantic-release/git commits updated package.json
  • prepareCmd generates current MCP manifest before build

5. GitHub Actions Workflow

# .github/workflows/release.yml
name: Release

on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          persist-credentials: false
          
      - uses: actions/setup-node@v4
        with:
          node-version: '24'
          registry-url: 'https://registry.npmjs.org'
          
      - run: yarn install --frozen-lockfile
      
      - name: Generate MCP Manifest
        run: |
          yarn build
          yarn list-tools --json > /tmp/tools.json
          node scripts/update-package-mcp.js /tmp/tools.json
          
      - name: Semantic Release
        env:
          GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: npx semantic-release

Additional Improvements

Health Check Endpoint Enhancement

When using HTTP transport, add MCP-specific health info:

app.get('/health', (req, res) => {
  res.json({
    status: 'healthy',
    server: '@structured-world/gitlab-mcp',
    version: pkg.version,
    mcp: {
      protocol: '2024-11-05',
      transports: ['stdio', 'sse', 'streamable-http'],
      toolCount: getAllTools().length,
      authenticated: !!process.env.GITLAB_TOKEN
    }
  });
});

Docker Image with Health Check

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3002/health || exit 1

Acceptance Criteria

Criterion Current Target
README.md ✅ Present -
LICENSE ✅ Present -
Tools > 0 ⚠️ Dynamic only Add static manifest
Installation methods ✅ npx -
Starts without errors ❌ Requires token Graceful startup
Resources ⚠️ None Optional
Prompts ⚠️ None Optional

Limitations

  1. Some validators may require actual GitLab API calls

    • If a validator calls real tools, not just tools/list
    • Cannot be resolved without a token
  2. Static manifest may become stale

    • Requires automation on each release
    • CI/CD must generate current list

Tasks

  • Implement graceful startup without token
  • Add static mcp section to package.json
  • Create MCP manifest generation script from yarn list-tools --json
  • Update .releaserc.json for automatic package.json updates
  • Update GitHub Actions workflow
  • Add marketplace badge to README
  • Test on local MCP clients
  • Request reindexing from relevant marketplaces

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions