builderos-cli 2.0.1 → 2.0.3
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/index.js +39 -14
- package/mcp-server.js +143 -0
- package/package.json +4 -1
package/index.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* Usage:
|
|
10
10
|
* npx builderos-cli init [options]
|
|
11
11
|
* npx builderos-cli update [options]
|
|
12
|
+
* npx builderos-cli mcp # Start MCP server
|
|
12
13
|
*
|
|
13
14
|
* Options:
|
|
14
15
|
* --api-url=<url> BuilderOS API URL (default: http://builder-os.test)
|
|
@@ -21,10 +22,22 @@
|
|
|
21
22
|
import { mkdir, writeFile, readFile, access } from 'fs/promises';
|
|
22
23
|
import { join } from 'path';
|
|
23
24
|
import { constants } from 'fs';
|
|
25
|
+
import { startMCPServer } from './mcp-server.js';
|
|
24
26
|
|
|
25
27
|
// Parse command line arguments
|
|
26
28
|
const args = process.argv.slice(2);
|
|
27
29
|
|
|
30
|
+
// Check for MCP server command first
|
|
31
|
+
const command = args[0];
|
|
32
|
+
if (command === 'mcp') {
|
|
33
|
+
// Start MCP server (this will run indefinitely)
|
|
34
|
+
await startMCPServer().catch((error) => {
|
|
35
|
+
console.error('Fatal error:', error);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
});
|
|
38
|
+
// MCP server is now running, this code won't be reached
|
|
39
|
+
}
|
|
40
|
+
|
|
28
41
|
// Default options
|
|
29
42
|
const options = {
|
|
30
43
|
apiUrl: process.env.BUILDEROS_API_URL || 'http://builder-os.test',
|
|
@@ -35,7 +48,6 @@ const options = {
|
|
|
35
48
|
};
|
|
36
49
|
|
|
37
50
|
// Check if first arg is help or no command
|
|
38
|
-
const command = args[0];
|
|
39
51
|
if (!command || command === '--help' || command === '-h') {
|
|
40
52
|
options.help = true;
|
|
41
53
|
}
|
|
@@ -58,15 +70,17 @@ for (const arg of args) {
|
|
|
58
70
|
// Show help
|
|
59
71
|
if (options.help) {
|
|
60
72
|
console.log(`
|
|
61
|
-
BuilderOS CLI v2.0.
|
|
73
|
+
BuilderOS CLI v2.0.3
|
|
62
74
|
|
|
63
75
|
Usage:
|
|
64
76
|
npx builderos-cli init [options]
|
|
65
77
|
npx builderos-cli update [options]
|
|
78
|
+
npx builderos-cli mcp
|
|
66
79
|
|
|
67
80
|
Commands:
|
|
68
81
|
init Initialize BuilderOS in current project
|
|
69
82
|
update Update skills from BuilderOS API
|
|
83
|
+
mcp Start MCP server (used by Claude Code)
|
|
70
84
|
|
|
71
85
|
Options:
|
|
72
86
|
--api-url=<url> BuilderOS API URL (default: http://builder-os.test)
|
|
@@ -87,6 +101,9 @@ Examples:
|
|
|
87
101
|
|
|
88
102
|
# Force reinstall
|
|
89
103
|
npx builderos-cli init --force
|
|
104
|
+
|
|
105
|
+
# Start MCP server (automatically used by .mcp.json)
|
|
106
|
+
npx builderos-cli mcp
|
|
90
107
|
`);
|
|
91
108
|
process.exit(0);
|
|
92
109
|
}
|
|
@@ -105,11 +122,15 @@ async function fileExists(path) {
|
|
|
105
122
|
async function fetchAPI(endpoint) {
|
|
106
123
|
try {
|
|
107
124
|
const url = `${options.apiUrl}${endpoint}`;
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
|
|
126
|
+
// Only set Host header if API URL is not builder-os.test
|
|
127
|
+
// (for cases where we need to access through IP but want nginx to route correctly)
|
|
128
|
+
const headers = {};
|
|
129
|
+
if (!options.apiUrl.includes('builder-os.test')) {
|
|
130
|
+
headers['Host'] = 'builder-os.test';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const response = await fetch(url, { headers });
|
|
113
134
|
|
|
114
135
|
if (!response.ok) {
|
|
115
136
|
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
@@ -118,6 +139,8 @@ async function fetchAPI(endpoint) {
|
|
|
118
139
|
return await response.json();
|
|
119
140
|
} catch (error) {
|
|
120
141
|
console.error(`❌ Error fetching ${endpoint}:`, error.message);
|
|
142
|
+
console.error(` URL: ${url}`);
|
|
143
|
+
console.error(` Stack:`, error.stack);
|
|
121
144
|
return null;
|
|
122
145
|
}
|
|
123
146
|
}
|
|
@@ -139,14 +162,13 @@ async function installMCP() {
|
|
|
139
162
|
}
|
|
140
163
|
}
|
|
141
164
|
|
|
142
|
-
//
|
|
143
|
-
// This CLI is meant to be standalone, not requiring local BuilderOS code
|
|
165
|
+
// Use builderos-cli mcp command as MCP server
|
|
144
166
|
const mcpConfig = {
|
|
145
167
|
mcpServers: {
|
|
146
168
|
'builder-os': {
|
|
147
169
|
type: 'stdio',
|
|
148
170
|
command: 'npx',
|
|
149
|
-
args: ['-y', '
|
|
171
|
+
args: ['-y', 'builderos-cli', 'mcp'],
|
|
150
172
|
env: {
|
|
151
173
|
BUILDEROS_API_URL: options.apiUrl,
|
|
152
174
|
},
|
|
@@ -166,12 +188,15 @@ async function installSkills() {
|
|
|
166
188
|
|
|
167
189
|
// Fetch skills list
|
|
168
190
|
const data = await fetchAPI('/api/skills');
|
|
169
|
-
if (!data || !data.
|
|
191
|
+
if (!data || !data.data) {
|
|
170
192
|
console.log(' ❌ Failed to fetch skills list');
|
|
193
|
+
if (data) {
|
|
194
|
+
console.log(' Response structure:', JSON.stringify(Object.keys(data)));
|
|
195
|
+
}
|
|
171
196
|
return;
|
|
172
197
|
}
|
|
173
198
|
|
|
174
|
-
const skills = data.
|
|
199
|
+
const skills = data.data;
|
|
175
200
|
console.log(` Found ${skills.length} skills`);
|
|
176
201
|
|
|
177
202
|
// Create .claude/skills directory
|
|
@@ -187,7 +212,7 @@ async function installSkills() {
|
|
|
187
212
|
|
|
188
213
|
const skillData = await fetchAPI(`/api/skills/${skill.slug}`);
|
|
189
214
|
|
|
190
|
-
if (!skillData || !skillData.content) {
|
|
215
|
+
if (!skillData || !skillData.data || !skillData.data.content) {
|
|
191
216
|
console.log(` ⚠️ No content available`);
|
|
192
217
|
failedSkills.push(skill.slug);
|
|
193
218
|
continue;
|
|
@@ -199,7 +224,7 @@ async function installSkills() {
|
|
|
199
224
|
|
|
200
225
|
// Write skill.md
|
|
201
226
|
const skillPath = join(skillDir, 'skill.md');
|
|
202
|
-
await writeFile(skillPath, skillData.content);
|
|
227
|
+
await writeFile(skillPath, skillData.data.content);
|
|
203
228
|
|
|
204
229
|
console.log(` ✅ Saved to ${skillDir}/skill.md`);
|
|
205
230
|
successCount++;
|
package/mcp-server.js
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BuilderOS MCP Server
|
|
5
|
+
*
|
|
6
|
+
* MCP server that connects to BuilderOS HTTP API.
|
|
7
|
+
* Used by Claude Code to access BuilderOS tools.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
11
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
12
|
+
import {
|
|
13
|
+
CallToolRequestSchema,
|
|
14
|
+
ListToolsRequestSchema,
|
|
15
|
+
} from '@modelcontextprotocol/sdk/types.js';
|
|
16
|
+
|
|
17
|
+
// Get API URL from environment variable
|
|
18
|
+
const API_URL = process.env.BUILDEROS_API_URL || 'http://builder-os.test';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Fetch tools from BuilderOS API
|
|
22
|
+
*/
|
|
23
|
+
async function fetchTools() {
|
|
24
|
+
try {
|
|
25
|
+
// Only set Host header if API URL is not builder-os.test
|
|
26
|
+
const headers = {};
|
|
27
|
+
if (!API_URL.includes('builder-os.test')) {
|
|
28
|
+
headers['Host'] = 'builder-os.test';
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const response = await fetch(`${API_URL}/api/mcp/tools`, { headers });
|
|
32
|
+
|
|
33
|
+
if (!response.ok) {
|
|
34
|
+
throw new Error(`Failed to fetch tools: ${response.statusText}`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const data = await response.json();
|
|
38
|
+
return data.tools || [];
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('Error fetching tools:', error);
|
|
41
|
+
return [];
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Execute tool via BuilderOS API
|
|
47
|
+
*/
|
|
48
|
+
async function executeTool(toolName, args) {
|
|
49
|
+
try {
|
|
50
|
+
// Only set Host header if API URL is not builder-os.test
|
|
51
|
+
const headers = {
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
};
|
|
54
|
+
if (!API_URL.includes('builder-os.test')) {
|
|
55
|
+
headers['Host'] = 'builder-os.test';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const response = await fetch(`${API_URL}/api/mcp/execute`, {
|
|
59
|
+
method: 'POST',
|
|
60
|
+
headers,
|
|
61
|
+
body: JSON.stringify({
|
|
62
|
+
tool: toolName,
|
|
63
|
+
arguments: args
|
|
64
|
+
})
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
if (!response.ok) {
|
|
68
|
+
throw new Error(`Failed to execute tool: ${response.statusText}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const data = await response.json();
|
|
72
|
+
return data;
|
|
73
|
+
} catch (error) {
|
|
74
|
+
console.error('Error executing tool:', error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Start MCP server
|
|
81
|
+
*/
|
|
82
|
+
export async function startMCPServer() {
|
|
83
|
+
const server = new Server(
|
|
84
|
+
{
|
|
85
|
+
name: 'builderos-cli-mcp',
|
|
86
|
+
version: '2.0.3',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
capabilities: {
|
|
90
|
+
tools: {},
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
// List available tools
|
|
96
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
97
|
+
const tools = await fetchTools();
|
|
98
|
+
return { tools };
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Execute tool
|
|
102
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
103
|
+
const { name, arguments: args } = request.params;
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const result = await executeTool(name, args || {});
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
content: [
|
|
110
|
+
{
|
|
111
|
+
type: 'text',
|
|
112
|
+
text: JSON.stringify(result, null, 2),
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
} catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
content: [
|
|
119
|
+
{
|
|
120
|
+
type: 'text',
|
|
121
|
+
text: `Error: ${error.message}`,
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
isError: true,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Start server
|
|
130
|
+
const transport = new StdioServerTransport();
|
|
131
|
+
await server.connect(transport);
|
|
132
|
+
|
|
133
|
+
console.error('BuilderOS MCP Server started');
|
|
134
|
+
console.error(`Connected to: ${API_URL}`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Run if called directly
|
|
138
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
139
|
+
startMCPServer().catch((error) => {
|
|
140
|
+
console.error('Fatal error:', error);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
});
|
|
143
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "builderos-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "BuilderOS CLI - Initialize BuilderOS in any project without requiring local code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -26,5 +26,8 @@
|
|
|
26
26
|
"repository": {
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "https://github.com/builderos/builderos"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@modelcontextprotocol/sdk": "^1.0.4"
|
|
29
32
|
}
|
|
30
33
|
}
|