Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .beads/metadata.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"database": "beads.db",
"jsonl_export": "issues.jsonl"
}
}
2 changes: 1 addition & 1 deletion .github/workflows/auto-merge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ permissions:
jobs:
auto-merge:
uses: detailobsessed/ci-components/.github/workflows/auto-merge-dependabot.yml@main
secrets: inherit
secrets: inherit
7 changes: 5 additions & 2 deletions .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
name: NPM Publish

on:
release:
types: [published]
workflow_run:
workflows: ["Release"]
branches: [main]
types: [completed]
workflow_dispatch:

permissions:
Expand All @@ -11,4 +13,5 @@ permissions:

jobs:
publish:
if: ${{ github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success' }}
uses: detailobsessed/ci-components/.github/workflows/npm-publish-bun.yml@main
1 change: 1 addition & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ repos:
hooks:
- id: typos
priority: 1
exclude: ^CHANGELOG\.md$

- repo: local
hooks:
Expand Down
6 changes: 6 additions & 0 deletions .typos.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[files]
extend-exclude = ["CHANGELOG.md", "*.lock"]

[default.extend-words]
# Git commit hashes that look like typos
ba = "ba"
1 change: 0 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,3 @@ bd sync # Sync with git
- NEVER stop before pushing - that leaves work stranded locally
- NEVER say "ready to push when you are" - YOU must push
- If push fails, resolve and retry until it succeeds

14 changes: 7 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@
* add branch comparison functionality and update related schemas ([af81bd4](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/af81bd402aeff1a6f03afcf7853d83d89231a8fe))
* add configuration files and scripts for project setup ✨ ([5b35bc1](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/5b35bc163c3277523fbf264523601f55103d714b))
* add configuration files and scripts for project setup ✨ ([4aac7f5](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/4aac7f576a91b14fcf7d379c5baa13df3762ef86))
* add cookie-based authentication support for enterprise GitLab ([#101](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/101)) ([402f068](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/402f06847056903058a5bf5bed0b65d81e0c5757)), closes [#100](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/100) [tou#cookie](https://github.com/tou/issues/cookie) [tou#cookie](https://github.com/tou/issues/cookie) [tou#cookie](https://github.com/tou/issues/cookie)
* add cookie-based authentication support for enterprise GitLab ([#101](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/101)) ([17b8574](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/17b85746b5c3d9fa64f7c912dbefc7fa1184c59d)), closes [#100](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/100) [tou#cookie](https://github.com/tou/issues/cookie) [tou#cookie](https://github.com/tou/issues/cookie) [tou#cookie](https://github.com/tou/issues/cookie)
* add cookie-based authentication support for enterprise GitLab ([#101](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/101)) ([402f068](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/402f06847056903058a5bf5bed0b65d81e0c5757)), closes [#100](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/100) [you#cookie](https://github.com/tou/issues/cookie) [you#cookie](https://github.com/tou/issues/cookie) [you#cookie](https://github.com/tou/issues/cookie)
* add cookie-based authentication support for enterprise GitLab ([#101](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/101)) ([17b8574](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/17b85746b5c3d9fa64f7c912dbefc7fa1184c59d)), closes [#100](https://github.com/detailobsessed/efficient-gitlab-mcp/issues/100) [you#cookie](https://github.com/tou/issues/cookie) [you#cookie](https://github.com/tou/issues/cookie) [you#cookie](https://github.com/tou/issues/cookie)
* Add create_merge_request_thread tool for diff notes ([026dd58](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/026dd58887079bb60187d6acacaafc6fa28d0c3d))
* Add create_merge_request_thread tool for diff notes ([23b0348](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/23b03481eacc2b32a1f4afdf5a125ca23f87bdcf))
* Add createDraftNote api support, useful for bulk code review ([5f08153](https://github.com/detailobsessed/efficient-gitlab-mcp/commit/5f08153da675a6fbec780329c82c6a3395f3f691))
Expand Down Expand Up @@ -294,7 +294,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
> 20 September 2025

- Fix/inline schemas [`#242`](https://github.com/zereight/gitlab-mcp/pull/242)
- Add "full_diff" parameter to get_commit_diff so we can retreive more than 20 files [`#244`](https://github.com/zereight/gitlab-mcp/pull/244)
- Add "full_diff" parameter to get_commit_diff so we can retrieve more than 20 files [`#244`](https://github.com/zereight/gitlab-mcp/pull/244)
- refactor(schemas): replace custom boolean validators with native zod boolean [`#245`](https://github.com/zereight/gitlab-mcp/pull/245)
- Feat/add delete to streamhttp [`#246`](https://github.com/zereight/gitlab-mcp/pull/246)
- Fix: Add 'logic' and 'style' line types to enum for mr_discussions [`#248`](https://github.com/zereight/gitlab-mcp/pull/248)
Expand Down Expand Up @@ -323,7 +323,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: Add NPM publish workflow for automated package publishing [`#208`](https://github.com/zereight/gitlab-mcp/pull/208)
- Fix list of tools in `README.md` [`#205`](https://github.com/zereight/gitlab-mcp/pull/205)
- FIX: flexible boolean [`#201`](https://github.com/zereight/gitlab-mcp/pull/201)
- feat(attachement):download attachement, e.g. images [`#200`](https://github.com/zereight/gitlab-mcp/pull/200)
- feat(attachment):download attachment, e.g. images [`#200`](https://github.com/zereight/gitlab-mcp/pull/200)
- FEAT: merge MR [`#193`](https://github.com/zereight/gitlab-mcp/pull/193)
- FEAT: get draft note [`#197`](https://github.com/zereight/gitlab-mcp/pull/197)
- feat: Add createDraftNote api support, useful for bulk code review [`#183`](https://github.com/zereight/gitlab-mcp/pull/183)
Expand Down Expand Up @@ -371,7 +371,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: add pagination support for CI job logs to prevent context window flooding [`#97`](https://github.com/zereight/gitlab-mcp/pull/97)
- FIX: private token auth [`#91`](https://github.com/zereight/gitlab-mcp/pull/91)
- FEAT: private token auth [`#89`](https://github.com/zereight/gitlab-mcp/pull/89)
- FIX: list issues assginee username [`#87`](https://github.com/zereight/gitlab-mcp/pull/87)
- FIX: list issues assignee username [`#87`](https://github.com/zereight/gitlab-mcp/pull/87)
- FEAT: add support for `remove_source_branch` and `squash` options for merge requests [`#86`](https://github.com/zereight/gitlab-mcp/pull/86)
- Fix for null error [`#85`](https://github.com/zereight/gitlab-mcp/pull/85)
- FIX: bug get issues [`#83`](https://github.com/zereight/gitlab-mcp/pull/83)
Expand Down Expand Up @@ -474,7 +474,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
- feat: Add NPM publish workflow for automated package publishing [`#208`](https://github.com/zereight/gitlab-mcp/pull/208)
- Fix list of tools in `README.md` [`#205`](https://github.com/zereight/gitlab-mcp/pull/205)
- FIX: flexible boolean [`#201`](https://github.com/zereight/gitlab-mcp/pull/201)
- feat(attachement):download attachement, e.g. images [`#200`](https://github.com/zereight/gitlab-mcp/pull/200)
- feat(attachment):download attachment, e.g. images [`#200`](https://github.com/zereight/gitlab-mcp/pull/200)
- FEAT: merge MR [`#193`](https://github.com/zereight/gitlab-mcp/pull/193)
- FEAT: get draft note [`#197`](https://github.com/zereight/gitlab-mcp/pull/197)
- feat: Add createDraftNote api support, useful for bulk code review [`#183`](https://github.com/zereight/gitlab-mcp/pull/183)
Expand Down Expand Up @@ -600,7 +600,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).

> 7 June 2025

- FIX: list issues assginee username [`#87`](https://github.com/zereight/gitlab-mcp/pull/87)
- FIX: list issues assignee username [`#87`](https://github.com/zereight/gitlab-mcp/pull/87)
- FEAT: add support for `remove_source_branch` and `squash` options for merge requests [`#86`](https://github.com/zereight/gitlab-mcp/pull/86)

#### [v1.0.59](https://github.com/zereight/gitlab-mcp/compare/v1.0.57...v1.0.59)
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
4 changes: 2 additions & 2 deletions docs/dynamic-api-url.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ X-GitLab-API-URL: https://gitlab.example.com
| `X-GitLab-API-URL` | Yes* | Full URL to GitLab API (e.g., `https://gitlab.example.com`) |
| `MCP-Session-ID` | Yes** | Session identifier for maintaining state |

\* Required when `ENABLE_DYNAMIC_API_URL=true`
\* Required when `ENABLE_DYNAMIC_API_URL=true`
\** Required for subsequent requests in the same session

### URL Format
Expand Down Expand Up @@ -391,4 +391,4 @@ Specifies the GitLab API URL for the current request.

## License

This feature is part of the GitLab MCP Server and follows the same license terms.
This feature is part of the GitLab MCP Server and follows the same license terms.
18 changes: 9 additions & 9 deletions test/client-pool-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

import { describe, test, after, before } from 'node:test';
import assert from 'node:assert';
import {
launchServer,
findAvailablePort,
cleanupServers,
ServerInstance,
import {
launchServer,
findAvailablePort,
cleanupServers,
ServerInstance,
TransportMode,
HOST
HOST
} from './utils/server-launcher.js';
import { MockGitLabServer, findMockServerPort } from './utils/mock-gitlab-server.js';
import { CustomHeaderClient } from './clients/custom-header-client.js';
Expand Down Expand Up @@ -115,17 +115,17 @@ describe('Client Pool Limits', () => {
'x-gitlab-api-url': 'https://gitlab-3.example.com/api/v4'
});
await client3.connect(mcpUrl);

try {
await client3.callTool('list_projects', { per_page: 1 });
assert.fail('Request 3 should have failed with pool limit error');
} catch (error: any) {
console.log(' ℹ️ Error received:', error.message);
assert.ok(
error.message.includes('capacity reached') || error.message.includes('pool is full'),
error.message.includes('capacity reached') || error.message.includes('pool is full'),
'Error should be about server capacity'
);
}
await client3.disconnect();
});
});
});
2 changes: 1 addition & 1 deletion test/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,4 @@ export class MCPToolCallError extends MCPClientError {
super(message, cause);
this.name = 'MCPToolCallError';
}
}
}
7 changes: 3 additions & 4 deletions test/clients/custom-header-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ export class CustomHeaderClient {
const opts = options as CustomHeaderClientOptions;
this.customHeaders = opts.headers || {};
this.timeout = opts.timeout || 30000;
this.client = new Client({
name: opts.clientName || "test-client-with-headers",
version: opts.clientVersion || "1.0.0"
this.client = new Client({
name: opts.clientName || "test-client-with-headers",
version: opts.clientVersion || "1.0.0"
});
} else {
// Backward compatible: treat options as headers record
Expand Down Expand Up @@ -141,4 +141,3 @@ export class CustomHeaderClient {
return this.transport !== null;
}
}

2 changes: 1 addition & 1 deletion test/clients/sse-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ export class SSETestClient implements MCPClientInterface {
get isConnected(): boolean {
return this.transport !== null;
}
}
}
6 changes: 3 additions & 3 deletions test/clients/stdio-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ export class StdioTestClient implements MCPClientInterface {

// Prepare environment variables for the server process
const serverEnv: Record<string, string> = {};

// Copy process.env, filtering out undefined values
for (const [key, value] of Object.entries(process.env)) {
if (value !== undefined) {
serverEnv[key] = value;
}
}

// Add custom environment variables
if (env) {
Object.assign(serverEnv, env);
Expand Down Expand Up @@ -133,4 +133,4 @@ export class StdioTestClient implements MCPClientInterface {
get isConnected(): boolean {
return this.transport !== null;
}
}
}
2 changes: 1 addition & 1 deletion test/clients/streamable-http-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,4 @@ export class StreamableHTTPTestClient implements MCPClientInterface {
get isConnected(): boolean {
return this.transport !== null;
}
}
}
30 changes: 15 additions & 15 deletions test/dynamic-api-url-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@

import { describe, test, after, before } from 'node:test';
import assert from 'node:assert';
import {
launchServer,
findAvailablePort,
cleanupServers,
ServerInstance,
import {
launchServer,
findAvailablePort,
cleanupServers,
ServerInstance,
TransportMode,
HOST
HOST
} from './utils/server-launcher.js';
import { MockGitLabServer, findMockServerPort } from './utils/mock-gitlab-server.js';
import { CustomHeaderClient } from './clients/custom-header-client.js';
Expand Down Expand Up @@ -94,10 +94,10 @@ describe('Dynamic API URL - Multiple GitLab Instances', () => {

await client.connect(mcpUrl);
const tools = await client.listTools();

assert.ok(tools.tools.length > 0, 'Should have tools');
console.log(` ✓ Connected to instance 1, got ${tools.tools.length} tools`);

await client.disconnect();
});

Expand All @@ -109,10 +109,10 @@ describe('Dynamic API URL - Multiple GitLab Instances', () => {

await client.connect(mcpUrl);
const tools = await client.listTools();

assert.ok(tools.tools.length > 0, 'Should have tools');
console.log(` ✓ Connected to instance 2, got ${tools.tools.length} tools`);

await client.disconnect();
});

Expand Down Expand Up @@ -231,10 +231,10 @@ describe('Dynamic API URL - Multiple GitLab Instances', () => {

await client.connect(mcpUrl);
const tools = await client.listTools();

assert.ok(tools.tools.length > 0, 'Should work with normalized URL');
console.log(' ✓ URL normalization works correctly');

await client.disconnect();
});
});
Expand Down Expand Up @@ -318,12 +318,12 @@ describe('Dynamic API URL - Connection Pool', () => {
// Check metrics
const response = await fetch(metricsUrl);
assert.ok(response.ok, 'Metrics endpoint should be accessible');

const metrics = await response.json();
assert.ok(metrics.gitlabClientPool, 'Should have pool metrics');
assert.ok(typeof metrics.gitlabClientPool.size === 'number', 'Should have pool size');
assert.ok(typeof metrics.gitlabClientPool.maxSize === 'number', 'Should have max size');

console.log(' ✓ Pool metrics available');
console.log(` ℹ️ Pool size: ${metrics.gitlabClientPool.size}/${metrics.gitlabClientPool.maxSize}`);

Expand Down Expand Up @@ -364,4 +364,4 @@ describe('Dynamic API URL - Connection Pool', () => {
await client.disconnect();
}
});
});
});
18 changes: 9 additions & 9 deletions test/dynamic-routing-tests.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, test, after, before } from 'node:test';
import assert from 'node:assert';
import {
launchServer,
findAvailablePort,
ServerInstance,
import {
launchServer,
findAvailablePort,
ServerInstance,
TransportMode,
HOST
HOST
} from './utils/server-launcher.js';
import { MockGitLabServer, findMockServerPort } from './utils/mock-gitlab-server.js';
import { CustomHeaderClient } from './clients/custom-header-client.js';
Expand Down Expand Up @@ -257,7 +257,7 @@ describe('Dynamic Routing and Authentication Scenarios', () => {
}
});
await client.connect(mcpUrl);

await validateToolCalls(client, headerMockServer, MOCK_TOKEN_HEADER);

await client.disconnect();
Expand Down Expand Up @@ -416,7 +416,7 @@ async function validateToolCalls(client: CustomHeaderClient, mockServer: MockGit

for (const tool of toolsToTest) {
mockServer.clearCustomHandlers();

let mockPath = '';
let mockResponse: any;

Expand Down Expand Up @@ -468,7 +468,7 @@ async function validateToolCalls(client: CustomHeaderClient, mockServer: MockGit

const result = await client.callTool(tool.name, tool.params);
const resultContent = JSON.parse((result.content[0] as any).text);

// Basic validation that we got the expected object back
if (Array.isArray(mockResponse)) {
assert.ok(Array.isArray(resultContent));
Expand All @@ -484,4 +484,4 @@ async function validateToolCalls(client: CustomHeaderClient, mockServer: MockGit
}
}
}
}
}
12 changes: 6 additions & 6 deletions test/multi-server-test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { describe, test, after, before } from 'node:test';
import assert from 'node:assert';
import {
launchServer,
findAvailablePort,
ServerInstance,
import {
launchServer,
findAvailablePort,
ServerInstance,
TransportMode,
HOST
HOST
} from './utils/server-launcher.js';
import { MockGitLabServer, findMockServerPort } from './utils/mock-gitlab-server.js';
import { CustomHeaderClient } from './clients/custom-header-client.js';
Expand Down Expand Up @@ -195,4 +195,4 @@ describe("Dynamic Client Mode (ENABLE_DYNAMIC_API_URL=true)", () => {
}
);
});
});
});
Loading