@guildai/cli 0.5.8 → 0.5.10
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 +28 -1
- package/dist/commands/setup.js +11 -4
- package/dist/mcp/tools.d.ts +1 -1
- package/dist/mcp/tools.js +56 -36
- package/docs/CLI_WORKFLOW.md +6 -0
- package/docs/DESIGN.md +2 -0
- package/docs/skills/agent-dev.md +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -210,8 +210,35 @@ guild version # Show version info
|
|
|
210
210
|
### Coding Assistant Skills
|
|
211
211
|
|
|
212
212
|
```bash
|
|
213
|
-
guild setup # Install
|
|
213
|
+
guild setup # Install skills + configure MCP server
|
|
214
214
|
guild setup --claude-md # Also create a CLAUDE.md template
|
|
215
|
+
guild setup --no-mcp # Install skills only, skip MCP configuration
|
|
216
|
+
guild mcp # Start MCP server (used by Claude Code, etc.)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### MCP Server
|
|
220
|
+
|
|
221
|
+
The CLI includes an [MCP](https://modelcontextprotocol.io/) server that exposes Guild's API to AI coding assistants like Claude Code.
|
|
222
|
+
|
|
223
|
+
**Setup:**
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
guild setup
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
This installs Claude Code skills and adds a `guild` entry to `.mcp.json` in your project. Claude Code (and other MCP-compatible tools) will automatically connect when they detect it.
|
|
230
|
+
|
|
231
|
+
**What it provides:**
|
|
232
|
+
|
|
233
|
+
- 24 tools: workspaces, agents, sessions, triggers, contexts, credentials
|
|
234
|
+
- 2 resources: current workspace info and installed agents
|
|
235
|
+
- All tools use your `guild auth` credentials automatically
|
|
236
|
+
|
|
237
|
+
**Manual start (for debugging):**
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
guild mcp
|
|
241
|
+
guild mcp --debug # Verbose logging to stderr
|
|
215
242
|
```
|
|
216
243
|
|
|
217
244
|
## Configuration
|
package/dist/commands/setup.js
CHANGED
|
@@ -60,8 +60,8 @@ async function setupMcp(options) {
|
|
|
60
60
|
const content = await fs.readFile(mcpPath, 'utf-8');
|
|
61
61
|
existing = JSON.parse(content);
|
|
62
62
|
if (existing.mcpServers && 'guild' in existing.mcpServers && !options.force) {
|
|
63
|
-
output.progress('Guild
|
|
64
|
-
return;
|
|
63
|
+
output.progress('.mcp.json already has Guild server (use --force to overwrite)');
|
|
64
|
+
return 'skipped';
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
const updated = {
|
|
@@ -78,6 +78,7 @@ async function setupMcp(options) {
|
|
|
78
78
|
else {
|
|
79
79
|
output.success('Created .mcp.json with Guild MCP server');
|
|
80
80
|
}
|
|
81
|
+
return 'created';
|
|
81
82
|
}
|
|
82
83
|
async function setup(options) {
|
|
83
84
|
const output = createOutputWriter();
|
|
@@ -116,7 +117,13 @@ async function setup(options) {
|
|
|
116
117
|
}
|
|
117
118
|
// Handle --mcp flag
|
|
118
119
|
if (options.mcp) {
|
|
119
|
-
await setupMcp({ force: options.force });
|
|
120
|
+
const result = await setupMcp({ force: options.force });
|
|
121
|
+
if (result === 'created') {
|
|
122
|
+
filesCreated++;
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
filesSkipped++;
|
|
126
|
+
}
|
|
120
127
|
}
|
|
121
128
|
// Handle CLAUDE.md template
|
|
122
129
|
if (options.claudeMd) {
|
|
@@ -155,7 +162,7 @@ export function createSetupCommand() {
|
|
|
155
162
|
.description('Set up Guild CLI skills for coding assistants (Claude Code, etc.)')
|
|
156
163
|
.option('--force', 'Overwrite existing skill files', false)
|
|
157
164
|
.option('--claude-md', 'Also create a CLAUDE.md template in the project root', false)
|
|
158
|
-
.option('--mcp', '
|
|
165
|
+
.option('--no-mcp', 'Skip MCP server configuration')
|
|
159
166
|
.action(async (options) => {
|
|
160
167
|
await setup(options);
|
|
161
168
|
});
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import type { GuildAPIClient } from '../lib/api-client.js';
|
|
3
|
-
export declare function registerTools(server: McpServer, apiClient: GuildAPIClient,
|
|
3
|
+
export declare function registerTools(server: McpServer, apiClient: GuildAPIClient, defaultWorkspaceId: string, debug: boolean): void;
|
|
4
4
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/mcp/tools.js
CHANGED
|
@@ -84,9 +84,16 @@ function errText(action, error) {
|
|
|
84
84
|
return `Failed to ${action}: ${error instanceof Error ? error.message : String(error)}`;
|
|
85
85
|
}
|
|
86
86
|
// ---------------------------------------------------------------------------
|
|
87
|
+
// Shared schema fragments
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
const workspaceIdParam = z
|
|
90
|
+
.string()
|
|
91
|
+
.optional()
|
|
92
|
+
.describe('Workspace ID (defaults to current workspace)');
|
|
93
|
+
// ---------------------------------------------------------------------------
|
|
87
94
|
// Tool registration
|
|
88
95
|
// ---------------------------------------------------------------------------
|
|
89
|
-
export function registerTools(server, apiClient,
|
|
96
|
+
export function registerTools(server, apiClient, defaultWorkspaceId, debug) {
|
|
90
97
|
// =========================================================================
|
|
91
98
|
// User
|
|
92
99
|
// =========================================================================
|
|
@@ -139,12 +146,9 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
139
146
|
}
|
|
140
147
|
});
|
|
141
148
|
server.tool('guild_get_workspace', 'Get workspace details including context', {
|
|
142
|
-
workspace_id:
|
|
143
|
-
.string()
|
|
144
|
-
.optional()
|
|
145
|
-
.describe('Workspace ID (defaults to current workspace)'),
|
|
149
|
+
workspace_id: workspaceIdParam,
|
|
146
150
|
}, async ({ workspace_id }) => {
|
|
147
|
-
const wsId = workspace_id ||
|
|
151
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
148
152
|
debugLog(debug, `guild_get_workspace: ${wsId}`);
|
|
149
153
|
try {
|
|
150
154
|
const ws = await apiClient.get(`/workspaces/${wsId}`);
|
|
@@ -163,12 +167,14 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
163
167
|
};
|
|
164
168
|
}
|
|
165
169
|
});
|
|
166
|
-
server.tool('guild_list_workspace_agents', 'List agents installed in
|
|
170
|
+
server.tool('guild_list_workspace_agents', 'List agents installed in a workspace', {
|
|
171
|
+
workspace_id: workspaceIdParam,
|
|
167
172
|
search: z.string().optional().describe('Filter agents by name'),
|
|
168
|
-
}, async ({ search }) => {
|
|
169
|
-
|
|
173
|
+
}, async ({ workspace_id, search }) => {
|
|
174
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
175
|
+
debugLog(debug, `guild_list_workspace_agents: ws=${wsId} search=${search || ''}`);
|
|
170
176
|
try {
|
|
171
|
-
let endpoint = `/workspaces/${
|
|
177
|
+
let endpoint = `/workspaces/${wsId}/workspace_agents`;
|
|
172
178
|
if (search)
|
|
173
179
|
endpoint += `?search=${encodeURIComponent(search)}`;
|
|
174
180
|
const agents = await apiClient.fetchAll(endpoint);
|
|
@@ -194,12 +200,14 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
194
200
|
};
|
|
195
201
|
}
|
|
196
202
|
});
|
|
197
|
-
server.tool('guild_add_workspace_agent', 'Install an agent in
|
|
203
|
+
server.tool('guild_add_workspace_agent', 'Install an agent in a workspace', {
|
|
198
204
|
agent_id: z.string().describe('The agent ID to install'),
|
|
199
|
-
|
|
200
|
-
|
|
205
|
+
workspace_id: workspaceIdParam,
|
|
206
|
+
}, async ({ agent_id, workspace_id }) => {
|
|
207
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
208
|
+
debugLog(debug, `guild_add_workspace_agent: ${agent_id} ws=${wsId}`);
|
|
201
209
|
try {
|
|
202
|
-
const wa = await apiClient.post(`/workspaces/${
|
|
210
|
+
const wa = await apiClient.post(`/workspaces/${wsId}/workspace_agents`, { agent_id });
|
|
203
211
|
return {
|
|
204
212
|
content: [
|
|
205
213
|
{
|
|
@@ -245,7 +253,8 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
245
253
|
// =========================================================================
|
|
246
254
|
// Contexts
|
|
247
255
|
// =========================================================================
|
|
248
|
-
server.tool('guild_list_contexts', 'List context versions for
|
|
256
|
+
server.tool('guild_list_contexts', 'List context versions for a workspace', {
|
|
257
|
+
workspace_id: workspaceIdParam,
|
|
249
258
|
limit: z
|
|
250
259
|
.number()
|
|
251
260
|
.int()
|
|
@@ -253,10 +262,11 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
253
262
|
.max(100)
|
|
254
263
|
.optional()
|
|
255
264
|
.describe('Max results (default 20)'),
|
|
256
|
-
}, async ({ limit }) => {
|
|
257
|
-
|
|
265
|
+
}, async ({ workspace_id, limit }) => {
|
|
266
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
267
|
+
debugLog(debug, `guild_list_contexts: ws=${wsId}`);
|
|
258
268
|
try {
|
|
259
|
-
const response = await apiClient.get(`/workspaces/${
|
|
269
|
+
const response = await apiClient.get(`/workspaces/${wsId}/contexts?limit=${limit || 20}`);
|
|
260
270
|
const text = response.items
|
|
261
271
|
.map((c) => {
|
|
262
272
|
const summary = c.summary ? ` — ${c.summary}` : '';
|
|
@@ -302,22 +312,24 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
302
312
|
};
|
|
303
313
|
}
|
|
304
314
|
});
|
|
305
|
-
server.tool('guild_publish_context', 'Create or publish a new context version for
|
|
315
|
+
server.tool('guild_publish_context', 'Create or publish a new context version for a workspace', {
|
|
306
316
|
content: z.string().describe('The context content to publish'),
|
|
317
|
+
workspace_id: workspaceIdParam,
|
|
307
318
|
status: z
|
|
308
319
|
.enum(['ACTIVE', 'ARCHIVED'])
|
|
309
320
|
.optional()
|
|
310
321
|
.describe('Context status (default ACTIVE)'),
|
|
311
322
|
summary: z.string().optional().describe('Short summary of the context'),
|
|
312
|
-
}, async ({ content, status, summary }) => {
|
|
313
|
-
|
|
323
|
+
}, async ({ content, workspace_id, status, summary }) => {
|
|
324
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
325
|
+
debugLog(debug, `guild_publish_context: ws=${wsId}`);
|
|
314
326
|
try {
|
|
315
327
|
const body = { manual_context: content };
|
|
316
328
|
if (status)
|
|
317
329
|
body.status = status;
|
|
318
330
|
if (summary)
|
|
319
331
|
body.summary = summary;
|
|
320
|
-
const ctx = await apiClient.post(`/workspaces/${
|
|
332
|
+
const ctx = await apiClient.post(`/workspaces/${wsId}/contexts`, body);
|
|
321
333
|
return {
|
|
322
334
|
content: [
|
|
323
335
|
{
|
|
@@ -484,8 +496,10 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
484
496
|
.string()
|
|
485
497
|
.optional()
|
|
486
498
|
.describe('Agent identifier (e.g. owner/agent-name). Uses workspace default if not specified'),
|
|
487
|
-
|
|
488
|
-
|
|
499
|
+
workspace_id: workspaceIdParam,
|
|
500
|
+
}, async ({ message, agent, workspace_id }) => {
|
|
501
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
502
|
+
debugLog(debug, `guild_chat: message="${message}", agent=${agent || 'default'}, ws=${wsId}`);
|
|
489
503
|
try {
|
|
490
504
|
const body = {
|
|
491
505
|
session_type: 'chat',
|
|
@@ -494,7 +508,7 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
494
508
|
if (agent) {
|
|
495
509
|
body.agent_id = agent;
|
|
496
510
|
}
|
|
497
|
-
const session = await apiClient.post(`/workspaces/${
|
|
511
|
+
const session = await apiClient.post(`/workspaces/${wsId}/sessions`, body);
|
|
498
512
|
debugLog(debug, `Session created: ${session.id}`);
|
|
499
513
|
const response = await pollForResponse(apiClient, session.id, debug);
|
|
500
514
|
return {
|
|
@@ -530,7 +544,8 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
530
544
|
};
|
|
531
545
|
}
|
|
532
546
|
});
|
|
533
|
-
server.tool('guild_list_sessions', 'List recent sessions in
|
|
547
|
+
server.tool('guild_list_sessions', 'List recent sessions in a Guild workspace', {
|
|
548
|
+
workspace_id: workspaceIdParam,
|
|
534
549
|
limit: z
|
|
535
550
|
.number()
|
|
536
551
|
.int()
|
|
@@ -538,11 +553,12 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
538
553
|
.max(100)
|
|
539
554
|
.optional()
|
|
540
555
|
.describe('Number of sessions to return (default 20)'),
|
|
541
|
-
}, async ({ limit }) => {
|
|
542
|
-
|
|
556
|
+
}, async ({ workspace_id, limit }) => {
|
|
557
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
558
|
+
debugLog(debug, `guild_list_sessions: ws=${wsId}`);
|
|
543
559
|
try {
|
|
544
560
|
const queryLimit = limit || 20;
|
|
545
|
-
const response = await apiClient.get(`/workspaces/${
|
|
561
|
+
const response = await apiClient.get(`/workspaces/${wsId}/sessions?limit=${queryLimit}`);
|
|
546
562
|
const text = response.items
|
|
547
563
|
.map((s) => `• ${s.id} (${s.session_type}) — ${s.created_at}`)
|
|
548
564
|
.join('\n');
|
|
@@ -659,7 +675,8 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
659
675
|
// =========================================================================
|
|
660
676
|
// Triggers
|
|
661
677
|
// =========================================================================
|
|
662
|
-
server.tool('guild_list_triggers', 'List triggers configured in
|
|
678
|
+
server.tool('guild_list_triggers', 'List triggers configured in a workspace', {
|
|
679
|
+
workspace_id: workspaceIdParam,
|
|
663
680
|
limit: z
|
|
664
681
|
.number()
|
|
665
682
|
.int()
|
|
@@ -667,10 +684,11 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
667
684
|
.max(100)
|
|
668
685
|
.optional()
|
|
669
686
|
.describe('Max results (default 20)'),
|
|
670
|
-
}, async ({ limit }) => {
|
|
671
|
-
|
|
687
|
+
}, async ({ workspace_id, limit }) => {
|
|
688
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
689
|
+
debugLog(debug, `guild_list_triggers: ws=${wsId}`);
|
|
672
690
|
try {
|
|
673
|
-
const response = await apiClient.get(`/workspaces/${
|
|
691
|
+
const response = await apiClient.get(`/workspaces/${wsId}/triggers?limit=${limit || 20}`);
|
|
674
692
|
const text = response.items
|
|
675
693
|
.map((t) => {
|
|
676
694
|
const agent = t.agent.full_name || t.agent.name;
|
|
@@ -694,6 +712,7 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
694
712
|
});
|
|
695
713
|
server.tool('guild_get_trigger_sessions', 'List sessions spawned by a specific trigger', {
|
|
696
714
|
trigger_id: z.string().describe('The trigger ID'),
|
|
715
|
+
workspace_id: workspaceIdParam,
|
|
697
716
|
limit: z
|
|
698
717
|
.number()
|
|
699
718
|
.int()
|
|
@@ -701,10 +720,11 @@ export function registerTools(server, apiClient, workspaceId, debug) {
|
|
|
701
720
|
.max(100)
|
|
702
721
|
.optional()
|
|
703
722
|
.describe('Max results (default 20)'),
|
|
704
|
-
}, async ({ trigger_id, limit }) => {
|
|
705
|
-
|
|
723
|
+
}, async ({ trigger_id, workspace_id, limit }) => {
|
|
724
|
+
const wsId = workspace_id || defaultWorkspaceId;
|
|
725
|
+
debugLog(debug, `guild_get_trigger_sessions: ${trigger_id} ws=${wsId}`);
|
|
706
726
|
try {
|
|
707
|
-
const response = await apiClient.get(`/workspaces/${
|
|
727
|
+
const response = await apiClient.get(`/workspaces/${wsId}/sessions?trigger_id=${trigger_id}&limit=${limit || 20}`);
|
|
708
728
|
const text = response.items
|
|
709
729
|
.map((s) => `• ${s.id} (${s.session_type}) — ${s.created_at}`)
|
|
710
730
|
.join('\n');
|
package/docs/CLI_WORKFLOW.md
CHANGED
|
@@ -7,6 +7,12 @@ description: Agent development using the Guild CLI. Activated when user mentions
|
|
|
7
7
|
|
|
8
8
|
For local agent development using the Guild CLI. This workflow manages agent code via the Guild git server.
|
|
9
9
|
|
|
10
|
+
## MCP vs CLI
|
|
11
|
+
|
|
12
|
+
If Guild MCP tools are available (check for tools prefixed with `guild_`), use them for **read operations**: searching agents, listing workspaces, reading contexts, checking sessions, viewing credentials. MCP tools are faster and don't require shell execution.
|
|
13
|
+
|
|
14
|
+
Use the **CLI** (via Bash) for **local development operations**: `guild agent create`, `guild agent save`, `guild agent test`, `guild agent pull`, `guild agent clone`. These involve the local filesystem and git, which MCP can't do.
|
|
15
|
+
|
|
10
16
|
## CRITICAL: Always Use the Guild CLI
|
|
11
17
|
|
|
12
18
|
**NEVER manually create agent files or use raw git commands.**
|
package/docs/DESIGN.md
CHANGED
|
@@ -190,6 +190,8 @@ Environments are Docker containers managed by GuildCore. The CLI provides a simp
|
|
|
190
190
|
|
|
191
191
|
The CLI integrates with AI coding assistants like Claude Code, Cursor, and others. Run `guild setup` to install Guild skills into your project.
|
|
192
192
|
|
|
193
|
+
The CLI also exposes a [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server via `guild mcp`. This gives coding assistants direct access to Guild's API — searching agents, managing workspaces, reading contexts, and starting sessions — without leaving the editor. `guild setup` configures it by default; use `--no-mcp` to skip.
|
|
194
|
+
|
|
193
195
|
**Typical Workflow:**
|
|
194
196
|
|
|
195
197
|
1. Initialize agent: `guild agent init --name my-agent --template LLM`
|
package/docs/skills/agent-dev.md
CHANGED
|
@@ -7,6 +7,12 @@ description: Local agent development using the Guild CLI. Activated when user me
|
|
|
7
7
|
|
|
8
8
|
Build agents for Guild using the CLI. **Always use the Guild CLI for agent operations - never use raw git commands.**
|
|
9
9
|
|
|
10
|
+
## MCP vs CLI
|
|
11
|
+
|
|
12
|
+
If Guild MCP tools are available (check for tools prefixed with `guild_`), use them for **read operations**: searching agents, listing workspaces, reading contexts, checking sessions, viewing credentials. MCP tools are faster and don't require shell execution.
|
|
13
|
+
|
|
14
|
+
Use the **CLI** (via Bash) for **local development operations**: `guild agent create`, `guild agent save`, `guild agent test`, `guild agent pull`, `guild agent clone`. These involve the local filesystem and git, which MCP can't do.
|
|
15
|
+
|
|
10
16
|
## When to Use This
|
|
11
17
|
|
|
12
18
|
Activate when user:
|