server.ts•4.88 kB
import 'dotenv/config';
import { config } from 'dotenv';
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import express from 'express';
import { z } from 'zod';
import {
listUsers,
deleteUser,
lockUser,
unlockUser,
listUsersSchema,
deleteUserSchema,
lockUserSchema
} from './clerk-tools.js';
// Carregar variáveis de ambiente do .env.local
config({ path: '.env.local' });
// Criar o servidor MCP
const server = new McpServer({
name: 'clerk-mcp-server',
version: '1.0.0'
});
// Registrar ferramenta: Listar Usuários
server.registerTool(
'list-users',
{
title: 'Listar Usuários',
description: 'Lista todos os usuários cadastrados no Clerk com paginação',
inputSchema: listUsersSchema,
outputSchema: {
success: z.boolean(),
data: z.object({
users: z.array(z.object({
id: z.string(),
email: z.string().nullable(),
firstName: z.string().nullable(),
lastName: z.string().nullable(),
username: z.string().nullable(),
createdAt: z.number(),
updatedAt: z.number(),
locked: z.boolean(),
banned: z.boolean()
})),
total: z.number(),
limit: z.number(),
offset: z.number()
}).optional(),
error: z.string().optional()
}
},
async (params) => {
const result = await listUsers(params);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
structuredContent: result
};
}
);
// Registrar ferramenta: Deletar Usuário
server.registerTool(
'delete-user',
{
title: 'Deletar Usuário',
description: 'Deleta permanentemente um usuário do Clerk pelo ID. Esta ação é irreversível!',
inputSchema: deleteUserSchema,
outputSchema: {
success: z.boolean(),
message: z.string().optional(),
error: z.string().optional()
}
},
async (params) => {
const result = await deleteUser(params);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
structuredContent: result
};
}
);
// Registrar ferramenta: Bloquear Usuário
server.registerTool(
'lock-user',
{
title: 'Bloquear Usuário',
description: 'Bloqueia um usuário do Clerk, impedindo que ele faça login',
inputSchema: lockUserSchema,
outputSchema: {
success: z.boolean(),
message: z.string().optional(),
error: z.string().optional()
}
},
async (params) => {
const result = await lockUser(params);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
structuredContent: result
};
}
);
// Registrar ferramenta BÔNUS: Desbloquear Usuário
server.registerTool(
'unlock-user',
{
title: 'Desbloquear Usuário',
description: 'Desbloqueia um usuário do Clerk, permitindo que ele faça login novamente',
inputSchema: lockUserSchema, // Usa o mesmo schema do lock
outputSchema: {
success: z.boolean(),
message: z.string().optional(),
error: z.string().optional()
}
},
async (params) => {
const result = await unlockUser(params);
return {
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
structuredContent: result
};
}
);
// Configurar Express e transporte HTTP
const app = express();
app.use(express.json());
// Rota de health check
app.get('/', (req, res) => {
res.json({
status: 'online',
name: 'Clerk MCP Server',
version: '1.0.0',
tools: ['list-users', 'delete-user', 'lock-user', 'unlock-user']
});
});
// Rota MCP principal
app.post('/mcp', async (req, res) => {
// Criar um novo transporte para cada requisição
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined,
enableJsonResponse: true
});
res.on('close', () => {
transport.close();
});
await server.connect(transport);
await transport.handleRequest(req, res, req.body);
});
// Iniciar o servidor
const port = parseInt(process.env.PORT || '5000');
app.listen(port, () => {
console.log(`🚀 Clerk MCP Server rodando em http://localhost:${port}`);
console.log(`📡 Endpoint MCP: http://localhost:${port}/mcp`);
console.log(`\n🛠️ Ferramentas disponíveis:`);
console.log(` - list-users: Lista usuários do Clerk`);
console.log(` - delete-user: Deleta um usuário permanentemente`);
console.log(` - lock-user: Bloqueia um usuário`);
console.log(` - unlock-user: Desbloqueia um usuário`);
console.log(`\n💡 Teste com: npx @modelcontextprotocol/inspector`);
console.log(` Conecte em: http://localhost:${port}/mcp`);
}).on('error', (error) => {
console.error('❌ Erro ao iniciar servidor:', error);
process.exit(1);
});