|
|
@@ -352,6 +352,55 @@ const DeletePublicKeySchema = z.object({
|
|
|
keyId: z.number().describe('Public key ID to delete'),
|
|
|
});
|
|
|
|
|
|
+const ListHooksSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+});
|
|
|
+
|
|
|
+const CreateHookSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ type: z.enum(['gogs', 'slack']).describe('Webhook type (gogs or slack)'),
|
|
|
+ config: z.object({
|
|
|
+ url: z.string().describe('URL to send webhook payloads to'),
|
|
|
+ content_type: z.enum(['json', 'form']).describe('Content type for payload (json or form)'),
|
|
|
+ secret: z.string().optional().describe('Optional secret for webhook validation'),
|
|
|
+ channel: z.string().optional().describe('Slack channel (for slack webhooks)'),
|
|
|
+ username: z.string().optional().describe('Slack username (for slack webhooks)'),
|
|
|
+ icon_url: z.string().optional().describe('Slack icon URL (for slack webhooks)'),
|
|
|
+ color: z.string().optional().describe('Slack color (for slack webhooks)'),
|
|
|
+ }).describe('Webhook configuration'),
|
|
|
+ events: z.array(z.enum(['create', 'delete', 'fork', 'push', 'issues', 'issue_comment', 'pull_request', 'release']))
|
|
|
+ .optional()
|
|
|
+ .describe('Events that trigger the webhook (default: ["push"])'),
|
|
|
+ active: z.boolean().optional().describe('Whether the webhook is active (default: false)'),
|
|
|
+});
|
|
|
+
|
|
|
+const UpdateHookSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ hookId: z.number().describe('Webhook ID to update'),
|
|
|
+ config: z.object({
|
|
|
+ url: z.string().describe('URL to send webhook payloads to'),
|
|
|
+ content_type: z.enum(['json', 'form']).describe('Content type for payload (json or form)'),
|
|
|
+ secret: z.string().optional().describe('Optional secret for webhook validation'),
|
|
|
+ channel: z.string().optional().describe('Slack channel (for slack webhooks)'),
|
|
|
+ username: z.string().optional().describe('Slack username (for slack webhooks)'),
|
|
|
+ icon_url: z.string().optional().describe('Slack icon URL (for slack webhooks)'),
|
|
|
+ color: z.string().optional().describe('Slack color (for slack webhooks)'),
|
|
|
+ }).describe('Webhook configuration'),
|
|
|
+ events: z.array(z.enum(['create', 'delete', 'fork', 'push', 'issues', 'issue_comment', 'pull_request', 'release']))
|
|
|
+ .optional()
|
|
|
+ .describe('Events that trigger the webhook'),
|
|
|
+ active: z.boolean().optional().describe('Whether the webhook is active'),
|
|
|
+});
|
|
|
+
|
|
|
+const DeleteHookSchema = z.object({
|
|
|
+ owner: z.string().describe('Repository owner username'),
|
|
|
+ repo: z.string().describe('Repository name'),
|
|
|
+ hookId: z.number().describe('Webhook ID to delete'),
|
|
|
+});
|
|
|
+
|
|
|
/**
|
|
|
* Create and configure an MCP server with all tools and handlers
|
|
|
*/
|
|
|
@@ -1670,6 +1719,187 @@ export function createMcpServer(gogsClient: GogsClient): Server {
|
|
|
required: ['keyId'],
|
|
|
},
|
|
|
},
|
|
|
+ {
|
|
|
+ name: 'list_hooks',
|
|
|
+ description: 'List all webhooks for a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'create_hook',
|
|
|
+ description: 'Create a new webhook for a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ type: {
|
|
|
+ type: 'string',
|
|
|
+ enum: ['gogs', 'slack'],
|
|
|
+ description: 'Webhook type (gogs or slack)',
|
|
|
+ },
|
|
|
+ config: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ url: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'URL to send webhook payloads to',
|
|
|
+ },
|
|
|
+ content_type: {
|
|
|
+ type: 'string',
|
|
|
+ enum: ['json', 'form'],
|
|
|
+ description: 'Content type for payload (json or form)',
|
|
|
+ },
|
|
|
+ secret: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Optional secret for webhook validation',
|
|
|
+ },
|
|
|
+ channel: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack channel (for slack webhooks)',
|
|
|
+ },
|
|
|
+ username: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack username (for slack webhooks)',
|
|
|
+ },
|
|
|
+ icon_url: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack icon URL (for slack webhooks)',
|
|
|
+ },
|
|
|
+ color: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack color (for slack webhooks)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['url', 'content_type'],
|
|
|
+ description: 'Webhook configuration',
|
|
|
+ },
|
|
|
+ events: {
|
|
|
+ type: 'array',
|
|
|
+ items: {
|
|
|
+ type: 'string',
|
|
|
+ enum: ['create', 'delete', 'fork', 'push', 'issues', 'issue_comment', 'pull_request', 'release'],
|
|
|
+ },
|
|
|
+ description: 'Events that trigger the webhook (default: ["push"])',
|
|
|
+ },
|
|
|
+ active: {
|
|
|
+ type: 'boolean',
|
|
|
+ description: 'Whether the webhook is active (default: false)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'type', 'config'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'update_hook',
|
|
|
+ description: 'Update an existing webhook',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ hookId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Webhook ID to update',
|
|
|
+ },
|
|
|
+ config: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ url: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'URL to send webhook payloads to',
|
|
|
+ },
|
|
|
+ content_type: {
|
|
|
+ type: 'string',
|
|
|
+ enum: ['json', 'form'],
|
|
|
+ description: 'Content type for payload (json or form)',
|
|
|
+ },
|
|
|
+ secret: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Optional secret for webhook validation',
|
|
|
+ },
|
|
|
+ channel: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack channel (for slack webhooks)',
|
|
|
+ },
|
|
|
+ username: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack username (for slack webhooks)',
|
|
|
+ },
|
|
|
+ icon_url: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack icon URL (for slack webhooks)',
|
|
|
+ },
|
|
|
+ color: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Slack color (for slack webhooks)',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['url', 'content_type'],
|
|
|
+ description: 'Webhook configuration',
|
|
|
+ },
|
|
|
+ events: {
|
|
|
+ type: 'array',
|
|
|
+ items: {
|
|
|
+ type: 'string',
|
|
|
+ enum: ['create', 'delete', 'fork', 'push', 'issues', 'issue_comment', 'pull_request', 'release'],
|
|
|
+ },
|
|
|
+ description: 'Events that trigger the webhook',
|
|
|
+ },
|
|
|
+ active: {
|
|
|
+ type: 'boolean',
|
|
|
+ description: 'Whether the webhook is active',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'hookId', 'config'],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: 'delete_hook',
|
|
|
+ description: 'Delete a webhook from a repository',
|
|
|
+ inputSchema: {
|
|
|
+ type: 'object',
|
|
|
+ properties: {
|
|
|
+ owner: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository owner username',
|
|
|
+ },
|
|
|
+ repo: {
|
|
|
+ type: 'string',
|
|
|
+ description: 'Repository name',
|
|
|
+ },
|
|
|
+ hookId: {
|
|
|
+ type: 'number',
|
|
|
+ description: 'Webhook ID to delete',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ required: ['owner', 'repo', 'hookId'],
|
|
|
+ },
|
|
|
+ },
|
|
|
],
|
|
|
};
|
|
|
});
|
|
|
@@ -2511,6 +2741,72 @@ export function createMcpServer(gogsClient: GogsClient): Server {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+ case 'list_hooks': {
|
|
|
+ const { owner, repo } = ListHooksSchema.parse(args);
|
|
|
+ const hooks = await gogsClient.listHooks(owner, repo);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(hooks, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'create_hook': {
|
|
|
+ const { owner, repo, type, config, events, active } = CreateHookSchema.parse(args);
|
|
|
+ const hook = await gogsClient.createHook(owner, repo, {
|
|
|
+ type,
|
|
|
+ config,
|
|
|
+ events,
|
|
|
+ active,
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(hook, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'update_hook': {
|
|
|
+ const { owner, repo, hookId, config, events, active } = UpdateHookSchema.parse(args);
|
|
|
+ const hook = await gogsClient.updateHook(owner, repo, hookId, {
|
|
|
+ config,
|
|
|
+ events,
|
|
|
+ active,
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify(hook, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ case 'delete_hook': {
|
|
|
+ const { owner, repo, hookId } = DeleteHookSchema.parse(args);
|
|
|
+ await gogsClient.deleteHook(owner, repo, hookId);
|
|
|
+ return {
|
|
|
+ content: [
|
|
|
+ {
|
|
|
+ type: 'text',
|
|
|
+ text: JSON.stringify({
|
|
|
+ success: true,
|
|
|
+ message: `Successfully deleted webhook ${hookId} from ${owner}/${repo}`,
|
|
|
+ hookId,
|
|
|
+ repository: `${owner}/${repo}`
|
|
|
+ }, null, 2),
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
default:
|
|
|
throw new Error(`Unknown tool: ${name}`);
|
|
|
}
|