@protoboxai/cli 1.0.0 → 1.0.1
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/README.md +34 -40
- package/dist/commands/auth.js +10 -10
- package/dist/commands/chat.js +7 -7
- package/dist/commands/config.js +6 -6
- package/dist/commands/health.js +2 -2
- package/dist/commands/knowledge.js +42 -42
- package/dist/commands/mcp.js +51 -37
- package/dist/commands/prompts.js +16 -16
- package/dist/commands/tools.js +23 -23
- package/dist/commands/toolsets.js +18 -24
- package/dist/commands/workspaces.js +8 -8
- package/dist/utils/config-store.js +6 -6
- package/dist/utils/sdk-factory.js +6 -6
- package/package.json +15 -15
package/README.md
CHANGED
|
@@ -1,77 +1,71 @@
|
|
|
1
|
-
# @
|
|
1
|
+
# @protoboxai/cli
|
|
2
2
|
|
|
3
|
-
Command-line interface for
|
|
3
|
+
Command-line interface for [Protobox](https://protobox.ai) — manage your hosted MCP server: tools, toolsets, knowledge, prompts, workspaces, and API keys, all from your terminal.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
npm install -g @
|
|
8
|
+
npm install -g @protoboxai/cli
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Or run directly:
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
npx @
|
|
14
|
+
npx @protoboxai/cli
|
|
15
15
|
```
|
|
16
16
|
|
|
17
17
|
## Quick Start
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
# Authenticate
|
|
21
|
-
|
|
20
|
+
# Authenticate (API key or browser)
|
|
21
|
+
protobox auth login
|
|
22
22
|
|
|
23
|
-
# Check health
|
|
24
|
-
|
|
23
|
+
# Check API health
|
|
24
|
+
protobox health
|
|
25
25
|
|
|
26
|
-
#
|
|
27
|
-
|
|
26
|
+
# Manage tools and toolsets
|
|
27
|
+
protobox tools list
|
|
28
|
+
protobox toolsets list
|
|
28
29
|
|
|
29
|
-
#
|
|
30
|
-
|
|
30
|
+
# Knowledge base + prompts
|
|
31
|
+
protobox kb list
|
|
32
|
+
protobox prompts list
|
|
31
33
|
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
chanl scenarios run <id>
|
|
35
|
-
|
|
36
|
-
# Manage tools
|
|
37
|
-
chanl tools list
|
|
38
|
-
chanl toolsets list
|
|
34
|
+
# Connect your MCP client (Claude, Cursor, …)
|
|
35
|
+
protobox mcp config --format claude
|
|
39
36
|
```
|
|
40
37
|
|
|
41
38
|
## Commands
|
|
42
39
|
|
|
43
40
|
| Command | Description |
|
|
44
41
|
|---------|-------------|
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
-
| `
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `chanl memory` | Manage agent memory |
|
|
56
|
-
| `chanl scorecards` | Manage evaluation scorecards |
|
|
57
|
-
| `chanl prompts` | Manage prompt templates |
|
|
58
|
-
| `chanl config` | CLI configuration |
|
|
59
|
-
| `chanl mcp` | MCP server status |
|
|
42
|
+
| `protobox auth` | Authenticate with API key or browser |
|
|
43
|
+
| `protobox health` | Check API health |
|
|
44
|
+
| `protobox workspaces` | Manage workspaces |
|
|
45
|
+
| `protobox tools` | Manage MCP tools |
|
|
46
|
+
| `protobox toolsets` | Manage tool collections |
|
|
47
|
+
| `protobox kb` | Manage knowledge base |
|
|
48
|
+
| `protobox prompts` | Manage prompt templates |
|
|
49
|
+
| `protobox mcp` | MCP server status + client config |
|
|
50
|
+
| `protobox chat` | Interactive chat session |
|
|
51
|
+
| `protobox config` | CLI configuration |
|
|
60
52
|
|
|
61
53
|
## Configuration
|
|
62
54
|
|
|
63
55
|
```bash
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
56
|
+
protobox config show # Show current config
|
|
57
|
+
protobox config set baseUrl <url> # Custom API endpoint
|
|
58
|
+
protobox config reset # Reset to production
|
|
67
59
|
```
|
|
68
60
|
|
|
69
|
-
Default API: `https://platform.
|
|
61
|
+
Default API: `https://platform.protobox.ai`
|
|
62
|
+
|
|
63
|
+
Environment overrides: `PROTOBOX_API_KEY`, `PROTOBOX_BASE_URL`, `PROTOBOX_WORKSPACE_ID`.
|
|
70
64
|
|
|
71
65
|
## Documentation
|
|
72
66
|
|
|
73
|
-
- [
|
|
74
|
-
- [
|
|
67
|
+
- [Protobox](https://protobox.ai)
|
|
68
|
+
- [Docs](https://docs.protobox.ai)
|
|
75
69
|
|
|
76
70
|
## License
|
|
77
71
|
|
package/dist/commands/auth.js
CHANGED
|
@@ -3,7 +3,7 @@ import { select } from "@inquirer/prompts";
|
|
|
3
3
|
import ora from "ora";
|
|
4
4
|
import chalk from "chalk";
|
|
5
5
|
import http from "node:http";
|
|
6
|
-
import {
|
|
6
|
+
import { ProtoboxSDK } from "@protoboxai/sdk";
|
|
7
7
|
import { configStore } from "../utils/config-store.js";
|
|
8
8
|
import {
|
|
9
9
|
printSuccess,
|
|
@@ -21,7 +21,7 @@ function createAuthCommand() {
|
|
|
21
21
|
return auth;
|
|
22
22
|
}
|
|
23
23
|
function createLoginCommand() {
|
|
24
|
-
return new Command("login").description("Authenticate with
|
|
24
|
+
return new Command("login").description("Authenticate with Protobox API").option("-k, --api-key <key>", "API key to use for authentication").option("--browser", "Force browser-based login (email/password or Google/Microsoft)").option("--base-url <url>", "Override the API base URL").addHelpText(
|
|
25
25
|
"after",
|
|
26
26
|
`
|
|
27
27
|
Login Methods:
|
|
@@ -29,9 +29,9 @@ Login Methods:
|
|
|
29
29
|
--api-key <key> Use an API key directly (skips browser)
|
|
30
30
|
|
|
31
31
|
Examples:
|
|
32
|
-
$
|
|
33
|
-
$
|
|
34
|
-
$
|
|
32
|
+
$ protobox login # Browser login (recommended)
|
|
33
|
+
$ protobox login --api-key ak_xxx # API key login
|
|
34
|
+
$ protobox login --base-url http://localhost:3100 # Custom API URL`
|
|
35
35
|
).action(handleLogin);
|
|
36
36
|
}
|
|
37
37
|
function createLogoutCommand() {
|
|
@@ -51,7 +51,7 @@ async function handleApiKeyLogin(apiKey) {
|
|
|
51
51
|
const baseUrl = configStore.getBaseUrl();
|
|
52
52
|
const spinner = ora("Validating API key...").start();
|
|
53
53
|
try {
|
|
54
|
-
const sdk = new
|
|
54
|
+
const sdk = new ProtoboxSDK({ apiKey, baseUrl });
|
|
55
55
|
const healthResponse = await sdk.health.getHealth();
|
|
56
56
|
if (!healthResponse.success) {
|
|
57
57
|
spinner.fail("Cannot connect to API");
|
|
@@ -97,7 +97,7 @@ async function handleBrowserLogin() {
|
|
|
97
97
|
const spinner = ora("Waiting for authentication...").start();
|
|
98
98
|
const token = await firebaseToken;
|
|
99
99
|
spinner.text = "Exchanging token...";
|
|
100
|
-
const sdk = new
|
|
100
|
+
const sdk = new ProtoboxSDK({ baseUrl });
|
|
101
101
|
const response = await sdk.auth.exchangeFirebaseToken(token);
|
|
102
102
|
if (!response.success || !response.data) {
|
|
103
103
|
spinner.fail("Token exchange failed");
|
|
@@ -257,8 +257,8 @@ async function handleAuthStatus() {
|
|
|
257
257
|
if (!authMethod) {
|
|
258
258
|
printLabel("Status", chalk.yellow("Not authenticated"));
|
|
259
259
|
printBlank();
|
|
260
|
-
printInfo("Run '
|
|
261
|
-
printInfo("Run '
|
|
260
|
+
printInfo("Run 'protobox login' to authenticate via browser");
|
|
261
|
+
printInfo("Run 'protobox login --api-key <key>' to use an API key");
|
|
262
262
|
return;
|
|
263
263
|
}
|
|
264
264
|
printLabel("Status", chalk.green("Authenticated"));
|
|
@@ -276,7 +276,7 @@ async function handleAuthStatus() {
|
|
|
276
276
|
} else {
|
|
277
277
|
sdkConfig.jwtToken = configStore.getJwtToken();
|
|
278
278
|
}
|
|
279
|
-
const sdk = new
|
|
279
|
+
const sdk = new ProtoboxSDK(sdkConfig);
|
|
280
280
|
const response = await sdk.workspace.getById(workspaceId);
|
|
281
281
|
if (response.success && response.data?.name) {
|
|
282
282
|
printLabel("Workspace Name", response.data.name);
|
package/dist/commands/chat.js
CHANGED
|
@@ -17,7 +17,7 @@ function createChatCommand() {
|
|
|
17
17
|
`
|
|
18
18
|
What is Chat?
|
|
19
19
|
Chat lets you test an AI agent via text in your terminal. It creates a session
|
|
20
|
-
on the
|
|
20
|
+
on the Protobox platform, which manages the full lifecycle including
|
|
21
21
|
transcription, billing, and post-chat evaluation.
|
|
22
22
|
|
|
23
23
|
Modes:
|
|
@@ -31,12 +31,12 @@ Streaming:
|
|
|
31
31
|
Note: streaming responses do not include tool call metadata.
|
|
32
32
|
|
|
33
33
|
Examples:
|
|
34
|
-
$
|
|
35
|
-
$
|
|
36
|
-
$
|
|
37
|
-
$
|
|
38
|
-
$
|
|
39
|
-
$
|
|
34
|
+
$ protobox chat abc123 # Interactive chat
|
|
35
|
+
$ protobox chat abc123 --stream # Interactive with streaming
|
|
36
|
+
$ protobox chat abc123 --message "Hello" # Single message mode
|
|
37
|
+
$ protobox chat abc123 --message "Hi" --stream # Single message, streamed
|
|
38
|
+
$ protobox chat abc123 --message "Hi" --json # Single message, JSON output
|
|
39
|
+
$ protobox chat abc123 --workspace ws_456 # Override workspace`
|
|
40
40
|
).action(handleChat);
|
|
41
41
|
return chat;
|
|
42
42
|
}
|
package/dist/commands/config.js
CHANGED
|
@@ -21,13 +21,13 @@ const VALID_KEYS = [
|
|
|
21
21
|
"defaultFormat"
|
|
22
22
|
];
|
|
23
23
|
const ENVIRONMENT_PRESETS = {
|
|
24
|
-
production: "https://platform.
|
|
24
|
+
production: "https://platform.protobox.ai"
|
|
25
25
|
};
|
|
26
26
|
const KEY_DESCRIPTIONS = {
|
|
27
|
-
apiKey: "
|
|
27
|
+
apiKey: "Protobox API key for authentication",
|
|
28
28
|
jwtToken: "JWT access token (from browser login)",
|
|
29
29
|
refreshToken: "JWT refresh token (from browser login)",
|
|
30
|
-
baseUrl: "Base URL for the
|
|
30
|
+
baseUrl: "Base URL for the Protobox API",
|
|
31
31
|
server: "Alias for baseUrl (e.g. http://localhost:18005)",
|
|
32
32
|
deployment: "local | cloud \u2014 local rewrites /api/v1 paths for OSS scenario servers",
|
|
33
33
|
apiPrefix: "Override API prefix; empty string for flat /scenarios routes",
|
|
@@ -197,9 +197,9 @@ function isValidKey(key) {
|
|
|
197
197
|
}
|
|
198
198
|
function getConfigSource(key) {
|
|
199
199
|
const envVarMap = {
|
|
200
|
-
apiKey: "
|
|
201
|
-
baseUrl: "
|
|
202
|
-
workspaceId: "
|
|
200
|
+
apiKey: "PROTOBOX_API_KEY",
|
|
201
|
+
baseUrl: "PROTOBOX_BASE_URL",
|
|
202
|
+
workspaceId: "PROTOBOX_WORKSPACE_ID"
|
|
203
203
|
};
|
|
204
204
|
const envVar = envVarMap[key];
|
|
205
205
|
if (envVar && process.env[envVar]) {
|
package/dist/commands/health.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import ora from "ora";
|
|
3
3
|
import chalk from "chalk";
|
|
4
|
-
import {
|
|
4
|
+
import { ProtoboxSDK } from "@protoboxai/sdk";
|
|
5
5
|
import { configStore } from "../utils/config-store.js";
|
|
6
6
|
import {
|
|
7
7
|
printSuccess,
|
|
@@ -16,7 +16,7 @@ function createHealthCommand() {
|
|
|
16
16
|
}
|
|
17
17
|
async function handleHealth() {
|
|
18
18
|
const baseUrl = configStore.getBaseUrl();
|
|
19
|
-
const sdk = new
|
|
19
|
+
const sdk = new ProtoboxSDK({ baseUrl });
|
|
20
20
|
const spinner = ora("Checking API health...").start();
|
|
21
21
|
try {
|
|
22
22
|
const response = await sdk.health.getHealth();
|
|
@@ -3,7 +3,7 @@ import ora from "ora";
|
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { readFileSync, existsSync } from "fs";
|
|
5
5
|
import { resolve } from "path";
|
|
6
|
-
import {
|
|
6
|
+
import { ProtoboxSDK } from "@protoboxai/sdk";
|
|
7
7
|
import { configStore } from "../utils/config-store.js";
|
|
8
8
|
import {
|
|
9
9
|
printError,
|
|
@@ -25,11 +25,11 @@ What is Knowledge Base?
|
|
|
25
25
|
can search and retrieve during conversations. Supports text, URLs, and files.
|
|
26
26
|
|
|
27
27
|
Quick Start:
|
|
28
|
-
$
|
|
29
|
-
$
|
|
30
|
-
$
|
|
31
|
-
$
|
|
32
|
-
$
|
|
28
|
+
$ protobox kb list # List all entries
|
|
29
|
+
$ protobox kb add --text "FAQ content" --title "FAQ" # Add text content
|
|
30
|
+
$ protobox kb add --url https://docs.example.com # Add from URL
|
|
31
|
+
$ protobox kb add --file ./docs/guide.pdf # Upload file
|
|
32
|
+
$ protobox kb search "how do I reset password" # Search KB
|
|
33
33
|
|
|
34
34
|
Workflow:
|
|
35
35
|
1. Add content via text, URL, or file upload
|
|
@@ -40,43 +40,43 @@ Workflow:
|
|
|
40
40
|
"after",
|
|
41
41
|
`
|
|
42
42
|
Examples:
|
|
43
|
-
$
|
|
44
|
-
$
|
|
45
|
-
$
|
|
46
|
-
$
|
|
43
|
+
$ protobox kb list # List all entries
|
|
44
|
+
$ protobox kb list --source url # Only URL-sourced entries
|
|
45
|
+
$ protobox kb list --status completed # Only fully processed
|
|
46
|
+
$ protobox kb list --json # Output as JSON`
|
|
47
47
|
).action(handleKnowledgeList);
|
|
48
48
|
knowledge.command("get <id>").description("Get knowledge entry details").option("--chunks", "Include chunk details").addHelpText(
|
|
49
49
|
"after",
|
|
50
50
|
`
|
|
51
51
|
Examples:
|
|
52
|
-
$
|
|
53
|
-
$
|
|
54
|
-
$
|
|
52
|
+
$ protobox kb get abc123 # Get entry details
|
|
53
|
+
$ protobox kb get abc123 --chunks # Include chunks
|
|
54
|
+
$ protobox kb get abc123 --json # Output as JSON`
|
|
55
55
|
).action(handleKnowledgeGet);
|
|
56
56
|
knowledge.command("add").description("Add knowledge content (text, URL, or file)").option("-t, --title <title>", "Title for the entry").option("--text <content>", "Direct text content").option("--url <url>", "URL to fetch content from").option("-f, --file <path>", "File to upload (PDF, TXT, HTML, MD)").option("--folder <folderId>", "Folder ID to organize entry").option("--tags <tags>", "Comma-separated tags").option("--category <category>", "Category for organization").option("--crawl-depth <depth>", "URL crawl depth (0-2)", "0").option("--max-pages <pages>", "Max pages to crawl (1-50)", "10").addHelpText(
|
|
57
57
|
"after",
|
|
58
58
|
`
|
|
59
59
|
Examples:
|
|
60
|
-
$
|
|
61
|
-
$
|
|
62
|
-
$
|
|
63
|
-
$
|
|
64
|
-
$
|
|
60
|
+
$ protobox kb add --text "Content here" --title "FAQ"
|
|
61
|
+
$ protobox kb add --url https://docs.example.com --title "Docs"
|
|
62
|
+
$ protobox kb add --url https://docs.example.com --crawl-depth 1 --max-pages 20
|
|
63
|
+
$ protobox kb add --file ./guide.pdf --title "User Guide"
|
|
64
|
+
$ protobox kb add --text "Content" --tags "faq,support" --category "support"`
|
|
65
65
|
).action(handleKnowledgeAdd);
|
|
66
66
|
knowledge.command("update <id>").description("Update a knowledge entry").option("-t, --title <title>", "New title").option("--content <content>", "New content (text entries only)").option("--tags <tags>", "Comma-separated tags").option("--category <category>", "Category").option("--enabled <boolean>", "Enable/disable for search").addHelpText(
|
|
67
67
|
"after",
|
|
68
68
|
`
|
|
69
69
|
Examples:
|
|
70
|
-
$
|
|
71
|
-
$
|
|
72
|
-
$
|
|
70
|
+
$ protobox kb update abc123 --title "New Title"
|
|
71
|
+
$ protobox kb update abc123 --enabled false
|
|
72
|
+
$ protobox kb update abc123 --tags "updated,important"`
|
|
73
73
|
).action(handleKnowledgeUpdate);
|
|
74
74
|
knowledge.command("delete <id>").description("Delete a knowledge entry").option("-y, --yes", "Skip confirmation prompt").addHelpText(
|
|
75
75
|
"after",
|
|
76
76
|
`
|
|
77
77
|
Examples:
|
|
78
|
-
$
|
|
79
|
-
$
|
|
78
|
+
$ protobox kb delete abc123
|
|
79
|
+
$ protobox kb delete abc123 --yes # Skip confirmation`
|
|
80
80
|
).action(handleKnowledgeDelete);
|
|
81
81
|
knowledge.command("search <query>").description("Search the knowledge base").option("-m, --mode <mode>", "Search mode: hybrid, vector, text", "hybrid").option("-l, --limit <number>", "Max results", "10").option("--min-score <score>", "Minimum similarity score (0-1)").addHelpText(
|
|
82
82
|
"after",
|
|
@@ -87,26 +87,26 @@ Search Modes:
|
|
|
87
87
|
text - Full-text keyword search
|
|
88
88
|
|
|
89
89
|
Examples:
|
|
90
|
-
$
|
|
91
|
-
$
|
|
92
|
-
$
|
|
90
|
+
$ protobox kb search "how to reset password"
|
|
91
|
+
$ protobox kb search "API authentication" --mode vector
|
|
92
|
+
$ protobox kb search "billing" --limit 5 --min-score 0.7`
|
|
93
93
|
).action(handleKnowledgeSearch);
|
|
94
94
|
knowledge.command("status <taskId>").description("Check processing status of async upload").addHelpText(
|
|
95
95
|
"after",
|
|
96
96
|
`
|
|
97
97
|
Examples:
|
|
98
|
-
$
|
|
98
|
+
$ protobox kb status abc123 # Check task status`
|
|
99
99
|
).action(handleKnowledgeStatus);
|
|
100
100
|
return knowledge;
|
|
101
101
|
}
|
|
102
102
|
async function handleKnowledgeList(options) {
|
|
103
103
|
const apiKey = configStore.getApiKey();
|
|
104
104
|
if (!apiKey) {
|
|
105
|
-
printError("Not logged in", "Run:
|
|
105
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
106
106
|
process.exitCode = 1;
|
|
107
107
|
return;
|
|
108
108
|
}
|
|
109
|
-
const sdk = new
|
|
109
|
+
const sdk = new ProtoboxSDK({
|
|
110
110
|
baseUrl: configStore.getBaseUrl(),
|
|
111
111
|
apiKey
|
|
112
112
|
});
|
|
@@ -163,11 +163,11 @@ async function handleKnowledgeList(options) {
|
|
|
163
163
|
async function handleKnowledgeGet(id, options) {
|
|
164
164
|
const apiKey = configStore.getApiKey();
|
|
165
165
|
if (!apiKey) {
|
|
166
|
-
printError("Not logged in", "Run:
|
|
166
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
167
167
|
process.exitCode = 1;
|
|
168
168
|
return;
|
|
169
169
|
}
|
|
170
|
-
const sdk = new
|
|
170
|
+
const sdk = new ProtoboxSDK({
|
|
171
171
|
baseUrl: configStore.getBaseUrl(),
|
|
172
172
|
apiKey
|
|
173
173
|
});
|
|
@@ -231,7 +231,7 @@ async function handleKnowledgeGet(id, options) {
|
|
|
231
231
|
async function handleKnowledgeAdd(options) {
|
|
232
232
|
const apiKey = configStore.getApiKey();
|
|
233
233
|
if (!apiKey) {
|
|
234
|
-
printError("Not logged in", "Run:
|
|
234
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
235
235
|
process.exitCode = 1;
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
@@ -246,7 +246,7 @@ async function handleKnowledgeAdd(options) {
|
|
|
246
246
|
process.exitCode = 1;
|
|
247
247
|
return;
|
|
248
248
|
}
|
|
249
|
-
const sdk = new
|
|
249
|
+
const sdk = new ProtoboxSDK({
|
|
250
250
|
baseUrl: configStore.getBaseUrl(),
|
|
251
251
|
apiKey
|
|
252
252
|
});
|
|
@@ -309,7 +309,7 @@ async function handleKnowledgeAdd(options) {
|
|
|
309
309
|
printLabel("ID", entry.id);
|
|
310
310
|
printLabel("Task ID", entry.taskId);
|
|
311
311
|
printLabel("Status", formatStatus(entry.processingStatus));
|
|
312
|
-
printInfo(`Track progress:
|
|
312
|
+
printInfo(`Track progress: protobox kb status ${entry.taskId}`);
|
|
313
313
|
} else {
|
|
314
314
|
printSuccess(`Knowledge entry created`);
|
|
315
315
|
printLabel("ID", entry.id);
|
|
@@ -327,11 +327,11 @@ async function handleKnowledgeAdd(options) {
|
|
|
327
327
|
async function handleKnowledgeUpdate(id, options) {
|
|
328
328
|
const apiKey = configStore.getApiKey();
|
|
329
329
|
if (!apiKey) {
|
|
330
|
-
printError("Not logged in", "Run:
|
|
330
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
331
331
|
process.exitCode = 1;
|
|
332
332
|
return;
|
|
333
333
|
}
|
|
334
|
-
const sdk = new
|
|
334
|
+
const sdk = new ProtoboxSDK({
|
|
335
335
|
baseUrl: configStore.getBaseUrl(),
|
|
336
336
|
apiKey
|
|
337
337
|
});
|
|
@@ -377,7 +377,7 @@ async function handleKnowledgeUpdate(id, options) {
|
|
|
377
377
|
async function handleKnowledgeDelete(id, options) {
|
|
378
378
|
const apiKey = configStore.getApiKey();
|
|
379
379
|
if (!apiKey) {
|
|
380
|
-
printError("Not logged in", "Run:
|
|
380
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
381
381
|
process.exitCode = 1;
|
|
382
382
|
return;
|
|
383
383
|
}
|
|
@@ -396,7 +396,7 @@ async function handleKnowledgeDelete(id, options) {
|
|
|
396
396
|
return;
|
|
397
397
|
}
|
|
398
398
|
}
|
|
399
|
-
const sdk = new
|
|
399
|
+
const sdk = new ProtoboxSDK({
|
|
400
400
|
baseUrl: configStore.getBaseUrl(),
|
|
401
401
|
apiKey
|
|
402
402
|
});
|
|
@@ -421,11 +421,11 @@ async function handleKnowledgeDelete(id, options) {
|
|
|
421
421
|
async function handleKnowledgeSearch(query, options) {
|
|
422
422
|
const apiKey = configStore.getApiKey();
|
|
423
423
|
if (!apiKey) {
|
|
424
|
-
printError("Not logged in", "Run:
|
|
424
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
425
425
|
process.exitCode = 1;
|
|
426
426
|
return;
|
|
427
427
|
}
|
|
428
|
-
const sdk = new
|
|
428
|
+
const sdk = new ProtoboxSDK({
|
|
429
429
|
baseUrl: configStore.getBaseUrl(),
|
|
430
430
|
apiKey
|
|
431
431
|
});
|
|
@@ -475,11 +475,11 @@ async function handleKnowledgeSearch(query, options) {
|
|
|
475
475
|
async function handleKnowledgeStatus(taskId) {
|
|
476
476
|
const apiKey = configStore.getApiKey();
|
|
477
477
|
if (!apiKey) {
|
|
478
|
-
printError("Not logged in", "Run:
|
|
478
|
+
printError("Not logged in", "Run: protobox auth login");
|
|
479
479
|
process.exitCode = 1;
|
|
480
480
|
return;
|
|
481
481
|
}
|
|
482
|
-
const sdk = new
|
|
482
|
+
const sdk = new ProtoboxSDK({
|
|
483
483
|
baseUrl: configStore.getBaseUrl(),
|
|
484
484
|
apiKey
|
|
485
485
|
});
|
package/dist/commands/mcp.js
CHANGED
|
@@ -21,31 +21,31 @@ function createMcpCommand() {
|
|
|
21
21
|
`
|
|
22
22
|
What is MCP?
|
|
23
23
|
Model Context Protocol (MCP) lets AI agents (Claude, Cursor, etc.) use your
|
|
24
|
-
|
|
24
|
+
Protobox tools, knowledge base, and prompts. The MCP server bridges your workspace
|
|
25
25
|
with AI clients.
|
|
26
26
|
|
|
27
27
|
Quick Start:
|
|
28
|
-
$
|
|
29
|
-
$
|
|
30
|
-
$
|
|
28
|
+
$ protobox mcp # Check server status
|
|
29
|
+
$ protobox mcp test # Run protocol test
|
|
30
|
+
$ protobox mcp config # Get config for your AI client
|
|
31
31
|
|
|
32
32
|
Connecting AI Clients:
|
|
33
|
-
1. Run '
|
|
33
|
+
1. Run 'protobox mcp config --format claude' to get Claude Desktop config
|
|
34
34
|
2. Add the JSON to Claude Desktop's settings
|
|
35
|
-
3. Your
|
|
35
|
+
3. Your Protobox tools will appear in Claude!`
|
|
36
36
|
).action(handleMcpDefault);
|
|
37
37
|
mcp.command("info").description("Show MCP server URL, status, and resource counts").addHelpText(
|
|
38
38
|
"after",
|
|
39
39
|
`
|
|
40
40
|
Example:
|
|
41
|
-
$
|
|
42
|
-
$
|
|
41
|
+
$ protobox mcp info # Show server details
|
|
42
|
+
$ protobox mcp info --json # Output as JSON`
|
|
43
43
|
).action(handleMcpInfo);
|
|
44
44
|
mcp.command("status").description("Health check the MCP server").addHelpText(
|
|
45
45
|
"after",
|
|
46
46
|
`
|
|
47
47
|
Example:
|
|
48
|
-
$
|
|
48
|
+
$ protobox mcp status # Quick health check`
|
|
49
49
|
).action(handleMcpStatus);
|
|
50
50
|
mcp.command("test").description("Run MCP protocol test with real MCP client").addHelpText(
|
|
51
51
|
"after",
|
|
@@ -57,8 +57,8 @@ Tests the full MCP protocol handshake:
|
|
|
57
57
|
4. List prompts
|
|
58
58
|
|
|
59
59
|
Example:
|
|
60
|
-
$
|
|
61
|
-
$
|
|
60
|
+
$ protobox mcp test # Run all protocol tests
|
|
61
|
+
$ protobox mcp test --json # Output results as JSON`
|
|
62
62
|
).action(handleMcpTest);
|
|
63
63
|
mcp.command("config").description("Output MCP configuration for AI clients").option("-f, --format <format>", "Format: claude, cursor, generic", "generic").addHelpText(
|
|
64
64
|
"after",
|
|
@@ -71,13 +71,13 @@ Supported formats:
|
|
|
71
71
|
generic - Generic MCP client format
|
|
72
72
|
|
|
73
73
|
Examples:
|
|
74
|
-
$
|
|
75
|
-
$
|
|
76
|
-
$
|
|
77
|
-
$
|
|
74
|
+
$ protobox mcp config # Generic format
|
|
75
|
+
$ protobox mcp config --format claude # Claude Desktop format
|
|
76
|
+
$ protobox mcp config --format cursor # Cursor IDE format
|
|
77
|
+
$ protobox mcp config --format claude > config.json # Save to file
|
|
78
78
|
|
|
79
79
|
Setup Claude Desktop:
|
|
80
|
-
1. Run:
|
|
80
|
+
1. Run: protobox mcp config --format claude
|
|
81
81
|
2. Copy the JSON output
|
|
82
82
|
3. Paste into ~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
83
83
|
).action(handleMcpConfig);
|
|
@@ -85,23 +85,23 @@ Setup Claude Desktop:
|
|
|
85
85
|
"after",
|
|
86
86
|
`
|
|
87
87
|
Example:
|
|
88
|
-
$
|
|
89
|
-
$
|
|
88
|
+
$ protobox mcp tools agent_123 # List tools for agent
|
|
89
|
+
$ protobox mcp tools agent_123 --json # Output as JSON`
|
|
90
90
|
).action(handleMcpTools);
|
|
91
91
|
mcp.command("call <agent-id> <tool-name> [args]").description("Call an MCP tool by name").addHelpText(
|
|
92
92
|
"after",
|
|
93
93
|
`
|
|
94
94
|
Example:
|
|
95
|
-
$
|
|
96
|
-
$
|
|
97
|
-
$
|
|
95
|
+
$ protobox mcp call agent_123 get_weather '{"city":"London"}'
|
|
96
|
+
$ protobox mcp call agent_123 ping
|
|
97
|
+
$ protobox mcp call agent_123 get_weather '{"city":"London"}' --json`
|
|
98
98
|
).action(handleMcpCall);
|
|
99
99
|
mcp.command("inspect <agent-id> <tool-name>").description("Show schema and details for a specific MCP tool").addHelpText(
|
|
100
100
|
"after",
|
|
101
101
|
`
|
|
102
102
|
Example:
|
|
103
|
-
$
|
|
104
|
-
$
|
|
103
|
+
$ protobox mcp inspect agent_123 get_weather
|
|
104
|
+
$ protobox mcp inspect agent_123 get_weather --json`
|
|
105
105
|
).action(handleMcpInspect);
|
|
106
106
|
mcp.command("install").description("Generate MCP config snippet for editors (Cursor, VSCode, Claude)").option("-f, --format <format>", "Format: claude, cursor, vscode, generic", "generic").addHelpText(
|
|
107
107
|
"after",
|
|
@@ -116,11 +116,11 @@ Supported formats:
|
|
|
116
116
|
generic - Generic MCP client (default)
|
|
117
117
|
|
|
118
118
|
Examples:
|
|
119
|
-
$
|
|
120
|
-
$
|
|
121
|
-
$
|
|
122
|
-
$
|
|
123
|
-
$
|
|
119
|
+
$ protobox mcp install # Generic format
|
|
120
|
+
$ protobox mcp install --format claude # Claude Desktop format
|
|
121
|
+
$ protobox mcp install --format cursor # Cursor IDE format
|
|
122
|
+
$ protobox mcp install --format vscode # VSCode format
|
|
123
|
+
$ protobox mcp install --format claude > mcp.json # Save to file`
|
|
124
124
|
).action(handleMcpInstall);
|
|
125
125
|
return mcp;
|
|
126
126
|
}
|
|
@@ -201,6 +201,19 @@ async function handleMcpStatus() {
|
|
|
201
201
|
process.exitCode = 1;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
+
function rebrandMcpServerKey(cfg) {
|
|
205
|
+
if (!cfg || typeof cfg !== "object") return cfg;
|
|
206
|
+
const obj = cfg;
|
|
207
|
+
const servers = obj["mcpServers"];
|
|
208
|
+
if (servers && typeof servers === "object" && !Array.isArray(servers)) {
|
|
209
|
+
const s = servers;
|
|
210
|
+
if ("chanl" in s && !("protobox" in s)) {
|
|
211
|
+
const { chanl, ...rest } = s;
|
|
212
|
+
return { ...obj, mcpServers: { protobox: chanl, ...rest } };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return cfg;
|
|
216
|
+
}
|
|
204
217
|
async function handleMcpConfig(options) {
|
|
205
218
|
const sdk = createSdk();
|
|
206
219
|
if (!sdk) return;
|
|
@@ -228,11 +241,12 @@ async function handleMcpConfig(options) {
|
|
|
228
241
|
output = config.agentConfigs.generic;
|
|
229
242
|
break;
|
|
230
243
|
}
|
|
244
|
+
output = rebrandMcpServerKey(output);
|
|
231
245
|
printJson(output);
|
|
232
246
|
if (!isJsonOutput()) {
|
|
233
247
|
printBlank();
|
|
234
248
|
printInfo(`Configuration for ${format} format. Copy and paste into your ${format === "claude" ? "Claude Desktop" : format === "cursor" ? "Cursor IDE" : "MCP client"} configuration.`);
|
|
235
|
-
printInfo(`Replace \${
|
|
249
|
+
printInfo(`Replace \${PROTOBOX_MCP_API_KEY} with your actual MCP API key.`);
|
|
236
250
|
}
|
|
237
251
|
} catch (error) {
|
|
238
252
|
spinner.fail("Failed to fetch MCP configuration");
|
|
@@ -276,7 +290,7 @@ async function handleMcpDefault() {
|
|
|
276
290
|
console.log(chalk.dim("\u2500".repeat(40)));
|
|
277
291
|
printBlank();
|
|
278
292
|
if (!status?.healthy) {
|
|
279
|
-
printInfo("Run '
|
|
293
|
+
printInfo("Run 'protobox mcp test' for detailed diagnostics");
|
|
280
294
|
process.exitCode = 1;
|
|
281
295
|
}
|
|
282
296
|
} catch (error) {
|
|
@@ -432,11 +446,11 @@ async function handleMcpInspect(agentId, toolName) {
|
|
|
432
446
|
async function handleMcpInstall(options) {
|
|
433
447
|
const apiKey = configStore.getApiKey();
|
|
434
448
|
if (!apiKey) {
|
|
435
|
-
printError("Not authenticated", "Run '
|
|
449
|
+
printError("Not authenticated", "Run 'protobox login' to authenticate first");
|
|
436
450
|
process.exitCode = 1;
|
|
437
451
|
return;
|
|
438
452
|
}
|
|
439
|
-
const baseUrl = configStore.getBaseUrl() || "https://
|
|
453
|
+
const baseUrl = configStore.getBaseUrl() || "https://platform.protobox.ai";
|
|
440
454
|
const mcpUrl = baseUrl.replace(/\/$/, "") + "/mcp";
|
|
441
455
|
const format = options.format.toLowerCase();
|
|
442
456
|
const serverConfig = {
|
|
@@ -449,21 +463,21 @@ async function handleMcpInstall(options) {
|
|
|
449
463
|
case "claude":
|
|
450
464
|
output = {
|
|
451
465
|
mcpServers: {
|
|
452
|
-
|
|
466
|
+
protobox: serverConfig
|
|
453
467
|
}
|
|
454
468
|
};
|
|
455
469
|
break;
|
|
456
470
|
case "cursor":
|
|
457
471
|
output = {
|
|
458
472
|
mcpServers: {
|
|
459
|
-
|
|
473
|
+
protobox: serverConfig
|
|
460
474
|
}
|
|
461
475
|
};
|
|
462
476
|
break;
|
|
463
477
|
case "vscode":
|
|
464
478
|
output = {
|
|
465
479
|
mcpServers: {
|
|
466
|
-
|
|
480
|
+
protobox: serverConfig
|
|
467
481
|
}
|
|
468
482
|
};
|
|
469
483
|
break;
|
|
@@ -471,7 +485,7 @@ async function handleMcpInstall(options) {
|
|
|
471
485
|
default:
|
|
472
486
|
output = {
|
|
473
487
|
mcpServers: {
|
|
474
|
-
|
|
488
|
+
protobox: serverConfig
|
|
475
489
|
}
|
|
476
490
|
};
|
|
477
491
|
break;
|
|
@@ -521,7 +535,7 @@ async function handleMcpTest() {
|
|
|
521
535
|
}
|
|
522
536
|
});
|
|
523
537
|
const client = new Client(
|
|
524
|
-
{ name: "
|
|
538
|
+
{ name: "protobox-cli", version: "1.0.0" },
|
|
525
539
|
{ capabilities: {} }
|
|
526
540
|
);
|
|
527
541
|
spinner.text = "Connecting to MCP server...";
|
package/dist/commands/prompts.js
CHANGED
|
@@ -23,33 +23,33 @@ What are Prompts?
|
|
|
23
23
|
variables, versioning, and categories for organizing across use cases.
|
|
24
24
|
|
|
25
25
|
Quick Start:
|
|
26
|
-
$
|
|
27
|
-
$
|
|
28
|
-
$
|
|
29
|
-
$
|
|
30
|
-
$
|
|
26
|
+
$ protobox prompts list # List all prompts
|
|
27
|
+
$ protobox prompts get <id> # View prompt details
|
|
28
|
+
$ protobox prompts create -f prompt.json # Create from JSON file
|
|
29
|
+
$ protobox prompts update <id> -f data.json # Update a prompt
|
|
30
|
+
$ protobox prompts delete <id> # Delete a prompt`
|
|
31
31
|
);
|
|
32
32
|
prompts.command("list").description("List all prompts").option("-c, --category <category>", "Filter by category (support, sales, onboarding, general)").option("-s, --status <status>", "Filter by status (active, draft, archived)").option("--search <query>", "Search by name or content").option("-l, --limit <number>", "Number of items per page", "20").option("--page <number>", "Page number", "1").addHelpText(
|
|
33
33
|
"after",
|
|
34
34
|
`
|
|
35
35
|
Examples:
|
|
36
|
-
$
|
|
37
|
-
$
|
|
38
|
-
$
|
|
39
|
-
$
|
|
36
|
+
$ protobox prompts list # List all prompts
|
|
37
|
+
$ protobox prompts list --category support # Filter by category
|
|
38
|
+
$ protobox prompts list --status active # Only active prompts
|
|
39
|
+
$ protobox prompts list --json # Output as JSON`
|
|
40
40
|
).action(handlePromptsList);
|
|
41
41
|
prompts.command("get <id>").description("Get prompt details").addHelpText(
|
|
42
42
|
"after",
|
|
43
43
|
`
|
|
44
44
|
Examples:
|
|
45
|
-
$
|
|
46
|
-
$
|
|
45
|
+
$ protobox prompts get abc123 # Get prompt details
|
|
46
|
+
$ protobox prompts get abc123 --json # Output as JSON`
|
|
47
47
|
).action(handlePromptsGet);
|
|
48
48
|
prompts.command("create").description("Create a new prompt").option("-f, --file <path>", "Path to JSON file with prompt data").addHelpText(
|
|
49
49
|
"after",
|
|
50
50
|
`
|
|
51
51
|
Examples:
|
|
52
|
-
$
|
|
52
|
+
$ protobox prompts create -f prompt.json # Create from file
|
|
53
53
|
|
|
54
54
|
JSON file format:
|
|
55
55
|
{
|
|
@@ -64,14 +64,14 @@ JSON file format:
|
|
|
64
64
|
"after",
|
|
65
65
|
`
|
|
66
66
|
Examples:
|
|
67
|
-
$
|
|
67
|
+
$ protobox prompts update abc123 -f updates.json`
|
|
68
68
|
).action(handlePromptsUpdate);
|
|
69
69
|
prompts.command("delete <id>").description("Delete a prompt").option("-y, --yes", "Skip confirmation prompt").addHelpText(
|
|
70
70
|
"after",
|
|
71
71
|
`
|
|
72
72
|
Examples:
|
|
73
|
-
$
|
|
74
|
-
$
|
|
73
|
+
$ protobox prompts delete abc123
|
|
74
|
+
$ protobox prompts delete abc123 --yes # Skip confirmation`
|
|
75
75
|
).action(handlePromptsDelete);
|
|
76
76
|
return prompts;
|
|
77
77
|
}
|
|
@@ -112,7 +112,7 @@ async function handlePromptsList(options) {
|
|
|
112
112
|
}
|
|
113
113
|
if (prompts.length === 0) {
|
|
114
114
|
printInfo("No prompts found");
|
|
115
|
-
printInfo("Use '
|
|
115
|
+
printInfo("Use 'protobox prompts create -f prompt.json' to create a prompt");
|
|
116
116
|
return;
|
|
117
117
|
}
|
|
118
118
|
printBlank();
|
package/dist/commands/tools.js
CHANGED
|
@@ -60,30 +60,30 @@ const TOOL_TEMPLATES = {
|
|
|
60
60
|
};
|
|
61
61
|
function createToolsCommand() {
|
|
62
62
|
const tools = new Command("tools").description("Manage MCP tools");
|
|
63
|
-
tools.command("list").description("List all tools in the workspace").option("-t, --type <type>", "Filter by type: http, javascript, code").option("-e, --enabled", "Show only enabled tools").option("-d, --disabled", "Show only disabled tools").option("--tag <tag>", "Filter by tag (e.g., --tag api)").option("--no-system", "Exclude system tools (kb_search
|
|
63
|
+
tools.command("list").description("List all tools in the workspace").option("-t, --type <type>", "Filter by type: http, javascript, code").option("-e, --enabled", "Show only enabled tools").option("-d, --disabled", "Show only disabled tools").option("--tag <tag>", "Filter by tag (e.g., --tag api)").option("--no-system", "Exclude system tools (e.g. kb_search)").option("-l, --limit <number>", "Items per page (default: 20)", "20").option("-p, --page <number>", "Page number (default: 1)", "1").addHelpText(
|
|
64
64
|
"after",
|
|
65
65
|
`
|
|
66
66
|
Examples:
|
|
67
|
-
$
|
|
68
|
-
$
|
|
69
|
-
$
|
|
70
|
-
$
|
|
71
|
-
$
|
|
72
|
-
$
|
|
67
|
+
$ protobox tools list # List all tools
|
|
68
|
+
$ protobox tools list --enabled # Only enabled tools
|
|
69
|
+
$ protobox tools list --type http # Only HTTP tools
|
|
70
|
+
$ protobox tools list --tag api # Filter by tag
|
|
71
|
+
$ protobox tools list --no-system # Exclude system tools
|
|
72
|
+
$ protobox tools list --json # Output as JSON`
|
|
73
73
|
).action(handleToolsList);
|
|
74
74
|
tools.command("get <id>").description("Get detailed info about a tool").addHelpText(
|
|
75
75
|
"after",
|
|
76
76
|
`
|
|
77
77
|
Examples:
|
|
78
|
-
$
|
|
79
|
-
$
|
|
78
|
+
$ protobox tools get 507f1f77bcf86cd799439011
|
|
79
|
+
$ protobox tools get 507f1f77bcf86cd799439011 --json`
|
|
80
80
|
).action(handleToolsGet);
|
|
81
81
|
tools.command("create").description("Create a new tool from JSON file").option("-f, --file <path>", "Path to JSON file with tool definition").option("--template [type]", "Output a sample JSON template (http or javascript)").addHelpText(
|
|
82
82
|
"after",
|
|
83
83
|
`
|
|
84
84
|
Examples:
|
|
85
|
-
$
|
|
86
|
-
$
|
|
85
|
+
$ protobox tools create --template http > my-tool.json # Generate template
|
|
86
|
+
$ protobox tools create -f my-tool.json # Create from file
|
|
87
87
|
|
|
88
88
|
Required JSON fields:
|
|
89
89
|
name Tool name (used in MCP)
|
|
@@ -96,13 +96,13 @@ Optional fields:
|
|
|
96
96
|
isEnabled Enable immediately (default: true)
|
|
97
97
|
tags Array of category tags
|
|
98
98
|
|
|
99
|
-
Run '
|
|
99
|
+
Run 'protobox tools create --template' to see full structure.`
|
|
100
100
|
).action(handleToolsCreate);
|
|
101
101
|
tools.command("update <id>").description("Update a tool from JSON file").requiredOption("-f, --file <path>", "Path to JSON file with updates").addHelpText(
|
|
102
102
|
"after",
|
|
103
103
|
`
|
|
104
104
|
Examples:
|
|
105
|
-
$
|
|
105
|
+
$ protobox tools update 507f1f77bcf86cd799439011 -f updates.json
|
|
106
106
|
|
|
107
107
|
The JSON file only needs fields you want to change:
|
|
108
108
|
{"description": "Updated description", "isEnabled": false}`
|
|
@@ -111,28 +111,28 @@ The JSON file only needs fields you want to change:
|
|
|
111
111
|
"after",
|
|
112
112
|
`
|
|
113
113
|
Examples:
|
|
114
|
-
$
|
|
115
|
-
$
|
|
114
|
+
$ protobox tools delete 507f1f77bcf86cd799439011 # With confirmation
|
|
115
|
+
$ protobox tools delete 507f1f77bcf86cd799439011 -y # Skip confirmation`
|
|
116
116
|
).action(handleToolsDelete);
|
|
117
117
|
tools.command("execute <id>").description("Execute a tool and get results").requiredOption("-i, --input <json>", "Input arguments as JSON string").addHelpText(
|
|
118
118
|
"after",
|
|
119
119
|
`
|
|
120
120
|
Examples:
|
|
121
|
-
$
|
|
122
|
-
$
|
|
121
|
+
$ protobox tools execute 507f1f77bcf86cd799439011 -i '{"query": "hello"}'
|
|
122
|
+
$ protobox tools execute my-tool-id -i '{"location": "London"}' --json`
|
|
123
123
|
).action(handleToolsExecute);
|
|
124
124
|
tools.command("test <id>").description("Test a tool execution (dry run)").requiredOption("-i, --input <json>", "Input arguments as JSON string").addHelpText(
|
|
125
125
|
"after",
|
|
126
126
|
`
|
|
127
127
|
Examples:
|
|
128
|
-
$
|
|
128
|
+
$ protobox tools test 507f1f77bcf86cd799439011 -i '{"message": "test"}'`
|
|
129
129
|
).action(handleToolsTest);
|
|
130
130
|
tools.command("executions <id>").description("Get execution history for a tool").option("-l, --limit <number>", "Items per page (default: 10)", "10").option("-p, --page <number>", "Page number (default: 1)", "1").option("--status <status>", "Filter: pending, running, completed, failed").addHelpText(
|
|
131
131
|
"after",
|
|
132
132
|
`
|
|
133
133
|
Examples:
|
|
134
|
-
$
|
|
135
|
-
$
|
|
134
|
+
$ protobox tools executions 507f1f77bcf86cd799439011
|
|
135
|
+
$ protobox tools executions my-tool-id --status failed --limit 5`
|
|
136
136
|
).action(handleToolsExecutions);
|
|
137
137
|
tools.command("enable <id>").description("Enable a tool (makes it available in MCP)").action(handleToolsEnable);
|
|
138
138
|
tools.command("disable <id>").description("Disable a tool (hides from MCP)").action(handleToolsDisable);
|
|
@@ -168,7 +168,7 @@ async function handleToolsList(options) {
|
|
|
168
168
|
process.exitCode = 1;
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
|
-
const { tools, total, pagination } = response.data;
|
|
171
|
+
const { items: tools, total, pagination } = response.data;
|
|
172
172
|
if (isJsonOutput()) {
|
|
173
173
|
printJson({ tools, total, pagination });
|
|
174
174
|
return;
|
|
@@ -237,7 +237,7 @@ async function handleToolsCreate(options) {
|
|
|
237
237
|
}
|
|
238
238
|
if (!options.file) {
|
|
239
239
|
printError("Missing required option", "Use '-f, --file <path>' or '--template' for sample JSON");
|
|
240
|
-
printInfo("Run '
|
|
240
|
+
printInfo("Run 'protobox tools create --help' for usage");
|
|
241
241
|
process.exitCode = 1;
|
|
242
242
|
return;
|
|
243
243
|
}
|
|
@@ -433,7 +433,7 @@ async function handleToolsExecutions(id, options) {
|
|
|
433
433
|
process.exitCode = 1;
|
|
434
434
|
return;
|
|
435
435
|
}
|
|
436
|
-
const {
|
|
436
|
+
const { items: executions, total, pagination } = response.data;
|
|
437
437
|
if (isJsonOutput()) {
|
|
438
438
|
printJson({ executions, total, pagination });
|
|
439
439
|
return;
|
|
@@ -40,30 +40,30 @@ What are Toolsets?
|
|
|
40
40
|
- Enable/disable entire groups of tools at once
|
|
41
41
|
|
|
42
42
|
Examples:
|
|
43
|
-
$
|
|
44
|
-
$
|
|
45
|
-
$
|
|
43
|
+
$ protobox toolsets list # List all toolsets
|
|
44
|
+
$ protobox toolsets create -f toolset.json # Create new toolset
|
|
45
|
+
$ protobox toolsets add-tools <id> -t id1,id2 # Add tools to toolset`
|
|
46
46
|
);
|
|
47
47
|
toolsets.command("list").description("List all toolsets in the workspace").option("-e, --enabled", "Show only enabled toolsets").option("-d, --disabled", "Show only disabled toolsets").option("--tag <tag>", "Filter by tag").option("-s, --search <search>", "Search by name or description").option("-l, --limit <number>", "Items per page (default: 20)", "20").option("-p, --page <number>", "Page number (default: 1)", "1").addHelpText(
|
|
48
48
|
"after",
|
|
49
49
|
`
|
|
50
50
|
Examples:
|
|
51
|
-
$
|
|
52
|
-
$
|
|
53
|
-
$
|
|
51
|
+
$ protobox toolsets list # List all
|
|
52
|
+
$ protobox toolsets list --enabled # Only enabled
|
|
53
|
+
$ protobox toolsets list --search "api" # Search by name`
|
|
54
54
|
).action(handleToolsetsList);
|
|
55
55
|
toolsets.command("get <id>").description("Get detailed info about a toolset").addHelpText(
|
|
56
56
|
"after",
|
|
57
57
|
`
|
|
58
58
|
Example:
|
|
59
|
-
$
|
|
59
|
+
$ protobox toolsets get 507f1f77bcf86cd799439011`
|
|
60
60
|
).action(handleToolsetsGet);
|
|
61
61
|
toolsets.command("create").description("Create a new toolset from JSON file").option("-f, --file <path>", "Path to JSON file with toolset definition").option("--template", "Output a sample JSON template").addHelpText(
|
|
62
62
|
"after",
|
|
63
63
|
`
|
|
64
64
|
Examples:
|
|
65
|
-
$
|
|
66
|
-
$
|
|
65
|
+
$ protobox toolsets create --template > my-toolset.json # Generate template
|
|
66
|
+
$ protobox toolsets create -f my-toolset.json # Create from file
|
|
67
67
|
|
|
68
68
|
Required JSON fields:
|
|
69
69
|
name Toolset name
|
|
@@ -79,14 +79,14 @@ Optional fields:
|
|
|
79
79
|
"after",
|
|
80
80
|
`
|
|
81
81
|
Example:
|
|
82
|
-
$
|
|
82
|
+
$ protobox toolsets update 507f1f77bcf86cd799439011 -f updates.json`
|
|
83
83
|
).action(handleToolsetsUpdate);
|
|
84
84
|
toolsets.command("delete <id>").description("Delete a toolset permanently").option("-y, --yes", "Skip confirmation prompt").addHelpText(
|
|
85
85
|
"after",
|
|
86
86
|
`
|
|
87
87
|
Examples:
|
|
88
|
-
$
|
|
89
|
-
$
|
|
88
|
+
$ protobox toolsets delete 507f1f77bcf86cd799439011 # With confirmation
|
|
89
|
+
$ protobox toolsets delete 507f1f77bcf86cd799439011 -y # Skip confirmation`
|
|
90
90
|
).action(handleToolsetsDelete);
|
|
91
91
|
toolsets.command("enable <id>").description("Enable a toolset (makes its tools available)").action(handleToolsetsEnable);
|
|
92
92
|
toolsets.command("disable <id>").description("Disable a toolset (hides its tools)").action(handleToolsetsDisable);
|
|
@@ -94,13 +94,13 @@ Examples:
|
|
|
94
94
|
"after",
|
|
95
95
|
`
|
|
96
96
|
Example:
|
|
97
|
-
$
|
|
97
|
+
$ protobox toolsets add-tools 507f1f77bcf86cd799439011 -t tool1,tool2,tool3`
|
|
98
98
|
).action(handleToolsetsAddTools);
|
|
99
99
|
toolsets.command("remove-tools <id>").description("Remove tools from a toolset").requiredOption("-t, --tools <ids>", "Comma-separated tool IDs").addHelpText(
|
|
100
100
|
"after",
|
|
101
101
|
`
|
|
102
102
|
Example:
|
|
103
|
-
$
|
|
103
|
+
$ protobox toolsets remove-tools 507f1f77bcf86cd799439011 -t tool1,tool2`
|
|
104
104
|
).action(handleToolsetsRemoveTools);
|
|
105
105
|
return toolsets;
|
|
106
106
|
}
|
|
@@ -125,15 +125,9 @@ async function handleToolsetsList(options) {
|
|
|
125
125
|
process.exitCode = 1;
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
|
-
const toolsets = response.data.items
|
|
129
|
-
const total = response.data.total
|
|
130
|
-
const pagination = response.data.pagination
|
|
131
|
-
page: parseInt(options.page, 10),
|
|
132
|
-
limit: parseInt(options.limit, 10),
|
|
133
|
-
totalPages: Math.ceil(total / parseInt(options.limit, 10)),
|
|
134
|
-
hasNext: false,
|
|
135
|
-
hasPrev: false
|
|
136
|
-
};
|
|
128
|
+
const toolsets = response.data.items;
|
|
129
|
+
const total = response.data.total;
|
|
130
|
+
const pagination = response.data.pagination;
|
|
137
131
|
if (isJsonOutput()) {
|
|
138
132
|
printJson({ toolsets, total, pagination });
|
|
139
133
|
return;
|
|
@@ -195,7 +189,7 @@ async function handleToolsetsCreate(options) {
|
|
|
195
189
|
}
|
|
196
190
|
if (!options.file) {
|
|
197
191
|
printError("Missing required option", "Use '-f, --file <path>' or '--template' for sample JSON");
|
|
198
|
-
printInfo("Run '
|
|
192
|
+
printInfo("Run 'protobox toolsets create --help' for usage");
|
|
199
193
|
process.exitCode = 1;
|
|
200
194
|
return;
|
|
201
195
|
}
|
|
@@ -23,29 +23,29 @@ What are Workspaces?
|
|
|
23
23
|
configurations. Switch between workspaces to manage different projects.
|
|
24
24
|
|
|
25
25
|
Quick Start:
|
|
26
|
-
$
|
|
27
|
-
$
|
|
28
|
-
$
|
|
26
|
+
$ protobox workspaces list # List your workspaces
|
|
27
|
+
$ protobox workspaces get <id> # View workspace details
|
|
28
|
+
$ protobox workspaces use <id> # Set active workspace`
|
|
29
29
|
);
|
|
30
30
|
workspaces.command("list").description("List workspaces").addHelpText(
|
|
31
31
|
"after",
|
|
32
32
|
`
|
|
33
33
|
Examples:
|
|
34
|
-
$
|
|
35
|
-
$
|
|
34
|
+
$ protobox workspaces list # List all workspaces
|
|
35
|
+
$ protobox workspaces list --json # Output as JSON`
|
|
36
36
|
).action(handleWorkspacesList);
|
|
37
37
|
workspaces.command("get <id>").description("Get workspace details").addHelpText(
|
|
38
38
|
"after",
|
|
39
39
|
`
|
|
40
40
|
Examples:
|
|
41
|
-
$
|
|
42
|
-
$
|
|
41
|
+
$ protobox workspaces get ws_abc123 # Get workspace details
|
|
42
|
+
$ protobox workspaces get ws_abc123 --json # Output as JSON`
|
|
43
43
|
).action(handleWorkspacesGet);
|
|
44
44
|
workspaces.command("use <id>").description("Set active workspace (saves to config)").addHelpText(
|
|
45
45
|
"after",
|
|
46
46
|
`
|
|
47
47
|
Examples:
|
|
48
|
-
$
|
|
48
|
+
$ protobox workspaces use ws_abc123 # Switch to workspace
|
|
49
49
|
|
|
50
50
|
This saves the workspace ID to your CLI config. All subsequent commands
|
|
51
51
|
will use this workspace by default.`
|
|
@@ -87,7 +87,7 @@ class ConfigStore {
|
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
89
|
* Get API key with environment variable fallback
|
|
90
|
-
* Priority: CHANL_API_KEY
|
|
90
|
+
* Priority: PROTOBOX_API_KEY (CHANL_API_KEY fallback) > config file
|
|
91
91
|
*/
|
|
92
92
|
getApiKey() {
|
|
93
93
|
return process.env["PROTOBOX_API_KEY"] || process.env["CHANL_API_KEY"] || this.get("apiKey");
|
|
@@ -106,13 +106,13 @@ class ConfigStore {
|
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* Get base URL with environment variable fallback
|
|
109
|
-
* Priority: CHANL_BASE_URL
|
|
109
|
+
* Priority: PROTOBOX_BASE_URL (CHANL_BASE_URL fallback) > config file > default
|
|
110
110
|
*/
|
|
111
111
|
getBaseUrl() {
|
|
112
112
|
return process.env["PROTOBOX_BASE_URL"] || process.env["CHANL_BASE_URL"] || this.get("server") || this.get("baseUrl");
|
|
113
113
|
}
|
|
114
114
|
getDeployment() {
|
|
115
|
-
const d = process.env["CHANL_DEPLOYMENT"] || this.get("deployment");
|
|
115
|
+
const d = process.env["PROTOBOX_DEPLOYMENT"] || process.env["CHANL_DEPLOYMENT"] || this.get("deployment");
|
|
116
116
|
if (d === "local" || d === "cloud") return d;
|
|
117
117
|
const base = this.getBaseUrl();
|
|
118
118
|
if (base.includes("localhost:18005") || base.includes("127.0.0.1:18005")) {
|
|
@@ -121,13 +121,13 @@ class ConfigStore {
|
|
|
121
121
|
return void 0;
|
|
122
122
|
}
|
|
123
123
|
getApiPrefix() {
|
|
124
|
-
const fromEnv = process.env["CHANL_API_PREFIX"];
|
|
124
|
+
const fromEnv = process.env["PROTOBOX_API_PREFIX"] ?? process.env["CHANL_API_PREFIX"];
|
|
125
125
|
if (fromEnv !== void 0) return fromEnv;
|
|
126
126
|
return this.get("apiPrefix");
|
|
127
127
|
}
|
|
128
128
|
/**
|
|
129
129
|
* Get the app URL for browser-based flows (e.g., CLI auth)
|
|
130
|
-
* Priority: CHANL_APP_URL
|
|
130
|
+
* Priority: PROTOBOX_APP_URL (CHANL_APP_URL fallback) > config file > derived from baseUrl
|
|
131
131
|
*/
|
|
132
132
|
getAppUrl() {
|
|
133
133
|
if (process.env["PROTOBOX_APP_URL"]) return process.env["PROTOBOX_APP_URL"];
|
|
@@ -140,7 +140,7 @@ class ConfigStore {
|
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
142
142
|
* Get workspace ID with environment variable fallback
|
|
143
|
-
* Priority: CHANL_WORKSPACE_ID
|
|
143
|
+
* Priority: PROTOBOX_WORKSPACE_ID (CHANL_WORKSPACE_ID fallback) > config file
|
|
144
144
|
*/
|
|
145
145
|
getWorkspaceId() {
|
|
146
146
|
return process.env["PROTOBOX_WORKSPACE_ID"] || process.env["CHANL_WORKSPACE_ID"] || this.get("workspaceId");
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ProtoboxSDK } from "@protoboxai/sdk";
|
|
2
2
|
import { configStore } from "./config-store.js";
|
|
3
3
|
import { printError } from "./output.js";
|
|
4
4
|
function createSdk() {
|
|
@@ -6,7 +6,7 @@ function createSdk() {
|
|
|
6
6
|
const jwtToken = configStore.getJwtToken();
|
|
7
7
|
const baseUrl = configStore.getBaseUrl();
|
|
8
8
|
if (!apiKey && !jwtToken) {
|
|
9
|
-
printError("Not authenticated", "Run '
|
|
9
|
+
printError("Not authenticated", "Run 'protobox login' to authenticate");
|
|
10
10
|
process.exitCode = 1;
|
|
11
11
|
return null;
|
|
12
12
|
}
|
|
@@ -14,16 +14,16 @@ function createSdk() {
|
|
|
14
14
|
const apiPrefix = configStore.getApiPrefix();
|
|
15
15
|
if (apiKey) {
|
|
16
16
|
if (apiKey.startsWith("eyJ")) {
|
|
17
|
-
return new
|
|
17
|
+
return new ProtoboxSDK({
|
|
18
18
|
jwtToken: apiKey,
|
|
19
19
|
baseUrl,
|
|
20
20
|
deployment,
|
|
21
21
|
apiPrefix
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
|
-
return new
|
|
24
|
+
return new ProtoboxSDK({ apiKey, baseUrl, deployment, apiPrefix });
|
|
25
25
|
}
|
|
26
|
-
return new
|
|
26
|
+
return new ProtoboxSDK({
|
|
27
27
|
jwtToken,
|
|
28
28
|
baseUrl,
|
|
29
29
|
deployment,
|
|
@@ -33,7 +33,7 @@ function createSdk() {
|
|
|
33
33
|
function getWorkspaceId() {
|
|
34
34
|
const workspaceId = configStore.getWorkspaceId();
|
|
35
35
|
if (!workspaceId) {
|
|
36
|
-
printError("No workspace selected", "Run '
|
|
36
|
+
printError("No workspace selected", "Run 'protobox config set workspaceId <id>' to select a workspace");
|
|
37
37
|
process.exitCode = 1;
|
|
38
38
|
return null;
|
|
39
39
|
}
|
package/package.json
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@protoboxai/cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Command-line interface for Protobox — MCP, tools, knowledge, agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"protobox": "./bin/protobox.js"
|
|
9
9
|
},
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsup",
|
|
12
|
-
"dev": "tsup --watch",
|
|
13
|
-
"clean": "rimraf dist",
|
|
14
|
-
"prebuild": "npm run clean",
|
|
15
|
-
"test": "vitest run",
|
|
16
|
-
"test:watch": "vitest",
|
|
17
|
-
"lint": "eslint src/**/*.ts",
|
|
18
|
-
"format": "prettier --write src/**/*.ts",
|
|
19
|
-
"typecheck": "tsc --noEmit"
|
|
20
|
-
},
|
|
21
10
|
"keywords": [
|
|
22
11
|
"protobox",
|
|
23
12
|
"cli",
|
|
@@ -29,7 +18,6 @@
|
|
|
29
18
|
"author": "Protobox",
|
|
30
19
|
"license": "MIT",
|
|
31
20
|
"dependencies": {
|
|
32
|
-
"@protoboxai/sdk": "workspace:*",
|
|
33
21
|
"@inquirer/prompts": "^7.10.1",
|
|
34
22
|
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
35
23
|
"chalk": "^5.3.0",
|
|
@@ -37,7 +25,8 @@
|
|
|
37
25
|
"conf": "^13.0.1",
|
|
38
26
|
"inquirer": "^12.2.0",
|
|
39
27
|
"open": "^11.0.0",
|
|
40
|
-
"ora": "^8.1.1"
|
|
28
|
+
"ora": "^8.1.1",
|
|
29
|
+
"@protoboxai/sdk": "^1.0.0"
|
|
41
30
|
},
|
|
42
31
|
"devDependencies": {
|
|
43
32
|
"@types/inquirer": "^9.0.7",
|
|
@@ -58,5 +47,16 @@
|
|
|
58
47
|
"publishConfig": {
|
|
59
48
|
"registry": "https://registry.npmjs.org",
|
|
60
49
|
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup",
|
|
53
|
+
"dev": "tsup --watch",
|
|
54
|
+
"clean": "rimraf dist",
|
|
55
|
+
"prebuild": "npm run clean",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:watch": "vitest",
|
|
58
|
+
"lint": "eslint src/**/*.ts",
|
|
59
|
+
"format": "prettier --write src/**/*.ts",
|
|
60
|
+
"typecheck": "tsc --noEmit"
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
}
|