forked from zereight/gitlab-mcp
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: MCP Ecosystem Compatibility - Graceful Startup, Static Manifest, and Release Pipeline Improvements #210
Copy link
Copy link
Closed
Labels
Description
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
-
Server fails to start without GitLab token
- Automated validation systems attempt to start the server and call
tools/listto extract metadata - Without a valid
GITLAB_TOKEN, the server crashes or refuses to start - This results in "Installation Issue" status in various MCP marketplaces
- Automated validation systems attempt to start the server and call
-
No static metadata in package.json
- MCP tooling extracts tools/resources/prompts from static manifests
- Our server registers tools dynamically at startup
package.jsonlacks anmcpsection with metadata- Result: tooling shows "0 tools, 0 prompts, 0 resources"
-
Release pipeline doesn't update version in package.json
- During semver release, version is only updated in git tag
package.jsonretains 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/npmautomatically updates version in package.json@semantic-release/gitcommits updated package.jsonprepareCmdgenerates 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-releaseAdditional 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 1Acceptance Criteria
| Criterion | Current | Target |
|---|---|---|
| README.md | ✅ Present | - |
| LICENSE | ✅ Present | - |
| Tools > 0 | Add static manifest | |
| Installation methods | ✅ npx | - |
| Starts without errors | ❌ Requires token | Graceful startup |
| Resources | Optional | |
| Prompts | Optional |
Limitations
-
Some validators may require actual GitLab API calls
- If a validator calls real tools, not just
tools/list - Cannot be resolved without a token
- If a validator calls real tools, not just
-
Static manifest may become stale
- Requires automation on each release
- CI/CD must generate current list
Tasks
- Implement graceful startup without token
- Add static
mcpsection to package.json - Create MCP manifest generation script from
yarn list-tools --json - Update
.releaserc.jsonfor automatic package.json updates - Update GitHub Actions workflow
- Add marketplace badge to README
- Test on local MCP clients
- Request reindexing from relevant marketplaces
References
Reactions are currently unavailable