bottlenecks-mcp-server
Version:
Model Context Protocol server for Bottlenecks database - enables AI agents like Claude to interact with bottleneck data
259 lines • 11.6 kB
JavaScript
/**
* MCP Discovery Tools
* Provides AI agents with comprehensive guidance on using the Bottlenecks system
*/
/**
* Primary entry point for AI agents
* Returns comprehensive workflow, capabilities, and examples
*/
export function createAgentsStartHereTool(client) {
return {
type: 'call_tool',
name: 'agents_start_here',
description: 'Get comprehensive guidance on using the Bottlenecks MCP server. This is the recommended first call for any AI agent.',
inputSchema: {
type: 'object',
properties: {
include_examples: {
type: 'boolean',
description: 'Whether to include detailed usage examples',
default: true,
},
focus_area: {
type: 'string',
description: 'Specific area of interest (optional)',
enum: [
'authentication',
'bottlenecks',
'files',
'search',
'workflow',
],
},
},
required: [],
},
handler: async (args) => {
try {
const response = await client.request('/api/mcp/agents-start-here', {
method: 'GET',
requireAuth: false,
});
if (!response.success) {
return {
content: [
{
type: 'text',
text: `Error getting agent guidance: ${response.error}`,
},
],
isError: true,
};
}
const data = response.data;
let content = '';
// Safely access nested properties with fallbacks
const welcome = data?.welcome || {};
const workflow = data?.workflow || {};
const authentication = data?.authentication || {};
// Add welcome message
content += `# ${welcome.title || 'Bottlenecks MCP Server'}\n\n`;
content += `${welcome.description || 'AI-powered bottleneck research system'}\n\n`;
content += `**Version:** ${welcome.version || '1.0.0'}\n`;
const capabilities = welcome.capabilities || [];
content += `**Capabilities:** ${Array.isArray(capabilities) ? capabilities.join(', ') : 'None'}\n\n`;
// Add workflow if not focusing on specific area
if (!args.focus_area || args.focus_area === 'workflow') {
content += `## 🚀 Recommended Workflow\n\n`;
const steps = workflow.steps || [];
if (Array.isArray(steps)) {
steps.forEach((step, index) => {
content += `### Step ${step.step || index + 1}: ${step.action || 'Unknown'}\n`;
content += `${step.description || 'No description'}\n`;
if (step.tool)
content += `**Tool:** \`${step.tool}\`\n`;
if (step.endpoint)
content += `**Endpoint:** \`${step.endpoint}\`\n`;
if (step.required)
content += `**Required:** Yes\n`;
content += '\n';
});
}
else {
content += `No workflow steps available\n\n`;
}
}
// Add authentication info if requested
if (!args.focus_area || args.focus_area === 'authentication') {
content += `## 🔐 Authentication\n\n`;
content += `${authentication.description || 'OAuth-based authentication required'}\n\n`;
content += `**OAuth Flow:**\n`;
const oauthFlow = authentication.oauth_flow || [];
if (Array.isArray(oauthFlow)) {
oauthFlow.forEach((step, index) => {
content += `${index + 1}. ${step}\n`;
});
}
else {
content += `1. Visit authorization endpoint\n2. Obtain API key\n3. Use key in requests\n`;
}
content += '\n';
}
// Add data structure if requested
if (!args.focus_area || args.focus_area === 'bottlenecks') {
content += `## 📊 Bottleneck Data Structure\n\n`;
content += '```json\n';
content += JSON.stringify(data.data_structure.bottleneck_schema, null, 2);
content += '\n```\n\n';
}
// Add file support if requested
if (!args.focus_area || args.focus_area === 'files') {
content += `## 📁 File Support\n\n`;
content += `${data.file_support.description}\n\n`;
content += `**Supported Types:** ${data.file_support.supported_types.join(', ')}\n`;
content += `**Max Size:** ${data.file_support.max_size}\n`;
content += `**Processing:** ${data.file_support.processing_capabilities.join(', ')}\n\n`;
}
// Add examples if requested
if (args.include_examples !== false &&
(!args.focus_area || args.focus_area === 'workflow')) {
content += `## 💡 Example Usage\n\n`;
if (data.examples && data.examples.length > 0) {
data.examples.forEach((example) => {
content += `### ${example.title}\n`;
content += `${example.description}\n\n`;
content += '```typescript\n';
content += example.code;
content += '\n```\n\n';
});
}
}
// Add available tools
content += `## 🛠️ Available Tools\n\n`;
data.available_tools.forEach((tool) => {
content += `- **${tool.name}**: ${tool.description}\n`;
});
return {
content: [
{
type: 'text',
text: content,
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `Error in agents_start_here: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
isError: true,
};
}
},
};
}
/**
* Get server capabilities and status
*/
export function createGetCapabilitiesTool(client) {
return {
type: 'call_tool',
name: 'get_capabilities',
description: 'Get detailed information about server capabilities, rate limits, and current status',
inputSchema: {
type: 'object',
properties: {
include_limits: {
type: 'boolean',
description: 'Include rate limiting information',
default: true,
},
},
required: [],
},
handler: async (args) => {
try {
// Get basic capabilities from the discovery endpoint
const response = await client.request('/api/mcp/agents-start-here', {
method: 'GET',
requireAuth: false,
});
if (!response.success) {
return {
content: [
{
type: 'text',
text: `Error getting capabilities: ${response.error}`,
},
],
isError: true,
};
}
const data = response.data;
let content = `# Server Capabilities\n\n`;
// Safely access nested properties with fallbacks
const welcome = data?.welcome || {};
const availableTools = data?.available_tools || [];
const fileSupport = data?.file_support || {};
content += `**Server:** ${welcome.title || 'Unknown'}\n`;
content += `**Version:** ${welcome.version || '1.0.0'}\n`;
content += `**Status:** Online\n\n`;
content += `## Core Capabilities\n`;
const capabilities = welcome.capabilities || [];
if (Array.isArray(capabilities)) {
capabilities.forEach((cap) => {
content += `- ${cap}\n`;
});
}
else {
content += `- No capabilities available\n`;
}
content += `\n## Available Tools (${availableTools.length})\n`;
if (Array.isArray(availableTools)) {
availableTools.forEach((tool) => {
content += `- **${tool.name || 'Unknown'}**: ${tool.description || 'No description'}\n`;
});
}
else {
content += `- No tools available\n`;
}
content += `\n## File Support\n`;
const supportedTypes = fileSupport.supported_types || [];
const processingCapabilities = fileSupport.processing_capabilities || [];
content += `- **Types:** ${Array.isArray(supportedTypes) ? supportedTypes.join(', ') : 'None'}\n`;
content += `- **Max Size:** ${fileSupport.max_size || 'Unknown'}\n`;
content += `- **Processing:** ${Array.isArray(processingCapabilities) ? processingCapabilities.join(', ') : 'None'}\n`;
if (args.include_limits) {
content += `\n## Rate Limits\n`;
content += `- **Default:** 100 requests/hour\n`;
content += `- **Premium:** 1000 requests/hour\n`;
content += `- **Admin:** Unlimited\n`;
}
return {
content: [
{
type: 'text',
text: content,
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `Error in get_capabilities: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
isError: true,
};
}
},
};
}
//# sourceMappingURL=discovery.js.map