secondbrainos-mcp-server 1.0.5 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -22,6 +22,14 @@ class SecondBrainOSServer {
22
22
  model: "chatgpt",
23
23
  document
24
24
  });
25
+ // Create a map of operationId to function for easier lookup
26
+ this.functionMap = new Map();
27
+ this.application.functions.forEach(func => {
28
+ const operation = func.operation();
29
+ if (operation.operationId) {
30
+ this.functionMap.set(operation.operationId, func);
31
+ }
32
+ });
25
33
  this.server = new Server({
26
34
  name: "secondbrainos-server",
27
35
  version: "1.0.0"
@@ -59,19 +67,38 @@ class SecondBrainOSServer {
59
67
  }]
60
68
  };
61
69
  });
62
- // List available tools - now using @samchon/openapi functions
70
+ // List available tools - now using operationId as the tool name
63
71
  this.server.setRequestHandler(ListToolsRequestSchema, async () => {
64
- return {
65
- tools: this.application.functions.map(func => ({
66
- name: func.name,
67
- description: func.description || func.name,
72
+ const tools = [];
73
+ // Iterate through the function map to get tools with proper names
74
+ for (const [operationId, func] of this.functionMap) {
75
+ tools.push({
76
+ name: operationId,
77
+ description: func.description || operationId,
68
78
  inputSchema: func.parameters // Convert to MCP format
69
- }))
70
- };
79
+ });
80
+ }
81
+ // Also include functions without operationId (fallback)
82
+ this.application.functions.forEach(func => {
83
+ const operation = func.operation();
84
+ if (!operation.operationId) {
85
+ tools.push({
86
+ name: func.name,
87
+ description: func.description || func.name,
88
+ inputSchema: func.parameters
89
+ });
90
+ }
91
+ });
92
+ return { tools };
71
93
  });
72
- // Handle tool calls
94
+ // Handle tool calls - now supporting both operationId and original names
73
95
  this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
74
- const func = this.application.functions.find(f => f.name === request.params.name);
96
+ // First try to find by operationId
97
+ let func = this.functionMap.get(request.params.name);
98
+ // If not found, try the original function name
99
+ if (!func) {
100
+ func = this.application.functions.find(f => f.name === request.params.name);
101
+ }
75
102
  if (!func) {
76
103
  throw new McpError(ErrorCode.MethodNotFound, `Unknown function: ${request.params.name}`);
77
104
  }
