bottlenecks-mcp-server
Version:
Model Context Protocol server for Bottlenecks database - enables AI agents like Claude to interact with bottleneck data
119 lines • 5 kB
JavaScript
/**
* MCP Admin Operations Tools
* Provides AI agents with admin-specific capabilities for managing bottlenecks
*/
/**
* Admin tool to list unapproved bottlenecks for review
*/
export function createListUnapprovedBottlenecksTool(client) {
return {
type: 'call_tool',
name: 'list_unapproved_bottlenecks',
description: 'List unapproved bottlenecks for admin review (admin only)',
inputSchema: {
type: 'object',
properties: {
status: {
type: 'string',
description: 'Filter by specific status',
enum: ['pending', 'rejected', 'draft'],
default: 'pending',
},
page: {
type: 'number',
description: 'Page number for pagination',
minimum: 1,
default: 1,
},
limit: {
type: 'number',
description: 'Number of results per page',
minimum: 1,
maximum: 100,
default: 20,
},
},
required: [],
},
handler: async (args) => {
try {
const params = new URLSearchParams();
params.append('status', args.status || 'pending');
if (args.page)
params.append('page', args.page.toString());
if (args.limit)
params.append('limit', args.limit.toString());
const response = await client.request(`/api/admin/cards?${params.toString()}`, {
method: 'GET',
requireAuth: true,
});
if (!response.success) {
return {
content: [
{
type: 'text',
text: `Error listing unapproved bottlenecks: ${response.error}`,
},
],
isError: true,
};
}
const data = response.data || {};
let content = `# Unapproved Bottlenecks (${args.status || 'pending'})\n\n`;
const cards = data.data || data || [];
if (!Array.isArray(cards) || cards.length === 0) {
content += `No ${args.status || 'pending'} bottlenecks found.\n`;
return {
content: [
{
type: 'text',
text: content,
},
],
};
}
const total = data.pagination?.total || cards.length;
const page = data.pagination?.page || args.page || 1;
const limit = data.pagination?.limit || args.limit || 20;
content += `**Total:** ${total} ${args.status || 'pending'} bottlenecks\n`;
content += `**Page:** ${page} of ${Math.ceil(total / limit)}\n\n`;
cards.forEach((bottleneck, index) => {
const rowNum = (page - 1) * limit + index + 1;
content += `## ${rowNum}. ${bottleneck.title}\n`;
content += `**ID:** \`${bottleneck.id}\`\n`;
content += `**Status:** ${bottleneck.status}\n`;
content += `**Created:** ${new Date(bottleneck.created_at).toLocaleDateString()}\n`;
content += `**Author:** ${bottleneck.created_by || 'Unknown'}\n`;
content += `**Public:** ${bottleneck.is_public ? 'Yes' : 'No'}\n`;
if (bottleneck.summary) {
const summary = bottleneck.summary.length > 200
? bottleneck.summary.substring(0, 197) + '...'
: bottleneck.summary;
content += `**Summary:** ${summary}\n`;
}
content += `**View:** [Admin Edit](${client.getApiBaseUrl()}/admin/cards/edit/${bottleneck.id})\n\n`;
});
return {
content: [
{
type: 'text',
text: content,
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `Error: ${error instanceof Error ? error.message : 'Unknown error occurred'}`,
},
],
isError: true,
};
}
},
};
}
//# sourceMappingURL=admin-operations.js.map