@adcp/client 2.4.1 ā 2.5.0
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 +66 -11
- package/bin/adcp-config.js +230 -0
- package/bin/adcp.js +267 -42
- package/dist/lib/core/ADCPClient.d.ts.map +1 -1
- package/dist/lib/core/ADCPClient.js +20 -0
- package/dist/lib/core/ADCPClient.js.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.d.ts +8 -0
- package/dist/lib/core/ADCPMultiAgentClient.d.ts.map +1 -1
- package/dist/lib/core/ADCPMultiAgentClient.js +14 -0
- package/dist/lib/core/ADCPMultiAgentClient.js.map +1 -1
- package/dist/lib/core/AgentClient.d.ts +18 -2
- package/dist/lib/core/AgentClient.d.ts.map +1 -1
- package/dist/lib/core/AgentClient.js +10 -3
- package/dist/lib/core/AgentClient.js.map +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +4 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/types/schemas.generated.js +1 -1
- package/dist/lib/utils/protocol-detection.d.ts +26 -0
- package/dist/lib/utils/protocol-detection.d.ts.map +1 -0
- package/dist/lib/utils/protocol-detection.js +84 -0
- package/dist/lib/utils/protocol-detection.js.map +1 -0
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -457,26 +457,81 @@ ORDER BY sequence_number;
|
|
|
457
457
|
|
|
458
458
|
## CLI Tool
|
|
459
459
|
|
|
460
|
-
For development and testing, use the included CLI tool to interact with AdCP agents
|
|
460
|
+
For development and testing, use the included CLI tool to interact with AdCP agents.
|
|
461
|
+
|
|
462
|
+
### Quick Start with Aliases
|
|
463
|
+
|
|
464
|
+
Save agents for quick access:
|
|
461
465
|
|
|
462
466
|
```bash
|
|
463
|
-
#
|
|
464
|
-
npx @adcp/client
|
|
467
|
+
# Save an agent with an alias
|
|
468
|
+
npx @adcp/client --save-auth test https://test-agent.adcontextprotocol.org
|
|
465
469
|
|
|
466
|
-
#
|
|
467
|
-
npx @adcp/client
|
|
470
|
+
# Use the alias
|
|
471
|
+
npx @adcp/client test get_products '{"brief":"Coffee brands"}'
|
|
468
472
|
|
|
469
|
-
#
|
|
470
|
-
npx @adcp/client
|
|
473
|
+
# List saved agents
|
|
474
|
+
npx @adcp/client --list-agents
|
|
475
|
+
```
|
|
476
|
+
|
|
477
|
+
### Direct URL Usage
|
|
478
|
+
|
|
479
|
+
Auto-detect protocol and call directly:
|
|
480
|
+
|
|
481
|
+
```bash
|
|
482
|
+
# Protocol auto-detection (default)
|
|
483
|
+
npx @adcp/client https://test-agent.adcontextprotocol.org get_products '{"brief":"Coffee"}'
|
|
484
|
+
|
|
485
|
+
# Force specific protocol with --protocol flag
|
|
486
|
+
npx @adcp/client https://agent.example.com get_products '{"brief":"Coffee"}' --protocol mcp
|
|
487
|
+
npx @adcp/client https://agent.example.com list_authorized_properties --protocol a2a
|
|
471
488
|
|
|
472
|
-
#
|
|
473
|
-
npx @adcp/client
|
|
489
|
+
# List available tools
|
|
490
|
+
npx @adcp/client https://agent.example.com
|
|
491
|
+
|
|
492
|
+
# Use a file for payload
|
|
493
|
+
npx @adcp/client https://agent.example.com create_media_buy @payload.json
|
|
474
494
|
|
|
475
495
|
# JSON output for scripting
|
|
476
|
-
npx @adcp/client
|
|
496
|
+
npx @adcp/client https://agent.example.com get_products '{"brief":"..."}' --json | jq '.products'
|
|
477
497
|
```
|
|
478
498
|
|
|
479
|
-
|
|
499
|
+
### Authentication
|
|
500
|
+
|
|
501
|
+
Three ways to provide auth tokens (priority order):
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
# 1. Explicit flag (highest priority)
|
|
505
|
+
npx @adcp/client test get_products '{"brief":"..."}' --auth your-token
|
|
506
|
+
|
|
507
|
+
# 2. Saved in agent config (recommended)
|
|
508
|
+
npx @adcp/client --save-auth prod https://prod-agent.com
|
|
509
|
+
# Will prompt for auth token securely
|
|
510
|
+
|
|
511
|
+
# 3. Environment variable (fallback)
|
|
512
|
+
export ADCP_AUTH_TOKEN=your-token
|
|
513
|
+
npx @adcp/client test get_products '{"brief":"..."}'
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Agent Management
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
# Save agent with auth
|
|
520
|
+
npx @adcp/client --save-auth prod https://prod-agent.com mcp
|
|
521
|
+
|
|
522
|
+
# List all saved agents
|
|
523
|
+
npx @adcp/client --list-agents
|
|
524
|
+
|
|
525
|
+
# Remove an agent
|
|
526
|
+
npx @adcp/client --remove-agent test
|
|
527
|
+
|
|
528
|
+
# Show config file location
|
|
529
|
+
npx @adcp/client --show-config
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Protocol Auto-Detection**: The CLI automatically detects whether an endpoint uses MCP or A2A by checking URL patterns and discovery endpoints. Override with `--protocol mcp` or `--protocol a2a` if needed.
|
|
533
|
+
|
|
534
|
+
**Config File**: Agent configurations are saved to `~/.adcp/config.json` with secure file permissions (0600).
|
|
480
535
|
|
|
481
536
|
See [docs/CLI.md](docs/CLI.md) for complete CLI documentation including webhook support for async operations.
|
|
482
537
|
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AdCP CLI Configuration Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages agent aliases and authentication configuration
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const path = require('path');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
|
|
11
|
+
const CONFIG_DIR = path.join(os.homedir(), '.adcp');
|
|
12
|
+
const CONFIG_FILE = path.join(CONFIG_DIR, 'config.json');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Get the config file path
|
|
16
|
+
*/
|
|
17
|
+
function getConfigPath() {
|
|
18
|
+
return CONFIG_FILE;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Ensure config directory exists
|
|
23
|
+
*/
|
|
24
|
+
function ensureConfigDir() {
|
|
25
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
26
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Load configuration from disk
|
|
32
|
+
* @returns {Object} Configuration object
|
|
33
|
+
*/
|
|
34
|
+
function loadConfig() {
|
|
35
|
+
try {
|
|
36
|
+
if (!fs.existsSync(CONFIG_FILE)) {
|
|
37
|
+
return { agents: {}, defaults: {} };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf-8');
|
|
41
|
+
return JSON.parse(content);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.error(`Warning: Failed to load config from ${CONFIG_FILE}: ${error.message}`);
|
|
44
|
+
return { agents: {}, defaults: {} };
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Save configuration to disk
|
|
50
|
+
* @param {Object} config Configuration object
|
|
51
|
+
*/
|
|
52
|
+
function saveConfig(config) {
|
|
53
|
+
try {
|
|
54
|
+
ensureConfigDir();
|
|
55
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), { mode: 0o600 });
|
|
56
|
+
} catch (error) {
|
|
57
|
+
throw new Error(`Failed to save config to ${CONFIG_FILE}: ${error.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get agent configuration by alias
|
|
63
|
+
* @param {string} alias Agent alias
|
|
64
|
+
* @returns {Object|null} Agent config or null if not found
|
|
65
|
+
*/
|
|
66
|
+
function getAgent(alias) {
|
|
67
|
+
const config = loadConfig();
|
|
68
|
+
return config.agents[alias] || null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* List all saved agents
|
|
73
|
+
* @returns {Object} Map of alias to agent config
|
|
74
|
+
*/
|
|
75
|
+
function listAgents() {
|
|
76
|
+
const config = loadConfig();
|
|
77
|
+
return config.agents || {};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Save an agent configuration
|
|
82
|
+
* @param {string} alias Agent alias
|
|
83
|
+
* @param {Object} agentConfig Agent configuration
|
|
84
|
+
*/
|
|
85
|
+
function saveAgent(alias, agentConfig) {
|
|
86
|
+
const config = loadConfig();
|
|
87
|
+
if (!config.agents) {
|
|
88
|
+
config.agents = {};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
config.agents[alias] = agentConfig;
|
|
92
|
+
saveConfig(config);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Remove an agent configuration
|
|
97
|
+
* @param {string} alias Agent alias
|
|
98
|
+
* @returns {boolean} True if agent was removed
|
|
99
|
+
*/
|
|
100
|
+
function removeAgent(alias) {
|
|
101
|
+
const config = loadConfig();
|
|
102
|
+
if (config.agents && config.agents[alias]) {
|
|
103
|
+
delete config.agents[alias];
|
|
104
|
+
saveConfig(config);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Check if a string is an agent alias
|
|
112
|
+
* @param {string} str String to check
|
|
113
|
+
* @returns {boolean} True if string is a saved alias
|
|
114
|
+
*/
|
|
115
|
+
function isAlias(str) {
|
|
116
|
+
const config = loadConfig();
|
|
117
|
+
return config.agents && config.agents[str] !== undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Prompt for input securely (for passwords/tokens)
|
|
122
|
+
* @param {string} prompt Prompt message
|
|
123
|
+
* @param {boolean} hidden Hide input (for passwords)
|
|
124
|
+
* @returns {Promise<string>} User input
|
|
125
|
+
*/
|
|
126
|
+
async function promptSecure(prompt, hidden = true) {
|
|
127
|
+
const readline = require('readline');
|
|
128
|
+
|
|
129
|
+
return new Promise((resolve) => {
|
|
130
|
+
const rl = readline.createInterface({
|
|
131
|
+
input: process.stdin,
|
|
132
|
+
output: process.stdout
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
if (hidden) {
|
|
136
|
+
// Disable echo for password input
|
|
137
|
+
const stdin = process.stdin;
|
|
138
|
+
const originalSetRawMode = stdin.setRawMode;
|
|
139
|
+
|
|
140
|
+
// Mute output
|
|
141
|
+
rl.stdoutMuted = true;
|
|
142
|
+
rl._writeToOutput = function _writeToOutput(stringToWrite) {
|
|
143
|
+
if (!rl.stdoutMuted) {
|
|
144
|
+
rl.output.write(stringToWrite);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
rl.question(prompt, (answer) => {
|
|
150
|
+
rl.close();
|
|
151
|
+
if (hidden) {
|
|
152
|
+
console.log(''); // New line after hidden input
|
|
153
|
+
}
|
|
154
|
+
resolve(answer.trim());
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Interactive agent setup
|
|
161
|
+
* @param {string} alias Agent alias
|
|
162
|
+
* @param {string} url Agent URL (optional)
|
|
163
|
+
* @param {string} protocol Protocol (optional)
|
|
164
|
+
* @param {string} authToken Auth token (optional)
|
|
165
|
+
* @param {boolean} nonInteractive Skip prompts if all required args provided
|
|
166
|
+
*/
|
|
167
|
+
async function interactiveSetup(alias, url = null, protocol = null, authToken = null, nonInteractive = false) {
|
|
168
|
+
// Non-interactive mode: if URL is provided, just save it
|
|
169
|
+
if (nonInteractive && url) {
|
|
170
|
+
const agentConfig = { url };
|
|
171
|
+
if (protocol) agentConfig.protocol = protocol;
|
|
172
|
+
if (authToken) agentConfig.auth_token = authToken;
|
|
173
|
+
|
|
174
|
+
saveAgent(alias, agentConfig);
|
|
175
|
+
console.log(`\nā
Agent '${alias}' saved to ${CONFIG_FILE}`);
|
|
176
|
+
console.log(`\nYou can now use: adcp ${alias} <tool> <payload>`);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
console.log(`\nš Setting up agent: ${alias}\n`);
|
|
181
|
+
|
|
182
|
+
// Get URL if not provided
|
|
183
|
+
if (!url) {
|
|
184
|
+
url = await promptSecure('Agent URL: ', false);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Get protocol if not provided (optional, can auto-detect)
|
|
188
|
+
if (!protocol) {
|
|
189
|
+
const protocolInput = await promptSecure('Protocol (mcp/a2a, or leave blank to auto-detect): ', false);
|
|
190
|
+
protocol = protocolInput || null;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Get auth token if not provided
|
|
194
|
+
if (!authToken) {
|
|
195
|
+
authToken = await promptSecure('Auth token (leave blank if not needed): ', true);
|
|
196
|
+
authToken = authToken || null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Build config
|
|
200
|
+
const agentConfig = {
|
|
201
|
+
url: url
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
if (protocol) {
|
|
205
|
+
agentConfig.protocol = protocol;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
if (authToken) {
|
|
209
|
+
agentConfig.auth_token = authToken;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Save
|
|
213
|
+
saveAgent(alias, agentConfig);
|
|
214
|
+
|
|
215
|
+
console.log(`\nā
Agent '${alias}' saved to ${CONFIG_FILE}`);
|
|
216
|
+
console.log(`\nYou can now use: adcp ${alias} <tool> <payload>`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
module.exports = {
|
|
220
|
+
getConfigPath,
|
|
221
|
+
loadConfig,
|
|
222
|
+
saveConfig,
|
|
223
|
+
getAgent,
|
|
224
|
+
listAgents,
|
|
225
|
+
saveAgent,
|
|
226
|
+
removeAgent,
|
|
227
|
+
isAlias,
|
|
228
|
+
promptSecure,
|
|
229
|
+
interactiveSetup
|
|
230
|
+
};
|