@@ -0,0 +1,135 @@
1
+ import { OpenApi, HttpLlm } from "@samchon/openapi";
2
+ import axios from "axios";
3
+ import dotenv from "dotenv";
4
+ import fs from "fs/promises";
5
+ import path from "path";
6
+ import { fileURLToPath } from 'url';
7
+ import { dirname } from 'path';
8
+ // Get __dirname equivalent for ES modules
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ // Load environment variables
12
+ dotenv.config();
13
+ // Function to fetch the schema from the API
14
+ async function fetchSchema() {
15
+ const userId = process.env.USER_ID;
16
+ if (!userId) {
17
+ throw new Error("USER_ID environment variable is required");
18
+ }
19
+ console.log("Fetching schema for user:", userId);
20
+ try {
21
+ const response = await axios.post('https://us-central1-second-brain-os.cloudfunctions.net/generate-open-api-schema', { user_id: userId }, {
22
+ headers: {
23
+ 'Content-Type': 'application/json'
24
+ }
25
+ });
26
+ return response.data;
27
+ }
28
+ catch (error) {
29
+ console.error('Failed to fetch schema:', error);
30
+ throw new Error('Failed to fetch API schema');
31
+ }
32
+ }
33
+ async function testMCPConversion() {
34
+ try {
35
+ console.log("=== MCP Conversion Test ===\n");
36
+ // Step 1: Fetch the original schema
37
+ console.log("1. Fetching OpenAPI schema...");
38
+ const originalSchema = await fetchSchema();
39
+ console.log("✓ Schema fetched successfully");
40
+ console.log(` - Title: ${originalSchema.info?.title}`);
41
+ console.log(` - Version: ${originalSchema.info?.version}`);
42
+ console.log(` - Number of paths: ${Object.keys(originalSchema.paths || {}).length}\n`);
43
+ // Save original schema for reference
44
+ await fs.writeFile(path.join(__dirname, '../output/original-schema.json'), JSON.stringify(originalSchema, null, 2));
45
+ console.log("✓ Original schema saved to output/original-schema.json\n");
46
+ // Step 2: Convert using OpenApi
47
+ console.log("2. Converting schema using @samchon/openapi...");
48
+ const document = OpenApi.convert(originalSchema);
49
+ console.log("✓ Schema converted to OpenApi format\n");
50
+ // Step 3: Create LLM application
51
+ console.log("3. Creating LLM application...");
52
+ const application = HttpLlm.application({
53
+ model: "chatgpt",
54
+ document
55
+ });
56
+ console.log("✓ LLM application created");
57
+ console.log(` - Number of functions: ${application.functions.length}\n`);
58
+ // Step 4: Create MCP-compatible tools
59
+ console.log("4. Converting to MCP tool format...");
60
+ const mcpTools = [];
61
+ const functionMap = new Map();
62
+ application.functions.forEach(func => {
63
+ const operation = func.operation();
64
+ const operationId = operation.operationId || func.name;
65
+ functionMap.set(operationId, func);
66
+ const mcpTool = {
67
+ name: operationId,
68
+ description: func.description || operationId,
69
+ inputSchema: func.parameters
70
+ };
71
+ mcpTools.push(mcpTool);
72
+ });
73
+ console.log(`✓ Converted ${mcpTools.length} tools to MCP format\n`);
74
+ // Step 5: Save the results
75
+ console.log("5. Saving conversion results...");
76
+ // Create output directory if it doesn't exist
77
+ await fs.mkdir(path.join(__dirname, '../output'), { recursive: true });
78
+ // Save MCP tools
79
+ await fs.writeFile(path.join(__dirname, '../output/mcp-tools.json'), JSON.stringify(mcpTools, null, 2));
80
+ console.log("✓ MCP tools saved to output/mcp-tools.json");
81
+ // Save function details
82
+ const functionDetails = application.functions.map(func => {
83
+ const operation = func.operation();
84
+ // Extract method and path from the route property if available
85
+ let method;
86
+ let path;
87
+ // The operation might have these properties in different ways depending on the OpenAPI version
88
+ // Let's check the actual structure
89
+ const route = operation.route;
90
+ if (route) {
91
+ method = route.method;
92
+ path = route.path;
93
+ }
94
+ return {
95
+ name: func.name,
96
+ operationId: operation.operationId,
97
+ method,
98
+ path,
99
+ description: func.description,
100
+ parameters: func.parameters,
101
+ operation: {
102
+ summary: operation.summary,
103
+ description: operation.description,
104
+ tags: operation.tags
105
+ }
106
+ };
107
+ });
108
+ await fs.writeFile(path.join(__dirname, '../output/function-details.json'), JSON.stringify(functionDetails, null, 2));
109
+ console.log("✓ Function details saved to output/function-details.json\n");
110
+ // Step 6: Display summary
111
+ console.log("=== Conversion Summary ===");
112
+ console.log(`Total tools converted: ${mcpTools.length}`);
113
+ console.log("\nSample tools:");
114
+ mcpTools.slice(0, 5).forEach(tool => {
115
+ console.log(` - ${tool.name}: ${tool.description}`);
116
+ });
117
+ if (mcpTools.length > 5) {
118
+ console.log(` ... and ${mcpTools.length - 5} more`);
119
+ }
120
+ console.log("\n✓ Test completed successfully!");
121
+ console.log("\nCheck the 'output' directory for:");
122
+ console.log(" - original-schema.json: The raw OpenAPI schema from the API");
123
+ console.log(" - mcp-tools.json: Tools in MCP format");
124
+ console.log(" - function-details.json: Detailed function information");
125
+ }
126
+ catch (error) {
127
+ console.error("\n❌ Test failed:", error);
128
+ if (error instanceof Error) {
129
+ console.error("Error details:", error.message);
130
+ }
131
+ process.exit(1);
132
+ }
133
+ }
134
+ // Run the test
135
+ testMCPConversion().catch(console.error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secondbrainos-mcp-server",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Second Brain OS MCP Server for Claude Desktop",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
@@ -18,7 +18,7 @@
18
18
  "build": "tsc",
19
19
  "dev": "tsx src/index.ts",
20
20
  "start": "node build/index.js",
21
- "test-conversion": "tsx src/test-conversion.ts",
21
+ "test-conversion": "tsx src/test-mcp-conversion.ts",
22
22
  "prepublishOnly": "npm run build",
23
23
  "test": "echo \"Error: no test specified\" && exit 1"
24
24
  },
