Mejorar herramientas MCP Gitea con auto-creación y transferencia de repos
- gitea_variables: Ahora crea automáticamente variables que no existen - gitea_secrets: Ahora crea automáticamente secrets que no existen - Ambas herramientas notifican si crearon o actualizaron - Nueva herramienta gitea_transfer_repo para transferir ownership de repos - Mejoras en manejo de errores y mensajes de notificación
This commit is contained in:
@@ -284,10 +284,35 @@ server.registerTool(
|
||||
case 'set':
|
||||
if (!name) throw new Error('name es requerido para set');
|
||||
if (!value) throw new Error('value es requerido para set');
|
||||
|
||||
// Para secrets, intentamos PUT primero (actualizar)
|
||||
// Si falla con 404, hacemos POST (crear)
|
||||
let secretNotificationMessage = '';
|
||||
try {
|
||||
result = await giteaRequest(`${basePath}/${name}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ data: value }),
|
||||
});
|
||||
secretNotificationMessage = `✓ Secret '${name}' actualizado exitosamente`;
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : '';
|
||||
// Si es 404, el secret no existe, intentar crearlo con POST
|
||||
if (errorMsg.includes('404')) {
|
||||
result = await giteaRequest(basePath, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ name, data: value }),
|
||||
});
|
||||
secretNotificationMessage = `✓ Secret '${name}' creado exitosamente (no existía previamente)`;
|
||||
} else {
|
||||
// Re-lanzar el error si no es 404
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Agregar el mensaje de notificación al resultado
|
||||
result = typeof result === 'object' && result !== null
|
||||
? { ...result, _notification: secretNotificationMessage }
|
||||
: { success: true, _notification: secretNotificationMessage };
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
@@ -357,19 +382,36 @@ server.registerTool(
|
||||
if (!name) throw new Error('name es requerido para set');
|
||||
if (!value) throw new Error('value es requerido para set');
|
||||
|
||||
// Intentar actualizar (PUT) primero, si falla crear (POST)
|
||||
// Verificar si la variable ya existe
|
||||
let variableExists = false;
|
||||
let notificationMessage = '';
|
||||
try {
|
||||
await giteaRequest(`${basePath}/${name}`);
|
||||
variableExists = true;
|
||||
} catch (error) {
|
||||
// Variable no existe, será creada
|
||||
variableExists = false;
|
||||
}
|
||||
|
||||
// Crear o actualizar según corresponda
|
||||
if (variableExists) {
|
||||
result = await giteaRequest(`${basePath}/${name}`, {
|
||||
method: 'PUT',
|
||||
body: JSON.stringify({ value }),
|
||||
});
|
||||
} catch (error) {
|
||||
// Si el PUT falla (variable no existe), intentar POST
|
||||
result = await giteaRequest(`${basePath}/${name}`, {
|
||||
notificationMessage = `✓ Variable '${name}' actualizada exitosamente`;
|
||||
} else {
|
||||
result = await giteaRequest(basePath, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ value }),
|
||||
body: JSON.stringify({ name, value }),
|
||||
});
|
||||
notificationMessage = `✓ Variable '${name}' creada exitosamente (no existía previamente)`;
|
||||
}
|
||||
|
||||
// Agregar el mensaje de notificación al resultado
|
||||
result = typeof result === 'object' && result !== null
|
||||
? { ...result, _notification: notificationMessage }
|
||||
: { success: true, _notification: notificationMessage };
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
@@ -394,6 +436,51 @@ server.registerTool(
|
||||
}
|
||||
);
|
||||
|
||||
// ==================== HERRAMIENTA 6: gitea_transfer_repo ====================
|
||||
server.registerTool(
|
||||
'gitea_transfer_repo',
|
||||
{
|
||||
title: 'Transferir Repositorio Gitea',
|
||||
description: 'Transfiere la propiedad (ownership) de un repositorio a otro usuario u organización. Requiere owner, repo y new_owner.',
|
||||
inputSchema: {
|
||||
owner: z.string().describe('Propietario actual del repo'),
|
||||
repo: z.string().describe('Nombre del repo a transferir'),
|
||||
new_owner: z.string().describe('Nuevo propietario del repo (usuario u organización)'),
|
||||
},
|
||||
outputSchema: {
|
||||
result: z.any().describe('Resultado de la operación')
|
||||
}
|
||||
},
|
||||
async ({ owner, repo, new_owner }) => {
|
||||
try {
|
||||
const result = await giteaRequest(`/repos/${owner}/${repo}/transfer`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({ new_owner }),
|
||||
});
|
||||
|
||||
const transferResult = typeof result === 'object' && result !== null
|
||||
? { ...result, _notification: `✓ Repositorio '${owner}/${repo}' transferido exitosamente a '${new_owner}'` }
|
||||
: { success: true, _notification: `✓ Repositorio '${owner}/${repo}' transferido exitosamente a '${new_owner}'` };
|
||||
|
||||
return {
|
||||
content: [{
|
||||
type: 'text',
|
||||
text: JSON.stringify(transferResult, null, 2)
|
||||
}],
|
||||
structuredContent: {
|
||||
result: transferResult
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : 'Error desconocido';
|
||||
return {
|
||||
content: [{ type: 'text', text: `Error: ${errorMsg}` }],
|
||||
isError: true
|
||||
};
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// ==================== SERVIDOR EXPRESS ====================
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
Reference in New Issue
Block a user