Merge pull request #29 from gerbal/feat/read-only-mode
feat: Add read-only mode support
This commit is contained in:
14
README.md
14
README.md
@ -10,7 +10,7 @@ GitLab MCP(Model Context Protocol) Server. **Includes bug fixes and improvements
|
||||
|
||||
## Usage
|
||||
|
||||
### Using with Claude App, Cline, Roo Code
|
||||
### Using with Claude App, Cline, Roo Code, Cursor
|
||||
|
||||
When using with the Claude App, you need to set up your API key and URLs directly.
|
||||
|
||||
@ -22,23 +22,20 @@ When using with the Claude App, you need to set up your API key and URLs directl
|
||||
"args": ["-y", "@zereight/mcp-gitlab"],
|
||||
"env": {
|
||||
"GITLAB_PERSONAL_ACCESS_TOKEN": "your_gitlab_token",
|
||||
"GITLAB_API_URL": "your_gitlab_api_url"
|
||||
"GITLAB_API_URL": "your_gitlab_api_url",
|
||||
"GITLAB_READ_ONLY_MODE": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Using with Cursor
|
||||
### Environment Variables
|
||||
|
||||
When using with Cursor, you can set up environment variables and run the server as follows:
|
||||
|
||||
```
|
||||
env GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token GITLAB_API_URL=your_gitlab_api_url npx @zereight/mcp-gitlab
|
||||
```
|
||||
|
||||
- `GITLAB_PERSONAL_ACCESS_TOKEN`: Your GitLab personal access token.
|
||||
- `GITLAB_API_URL`: Your GitLab API URL. (Default: `https://gitlab.com/api/v4`)
|
||||
- `GITLAB_READ_ONLY_MODE`: When set to 'true', restricts the server to only expose read-only operations. Useful for enhanced security or when write access is not needed. Also useful for using with Cursor and it's 40 tool limit.
|
||||
|
||||
## Tools 🛠️
|
||||
|
||||
@ -272,6 +269,7 @@ Before running the server, you need to set the following environment variables:
|
||||
```
|
||||
GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token
|
||||
GITLAB_API_URL=your_gitlab_api_url # Default: https://gitlab.com/api/v4
|
||||
GITLAB_READ_ONLY_MODE=true # Optional: Enable read-only mode
|
||||
```
|
||||
|
||||
## License
|
||||
|
380
index.ts
380
index.ts
@ -124,6 +124,205 @@ const server = new Server(
|
||||
);
|
||||
|
||||
const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
|
||||
const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === 'true';
|
||||
|
||||
// Define all available tools
|
||||
const allTools = [
|
||||
{
|
||||
name: "create_or_update_file",
|
||||
description: "Create or update a single file in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateOrUpdateFileSchema),
|
||||
},
|
||||
{
|
||||
name: "search_repositories",
|
||||
description: "Search for GitLab projects",
|
||||
inputSchema: zodToJsonSchema(SearchRepositoriesSchema),
|
||||
},
|
||||
{
|
||||
name: "create_repository",
|
||||
description: "Create a new GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateRepositorySchema),
|
||||
},
|
||||
{
|
||||
name: "get_file_contents",
|
||||
description:
|
||||
"Get the contents of a file or directory from a GitLab project",
|
||||
inputSchema: zodToJsonSchema(GetFileContentsSchema),
|
||||
},
|
||||
{
|
||||
name: "push_files",
|
||||
description:
|
||||
"Push multiple files to a GitLab project in a single commit",
|
||||
inputSchema: zodToJsonSchema(PushFilesSchema),
|
||||
},
|
||||
{
|
||||
name: "create_issue",
|
||||
description: "Create a new issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "create_merge_request",
|
||||
description: "Create a new merge request in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "fork_repository",
|
||||
description:
|
||||
"Fork a GitLab project to your account or specified namespace",
|
||||
inputSchema: zodToJsonSchema(ForkRepositorySchema),
|
||||
},
|
||||
{
|
||||
name: "create_branch",
|
||||
description: "Create a new branch in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateBranchSchema),
|
||||
},
|
||||
{
|
||||
name: "get_merge_request",
|
||||
description: "Get details of a merge request",
|
||||
inputSchema: zodToJsonSchema(GetMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "get_merge_request_diffs",
|
||||
description: "Get the changes/diffs of a merge request",
|
||||
inputSchema: zodToJsonSchema(GetMergeRequestDiffsSchema),
|
||||
},
|
||||
{
|
||||
name: "update_merge_request",
|
||||
description: "Update a merge request",
|
||||
inputSchema: zodToJsonSchema(UpdateMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "create_note",
|
||||
description: "Create a new note (comment) to an issue or merge request",
|
||||
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
||||
},
|
||||
{
|
||||
name: "list_merge_request_discussions",
|
||||
description: "List discussion items for a merge request",
|
||||
inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
|
||||
},
|
||||
{
|
||||
name: "update_merge_request_note",
|
||||
description: "Modify an existing merge request thread note",
|
||||
inputSchema: zodToJsonSchema(UpdateMergeRequestNoteSchema),
|
||||
},
|
||||
{
|
||||
name: "list_issues",
|
||||
description: "List issues in a GitLab project with filtering options",
|
||||
inputSchema: zodToJsonSchema(ListIssuesSchema),
|
||||
},
|
||||
{
|
||||
name: "get_issue",
|
||||
description: "Get details of a specific issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(GetIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "update_issue",
|
||||
description: "Update an issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(UpdateIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_issue",
|
||||
description: "Delete an issue from a GitLab project",
|
||||
inputSchema: zodToJsonSchema(DeleteIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "list_issue_links",
|
||||
description: "List all issue links for a specific issue",
|
||||
inputSchema: zodToJsonSchema(ListIssueLinksSchema),
|
||||
},
|
||||
{
|
||||
name: "get_issue_link",
|
||||
description: "Get a specific issue link",
|
||||
inputSchema: zodToJsonSchema(GetIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "create_issue_link",
|
||||
description: "Create an issue link between two issues",
|
||||
inputSchema: zodToJsonSchema(CreateIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_issue_link",
|
||||
description: "Delete an issue link",
|
||||
inputSchema: zodToJsonSchema(DeleteIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "list_namespaces",
|
||||
description: "List all namespaces available to the current user",
|
||||
inputSchema: zodToJsonSchema(ListNamespacesSchema),
|
||||
},
|
||||
{
|
||||
name: "get_namespace",
|
||||
description: "Get details of a namespace by ID or path",
|
||||
inputSchema: zodToJsonSchema(GetNamespaceSchema),
|
||||
},
|
||||
{
|
||||
name: "verify_namespace",
|
||||
description: "Verify if a namespace path exists",
|
||||
inputSchema: zodToJsonSchema(VerifyNamespaceSchema),
|
||||
},
|
||||
{
|
||||
name: "get_project",
|
||||
description: "Get details of a specific project",
|
||||
inputSchema: zodToJsonSchema(GetProjectSchema),
|
||||
},
|
||||
{
|
||||
name: "list_projects",
|
||||
description: "List projects accessible by the current user",
|
||||
inputSchema: zodToJsonSchema(ListProjectsSchema),
|
||||
},
|
||||
{
|
||||
name: "list_labels",
|
||||
description: "List labels for a project",
|
||||
inputSchema: zodToJsonSchema(ListLabelsSchema),
|
||||
},
|
||||
{
|
||||
name: "get_label",
|
||||
description: "Get a single label from a project",
|
||||
inputSchema: zodToJsonSchema(GetLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "create_label",
|
||||
description: "Create a new label in a project",
|
||||
inputSchema: zodToJsonSchema(CreateLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "update_label",
|
||||
description: "Update an existing label in a project",
|
||||
inputSchema: zodToJsonSchema(UpdateLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_label",
|
||||
description: "Delete a label from a project",
|
||||
inputSchema: zodToJsonSchema(DeleteLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "list_group_projects",
|
||||
description: "List projects in a GitLab group with filtering options",
|
||||
inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
|
||||
},
|
||||
];
|
||||
|
||||
// Define which tools are read-only
|
||||
const readOnlyTools = [
|
||||
"search_repositories",
|
||||
"get_file_contents",
|
||||
"get_merge_request",
|
||||
"get_merge_request_diffs",
|
||||
"list_merge_request_discussions",
|
||||
"list_issues",
|
||||
"get_issue",
|
||||
"list_issue_links",
|
||||
"get_issue_link",
|
||||
"list_namespaces",
|
||||
"get_namespace",
|
||||
"verify_namespace",
|
||||
"get_project",
|
||||
"list_projects",
|
||||
"list_labels",
|
||||
"get_label",
|
||||
"list_group_projects"
|
||||
];
|
||||
|
||||
/**
|
||||
* Smart URL handling for GitLab API
|
||||
@ -1508,182 +1707,13 @@ async function listGroupProjects(
|
||||
}
|
||||
|
||||
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
||||
// If read-only mode is enabled, filter out write operations
|
||||
const tools = GITLAB_READ_ONLY_MODE
|
||||
? allTools.filter(tool => readOnlyTools.includes(tool.name))
|
||||
: allTools;
|
||||
|
||||
return {
|
||||
tools: [
|
||||
{
|
||||
name: "create_or_update_file",
|
||||
description: "Create or update a single file in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateOrUpdateFileSchema),
|
||||
},
|
||||
{
|
||||
name: "search_repositories",
|
||||
description: "Search for GitLab projects",
|
||||
inputSchema: zodToJsonSchema(SearchRepositoriesSchema),
|
||||
},
|
||||
{
|
||||
name: "create_repository",
|
||||
description: "Create a new GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateRepositorySchema),
|
||||
},
|
||||
{
|
||||
name: "get_file_contents",
|
||||
description:
|
||||
"Get the contents of a file or directory from a GitLab project",
|
||||
inputSchema: zodToJsonSchema(GetFileContentsSchema),
|
||||
},
|
||||
{
|
||||
name: "push_files",
|
||||
description:
|
||||
"Push multiple files to a GitLab project in a single commit",
|
||||
inputSchema: zodToJsonSchema(PushFilesSchema),
|
||||
},
|
||||
{
|
||||
name: "create_issue",
|
||||
description: "Create a new issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "create_merge_request",
|
||||
description: "Create a new merge request in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "fork_repository",
|
||||
description:
|
||||
"Fork a GitLab project to your account or specified namespace",
|
||||
inputSchema: zodToJsonSchema(ForkRepositorySchema),
|
||||
},
|
||||
{
|
||||
name: "create_branch",
|
||||
description: "Create a new branch in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(CreateBranchSchema),
|
||||
},
|
||||
{
|
||||
name: "get_merge_request",
|
||||
description: "Get details of a merge request",
|
||||
inputSchema: zodToJsonSchema(GetMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "get_merge_request_diffs",
|
||||
description: "Get the changes/diffs of a merge request",
|
||||
inputSchema: zodToJsonSchema(GetMergeRequestDiffsSchema),
|
||||
},
|
||||
{
|
||||
name: "update_merge_request",
|
||||
description: "Update a merge request",
|
||||
inputSchema: zodToJsonSchema(UpdateMergeRequestSchema),
|
||||
},
|
||||
{
|
||||
name: "create_note",
|
||||
description: "Create a new note (comment) to an issue or merge request",
|
||||
inputSchema: zodToJsonSchema(CreateNoteSchema),
|
||||
},
|
||||
{
|
||||
name: "list_merge_request_discussions",
|
||||
description: "List discussion items for a merge request",
|
||||
inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
|
||||
},
|
||||
{
|
||||
name: "update_merge_request_note",
|
||||
description: "Modify an existing merge request thread note",
|
||||
inputSchema: zodToJsonSchema(UpdateMergeRequestNoteSchema),
|
||||
},
|
||||
{
|
||||
name: "list_issues",
|
||||
description: "List issues in a GitLab project with filtering options",
|
||||
inputSchema: zodToJsonSchema(ListIssuesSchema),
|
||||
},
|
||||
{
|
||||
name: "get_issue",
|
||||
description: "Get details of a specific issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(GetIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "update_issue",
|
||||
description: "Update an issue in a GitLab project",
|
||||
inputSchema: zodToJsonSchema(UpdateIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_issue",
|
||||
description: "Delete an issue from a GitLab project",
|
||||
inputSchema: zodToJsonSchema(DeleteIssueSchema),
|
||||
},
|
||||
{
|
||||
name: "list_issue_links",
|
||||
description: "List all issue links for a specific issue",
|
||||
inputSchema: zodToJsonSchema(ListIssueLinksSchema),
|
||||
},
|
||||
{
|
||||
name: "get_issue_link",
|
||||
description: "Get a specific issue link",
|
||||
inputSchema: zodToJsonSchema(GetIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "create_issue_link",
|
||||
description: "Create an issue link between two issues",
|
||||
inputSchema: zodToJsonSchema(CreateIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_issue_link",
|
||||
description: "Delete an issue link",
|
||||
inputSchema: zodToJsonSchema(DeleteIssueLinkSchema),
|
||||
},
|
||||
{
|
||||
name: "list_namespaces",
|
||||
description: "List all namespaces available to the current user",
|
||||
inputSchema: zodToJsonSchema(ListNamespacesSchema),
|
||||
},
|
||||
{
|
||||
name: "get_namespace",
|
||||
description: "Get details of a namespace by ID or path",
|
||||
inputSchema: zodToJsonSchema(GetNamespaceSchema),
|
||||
},
|
||||
{
|
||||
name: "verify_namespace",
|
||||
description: "Verify if a namespace path exists",
|
||||
inputSchema: zodToJsonSchema(VerifyNamespaceSchema),
|
||||
},
|
||||
{
|
||||
name: "get_project",
|
||||
description: "Get details of a specific project",
|
||||
inputSchema: zodToJsonSchema(GetProjectSchema),
|
||||
},
|
||||
{
|
||||
name: "list_projects",
|
||||
description: "List projects accessible by the current user",
|
||||
inputSchema: zodToJsonSchema(ListProjectsSchema),
|
||||
},
|
||||
{
|
||||
name: "list_labels",
|
||||
description: "List labels for a project",
|
||||
inputSchema: zodToJsonSchema(ListLabelsSchema),
|
||||
},
|
||||
{
|
||||
name: "get_label",
|
||||
description: "Get a single label from a project",
|
||||
inputSchema: zodToJsonSchema(GetLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "create_label",
|
||||
description: "Create a new label in a project",
|
||||
inputSchema: zodToJsonSchema(CreateLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "update_label",
|
||||
description: "Update an existing label in a project",
|
||||
inputSchema: zodToJsonSchema(UpdateLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "delete_label",
|
||||
description: "Delete a label from a project",
|
||||
inputSchema: zodToJsonSchema(DeleteLabelSchema),
|
||||
},
|
||||
{
|
||||
name: "list_group_projects",
|
||||
description: "List projects in a GitLab group with filtering options",
|
||||
inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
|
||||
},
|
||||
],
|
||||
tools,
|
||||
};
|
||||
});
|
||||
|
||||
|
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@zereight/mcp-gitlab",
|
||||
"version": "1.0.21",
|
||||
"version": "1.0.24",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@zereight/mcp-gitlab",
|
||||
"version": "1.0.21",
|
||||
"version": "1.0.24",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@modelcontextprotocol/sdk": "1.8.0",
|
||||
|
Reference in New Issue
Block a user