@@ -47,4 +47,4 @@
47
47
  "engines": {
48
48
  "node": ">=16.0.0"
49
49
  }
50
- }
50
+ }
@@ -1,81 +0,0 @@
1
- import { OpenApi, HttpLlm } from "@samchon/openapi";
2
- import axios from "axios";
3
- import dotenv from "dotenv";
4
- dotenv.config();
5
- async function testSchemaConversion() {
6
- const userId = process.env.USER_ID;
7
- const userSecret = process.env.USER_SECRET;
8
- if (!userId || !userSecret) {
9
- console.error("❌ USER_ID and USER_SECRET environment variables are required");
10
- console.error("Create a .env file with:");
11
- console.error("USER_ID=your_user_id");
12
- console.error("USER_SECRET=your_user_secret");
13
- process.exit(1);
14
- }
15
- console.log("🔄 Fetching OpenAPI schema from Second Brain OS...");
16
- try {
17
- // Fetch the schema
18
- const response = await axios.post('https://us-central1-second-brain-os.cloudfunctions.net/generate-open-api-schema', { user_id: userId }, {
19
- headers: {
20
- 'Content-Type': 'application/json'
21
- }
22
- });
23
- const openApiSchema = response.data;
24
- console.log("✅ Schema fetched successfully!");
25
- console.log(`📋 API Title: ${openApiSchema.info?.title || 'Unknown'}`);
26
- console.log(`📋 API Version: ${openApiSchema.info?.version || 'Unknown'}`);
27
- // Convert to emended OpenAPI document
28
- console.log("\n🔄 Converting to emended OpenAPI format...");
29
- const document = OpenApi.convert(openApiSchema);
30
- console.log("✅ Conversion successful!");
31
- // Create LLM application
32
- console.log("\n🔄 Creating LLM function calling application...");
33
- const application = HttpLlm.application({
34
- model: "chatgpt",
35
- document
36
- });
37
- console.log("✅ LLM application created!");
38
- // Display the converted functions
39
- console.log(`\n📊 Total functions available: ${application.functions.length}`);
40
- console.log(`⚠️ Errors during conversion: ${application.errors.length}`);
41
- if (application.errors.length > 0) {
42
- console.log("\n❌ Conversion errors:");
43
- application.errors.forEach((error, index) => {
44
- console.log(` ${index + 1}. ${error.method.toUpperCase()} ${error.path}`);
45
- error.messages.forEach(msg => console.log(` - ${msg}`));
46
- });
47
- }
48
- console.log("\n🔧 Available MCP Tools:");
49
- console.log("=".repeat(80));
50
- application.functions.slice(0, 10).forEach((func, index) => {
51
- console.log(`\n${index + 1}. ${func.name}`);
52
- console.log(` Method: ${func.method.toUpperCase()}`);
53
- console.log(` Path: ${func.path}`);
54
- console.log(` Description: ${func.description?.split('\n')[0] || 'No description'}`);
55
- console.log(` Parameters Schema: ${JSON.stringify(func.parameters).substring(0, 100)}...`);
56
- });
57
- if (application.functions.length > 10) {
58
- console.log(`\n... and ${application.functions.length - 10} more functions`);
59
- }
60
- // Show a sample of how it would look as MCP tools
61
- console.log("\n\n🎯 Sample MCP Tool Format:");
62
- console.log("=".repeat(80));
63
- const sampleFunc = application.functions[0];
64
- if (sampleFunc) {
65
- const mcpTool = {
66
- name: sampleFunc.name,
67
- description: sampleFunc.description || sampleFunc.name,
68
- inputSchema: sampleFunc.parameters
69
- };
70
- console.log(JSON.stringify(mcpTool, null, 2));
71
- }
72
- }
73
- catch (error) {
74
- console.error("❌ Error:", error instanceof Error ? error.message : error);
75
- if (axios.isAxiosError(error) && error.response) {
76
- console.error("Response data:", error.response.data);
77
- }
78
- }
79
- }
80
- // Run the test
81
- testSchemaConversion();