|
|
@@ -137,6 +137,71 @@ const UpdateIssueCommentSchema = z.object({
|
|
|
body: z.string().describe('Updated comment text'),
|
|
|
});
|
|
|
|
|
|
+const ListLabelsSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+});
|
|
|
+
|
|
|
+const GetLabelSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ labelId: z.number().describe('Label ID'),
|
|
|
+});
|
|
|
+
|
|
|
+const CreateLabelSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ name: z.string().describe('Label name'),
|
|
|
+ color: z.string().describe('7-character hex color code with leading # (e.g., #ff0000)'),
|
|
|
+});
|
|
|
+
|
|
|
+const UpdateLabelSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ labelId: z.number().describe('Label ID'),
|
|
|
+ name: z.string().optional().describe('Label name'),
|
|
|
+ color: z.string().optional().describe('7-character hex color code with leading # (e.g., #ff0000)'),
|
|
|
+});
|
|
|
+
|
|
|
+const DeleteLabelSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ labelId: z.number().describe('Label ID'),
|
|
|
+});
|
|
|
+
|
|
|
+const ListIssueLabelsSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ number: z.number().describe('Issue number'),
|
|
|
+});
|
|
|
+
|
|
|
+const AddIssueLabelsSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ number: z.number().describe('Issue number'),
|
|
|
+ labels: z.array(z.number()).describe('Array of label IDs to add'),
|
|
|
+});
|
|
|
+
|
|
|
+const RemoveIssueLabelSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ number: z.number().describe('Issue number'),
|
|
|
+ labelId: z.number().describe('Label ID to remove'),
|
|
|
+});
|
|
|
+
|
|
|
+const ReplaceIssueLabelsSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ number: z.number().describe('Issue number'),
|
|
|
+ labels: z.array(z.number()).describe('Array of label IDs to set (replaces all existing labels)'),
|
|
|
+});
|
|
|
+
|
|
|
+const RemoveAllIssueLabelsSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ number: z.number().describe('Issue number'),
|
|
|
+});
|
|
|
+
|
|
|
/**
|
|
|
* Create and configure an MCP server with all tools and handlers
|
|
|
*/
|
|
|
@@ -629,6 +694,252 @@ export function createMcpServer(gogsClient: GogsClient): Server {
|
|
|
required: ['owner', 'repo', 'commentId', 'body'],
|
|
|
},
|
|
|
},
|
|
|
+ {
|
|
|
+ name: 'list_labels',
|
|
|
+ description: 'List all labels in a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'get_label',
|
|
|
+ description: 'Get a specific label by ID',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ labelId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Label ID',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'labelId'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'create_label',
|
|
|
+ description: 'Create a new label in a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ name: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Label name',
|
|
|
+ },
|
|
|
+ color: {
|
|
|
+ type: 'string',
|
|
|
+ description: '7-character hex color code with leading # (e.g., #ff0000)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'name', 'color'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'update_label',
|
|
|
+ description: 'Update an existing label',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ labelId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Label ID',
|
|
|
+ },
|
|
|
+ name: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Label name',
|
|
|
+ },
|
|
|
+ color: {
|
|
|
+ type: 'string',
|
|
|
+ description: '7-character hex color code with leading # (e.g., #ff0000)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'labelId'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'delete_label',
|
|
|
+ description: 'Delete a label from a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ labelId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Label ID',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'labelId'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'list_issue_labels',
|
|
|
+ description: 'List all labels on a specific issue',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ number: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Issue number',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'number'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'add_issue_labels',
|
|
|
+ description: 'Add labels to an issue',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ number: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Issue number',
|
|
|
+ },
|
|
|
+ labels: {
|
|
|
+ type: 'array',
|
|
|
+ items: {
|
|
|
+ type: 'number',
|
|
|
+ },
|
|
|
+ description: 'Array of label IDs to add',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'number', 'labels'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'remove_issue_label',
|
|
|
+ description: 'Remove a specific label from an issue',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ number: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Issue number',
|
|
|
+ },
|
|
|
+ labelId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Label ID to remove',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'number', 'labelId'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'replace_issue_labels',
|
|
|
+ description: 'Replace all labels on an issue with a new set',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ number: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Issue number',
|
|
|
+ },
|
|
|
+ labels: {
|
|
|
+ type: 'array',
|
|
|
+ items: {
|
|
|
+ type: 'number',
|
|
|
+ },
|
|
|
+ description: 'Array of label IDs to set (replaces all existing labels)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'number', 'labels'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'remove_all_issue_labels',
|
|
|
+ description: 'Remove all labels from an issue',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ number: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Issue number',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'number'],
|
|
|
+ },
|
|
|
+ },
|
|
|
],
|
|
|
};
|
|
|
});
|
|
|
@@ -914,6 +1225,136 @@ export function createMcpServer(gogsClient: GogsClient): Server {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ case 'list_labels': {
|
|
|
+ const { owner, repo } = ListLabelsSchema.parse(args);
|
|
|
+ const labels = await gogsClient.listLabels(owner, repo);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(labels, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'get_label': {
|
|
|
+ const { owner, repo, labelId } = GetLabelSchema.parse(args);
|
|
|
+ const label = await gogsClient.getLabel(owner, repo, labelId);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(label, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'create_label': {
|
|
|
+ const { owner, repo, name, color } = CreateLabelSchema.parse(args);
|
|
|
+ const label = await gogsClient.createLabel(owner, repo, { name, color });
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(label, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'update_label': {
|
|
|
+ const { owner, repo, labelId, name, color } = UpdateLabelSchema.parse(args);
|
|
|
+ const label = await gogsClient.updateLabel(owner, repo, labelId, { name, color });
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(label, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'delete_label': {
|
|
|
+ const { owner, repo, labelId } = DeleteLabelSchema.parse(args);
|
|
|
+ await gogsClient.deleteLabel(owner, repo, labelId);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: `Label ${labelId} deleted successfully from ${owner}/${repo}`,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'list_issue_labels': {
|
|
|
+ const { owner, repo, number } = ListIssueLabelsSchema.parse(args);
|
|
|
+ const labels = await gogsClient.listIssueLabels(owner, repo, number);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(labels, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'add_issue_labels': {
|
|
|
+ const { owner, repo, number, labels } = AddIssueLabelsSchema.parse(args);
|
|
|
+ const result = await gogsClient.addIssueLabels(owner, repo, number, labels);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(result, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'remove_issue_label': {
|
|
|
+ const { owner, repo, number, labelId } = RemoveIssueLabelSchema.parse(args);
|
|
|
+ await gogsClient.removeIssueLabel(owner, repo, number, labelId);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: `Label ${labelId} removed successfully from issue #${number}`,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'replace_issue_labels': {
|
|
|
+ const { owner, repo, number, labels } = ReplaceIssueLabelsSchema.parse(args);
|
|
|
+ const result = await gogsClient.replaceIssueLabels(owner, repo, number, labels);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(result, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'remove_all_issue_labels': {
|
|
|
+ const { owner, repo, number } = RemoveAllIssueLabelsSchema.parse(args);
|
|
|
+ await gogsClient.removeAllIssueLabels(owner, repo, number);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: `All labels removed successfully from issue #${number}`,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
default:
|
|
|
throw new Error(`Unknown tool: ${name}`);
|
|
|
}
|