@agent-deck/backend 1.2.2 → 1.2.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.
@@ -1,12 +1,6 @@
1
+ import { isAgentDeckDevMode, resolveAgentDeckHome } from '@agent-deck/shared';
2
+ export { isAgentDeckDevMode, resolveAgentDeckHome };
1
3
  /** Browser URL for the dashboard (OAuth return, docs). Bundled UI uses the API origin; dev uses Vite :3000. */
2
4
  export declare function resolveDashboardOrigin(): string;
3
- /** Dev monorepo / tsx — separate data dir from production `agent-deck start`. */
4
- export declare function isAgentDeckDevMode(): boolean;
5
- /**
6
- * Agent Deck data root: SQLite, credential yaml metadata, dev secret files, icons.
7
- * Production CLI → ~/.agent-deck
8
- * Monorepo dev (AGENT_DECK_DEV=1) → ~/.agent-deck/dev
9
- */
10
- export declare function resolveAgentDeckHome(): string;
11
5
  export declare function resolveDatabasePath(): string;
12
6
  //# sourceMappingURL=paths.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAIA,+GAA+G;AAC/G,wBAAgB,sBAAsB,IAAI,MAAM,CAa/C;AAED,iFAAiF;AACjF,wBAAgB,kBAAkB,IAAI,OAAO,CAS5C;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C"}
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE9E,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,CAAC;AAEpD,+GAA+G;AAC/G,wBAAgB,sBAAsB,IAAI,MAAM,CAa/C;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAW5C"}
package/dist/lib/paths.js CHANGED
@@ -3,13 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveAgentDeckHome = exports.isAgentDeckDevMode = void 0;
6
7
  exports.resolveDashboardOrigin = resolveDashboardOrigin;
7
- exports.isAgentDeckDevMode = isAgentDeckDevMode;
8
- exports.resolveAgentDeckHome = resolveAgentDeckHome;
9
8
  exports.resolveDatabasePath = resolveDatabasePath;
10
9
  const path_1 = __importDefault(require("path"));
11
10
  const fs_1 = __importDefault(require("fs"));
12
- const os_1 = __importDefault(require("os"));
11
+ const shared_1 = require("@agent-deck/shared");
12
+ Object.defineProperty(exports, "isAgentDeckDevMode", { enumerable: true, get: function () { return shared_1.isAgentDeckDevMode; } });
13
+ Object.defineProperty(exports, "resolveAgentDeckHome", { enumerable: true, get: function () { return shared_1.resolveAgentDeckHome; } });
13
14
  /** Browser URL for the dashboard (OAuth return, docs). Bundled UI uses the API origin; dev uses Vite :3000. */
14
15
  function resolveDashboardOrigin() {
15
16
  if (process.env.AGENT_DECK_DASHBOARD_URL?.trim()) {
@@ -23,29 +24,6 @@ function resolveDashboardOrigin() {
23
24
  }
24
25
  return 'http://localhost:3000';
25
26
  }
26
- /** Dev monorepo / tsx — separate data dir from production `agent-deck start`. */
27
- function isAgentDeckDevMode() {
28
- const flag = process.env.AGENT_DECK_DEV?.trim().toLowerCase();
29
- if (flag === '1' || flag === 'true' || flag === 'yes') {
30
- return true;
31
- }
32
- if (flag === '0' || flag === 'false' || flag === 'no') {
33
- return false;
34
- }
35
- return process.env.NODE_ENV === 'development';
36
- }
37
- /**
38
- * Agent Deck data root: SQLite, credential yaml metadata, dev secret files, icons.
39
- * Production CLI → ~/.agent-deck
40
- * Monorepo dev (AGENT_DECK_DEV=1) → ~/.agent-deck/dev
41
- */
42
- function resolveAgentDeckHome() {
43
- if (process.env.AGENT_DECK_HOME?.trim()) {
44
- return path_1.default.resolve(process.env.AGENT_DECK_HOME.trim());
45
- }
46
- const base = path_1.default.join(os_1.default.homedir(), '.agent-deck');
47
- return isAgentDeckDevMode() ? path_1.default.join(base, 'dev') : base;
48
- }
49
27
  function resolveDatabasePath() {
50
28
  if (process.env.AGENT_DECK_DB_PATH?.trim()) {
51
29
  return path_1.default.resolve(process.env.AGENT_DECK_DB_PATH.trim());
@@ -54,6 +32,6 @@ function resolveDatabasePath() {
54
32
  if (process.env.AGENT_DECK_USE_CWD_DB === '1' || process.env.AGENT_DECK_USE_CWD_DB === 'true') {
55
33
  return path_1.default.resolve(process.cwd(), 'agent_deck.db');
56
34
  }
57
- return path_1.default.join(resolveAgentDeckHome(), 'agent_deck.db');
35
+ return path_1.default.join((0, shared_1.resolveAgentDeckHome)(), 'agent_deck.db');
58
36
  }
59
37
  //# sourceMappingURL=paths.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":";;;;;AAKA,wDAaC;AAGD,gDASC;AAOD,oDAOC;AAED,kDAWC;AAzDD,gDAAwB;AACxB,4CAAoB;AACpB,4CAAoB;AAEpB,+GAA+G;AAC/G,SAAgB,sBAAsB;IACpC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,MAAM,IAAI,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;QACxC,OAAO,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED,iFAAiF;AACjF,SAAgB,kBAAkB;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9D,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,SAAgB,oBAAoB;IAClC,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;QACxC,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,IAAI,GAAG,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;IACpD,OAAO,kBAAkB,EAAE,CAAC,CAAC,CAAC,cAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9D,CAAC;AAED,SAAgB,mBAAmB;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3C,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,4EAA4E;IAC5E,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,EAAE,CAAC;QAC9F,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,cAAI,CAAC,IAAI,CAAC,oBAAoB,EAAE,EAAE,eAAe,CAAC,CAAC;AAC5D,CAAC"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":";;;;;;AAOA,wDAaC;AAED,kDAWC;AAjCD,gDAAwB;AACxB,4CAAoB;AACpB,+CAA8E;AAErE,mGAFA,2BAAkB,OAEA;AAAE,qGAFA,6BAAoB,OAEA;AAEjD,+GAA+G;AAC/G,SAAgB,sBAAsB;IACpC,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,IAAI,EAAE,EAAE,CAAC;QACjD,OAAO,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,MAAM,IAAI,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,WAAW,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;QACxC,OAAO,UAAU,IAAI,IAAI,IAAI,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED,SAAgB,mBAAmB;IACjC,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAAC;QAC3C,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,4EAA4E;IAC5E,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,KAAK,MAAM,EAAE,CAAC;QAC9F,OAAO,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,eAAe,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,cAAI,CAAC,IAAI,CAAC,IAAA,6BAAoB,GAAE,EAAE,eAAe,CAAC,CAAC;AAC5D,CAAC"}
@@ -16,10 +16,13 @@ export declare class AgentDeckMCPServer {
16
16
  private getAgentHeaders;
17
17
  private fetchDeck;
18
18
  private buildBindingPayload;
19
+ private writeBindingSidecar;
19
20
  private callBackendAPI;
20
21
  private getBoundDeckId;
21
22
  private toolResult;
22
23
  private toolError;
24
+ /** Avoid TS2589 when registering many MCP tools (SDK overload recursion). */
25
+ private registerTool;
23
26
  private setupTools;
24
27
  private setupResources;
25
28
  private setupRoutes;
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAQA,OAAO,OAA8B,MAAM,SAAS,CAAC;AA0BrD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAiC;IACjD,mFAAmF;IACnF,OAAO,CAAC,wBAAwB,CAAwB;IACxD,mFAAmF;IACnF,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,eAAe,CAAqB;IAE5C,OAAO,KAAK,MAAM,GAKjB;gBAEW,IAAI,GAAE,MAAa,EAAE,UAAU,GAAE,MAAgC;IAc7E,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,eAAe;YAIT,SAAS;YAkBT,mBAAmB;YAYnB,cAAc;YAwCd,cAAc;IAQ5B,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,UAAU;IAm2BlB,OAAO,CAAC,cAAc;IA2LtB,OAAO,CAAC,WAAW;IA2CnB,OAAO,CAAC,kBAAkB;YAKZ,aAAa;YAuDb,uBAAuB;IAiB/B,KAAK;IAmCL,IAAI;CAeX"}
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAUA,OAAO,OAA8B,MAAM,SAAS,CAAC;AA2BrD,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAiC;IACjD,mFAAmF;IACnF,OAAO,CAAC,wBAAwB,CAAwB;IACxD,mFAAmF;IACnF,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,eAAe,CAAqB;IAE5C,OAAO,KAAK,MAAM,GAKjB;gBAEW,IAAI,GAAE,MAAa,EAAE,UAAU,GAAE,MAAgC;IAc7E,OAAO,CAAC,eAAe;IAYvB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,eAAe;YAIT,SAAS;YAkBT,mBAAmB;YAYnB,mBAAmB;YAoBnB,cAAc;YAwCd,cAAc;IAQ5B,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,SAAS;IAIjB,6EAA6E;IAC7E,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,UAAU;IAy2BlB,OAAO,CAAC,cAAc;IA8MtB,OAAO,CAAC,WAAW;IA2CnB,OAAO,CAAC,kBAAkB;YAKZ,aAAa;YAuDb,uBAAuB;IAiB/B,KAAK;IAmCL,IAAI;CAeX"}
@@ -16,6 +16,7 @@ const zod_1 = require("zod");
16
16
  const repo_deck_1 = require("./scope/repo-deck");
17
17
  const version_1 = require("./lib/version");
18
18
  const mcp_session_binding_1 = require("./mcp-session-binding");
19
+ const bindings_sidecar_1 = require("./scope/bindings-sidecar");
19
20
  const agentClientHeaders = {
20
21
  [shared_1.AGENT_DECK_CLIENT_HEADER]: shared_1.AGENT_DECK_AGENT_CLIENT,
21
22
  Accept: 'application/json',
@@ -88,6 +89,23 @@ class AgentDeckMCPServer {
88
89
  session_deck_override: this.sessionBinding.hasSessionDeckOverride(sessionId),
89
90
  };
90
91
  }
92
+ async writeBindingSidecar(sessionId, manifestDeckId) {
93
+ const snapshot = this.sessionBinding.getBinding(sessionId);
94
+ if (!snapshot.workspaceRoot) {
95
+ return;
96
+ }
97
+ const deck = await this.callBackendAPI('/api/scope/deck');
98
+ if (!deck?.id || !deck?.name) {
99
+ return;
100
+ }
101
+ await (0, bindings_sidecar_1.upsertBindingForWorkspace)(snapshot.workspaceRoot, {
102
+ deckId: deck.id,
103
+ deckName: deck.name,
104
+ source: (0, mcp_session_binding_1.resolveDeckBindingSource)(snapshot, manifestDeckId),
105
+ updatedAt: new Date().toISOString(),
106
+ cardCounts: (0, shared_1.countDeckCards)(deck),
107
+ });
108
+ }
91
109
  async callBackendAPI(endpoint, init = {}) {
92
110
  try {
93
111
  const response = await fetch(`${this.backendUrl}${endpoint}`, {
@@ -142,8 +160,12 @@ class AgentDeckMCPServer {
142
160
  toolError(error) {
143
161
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
144
162
  }
163
+ /** Avoid TS2589 when registering many MCP tools (SDK overload recursion). */
164
+ registerTool(name, config, handler) {
165
+ this.server.registerTool(name, config, handler);
166
+ }
145
167
  setupTools() {
146
- this.server.registerTool("bind_workspace", {
168
+ this.registerTool("bind_workspace", {
147
169
  title: "Bind Workspace",
148
170
  description: "Bind this MCP session to a workspace root. Pass deckId for a session-only deck override (same path, different concurrent agents). Without deckId, uses .agent-deck/deck.yaml when present.",
149
171
  inputSchema: {
@@ -158,6 +180,7 @@ class AgentDeckMCPServer {
158
180
  const deck = await this.fetchDeck(deckId);
159
181
  this.sessionBinding.setDeckId(sessionId, deckId);
160
182
  const payload = await this.buildBindingPayload(sessionId);
183
+ await this.writeBindingSidecar(sessionId);
161
184
  return {
162
185
  content: [{
163
186
  type: "text",
@@ -182,6 +205,7 @@ class AgentDeckMCPServer {
182
205
  }
183
206
  const { data } = body;
184
207
  const payload = await this.buildBindingPayload(sessionId, data.manifest.deck_id);
208
+ await this.writeBindingSidecar(sessionId, data.manifest.deck_id);
185
209
  return {
186
210
  content: [{
187
211
  type: "text",
@@ -203,7 +227,7 @@ class AgentDeckMCPServer {
203
227
  };
204
228
  }
205
229
  });
206
- this.server.registerTool("switch_bound_deck", {
230
+ this.registerTool("switch_bound_deck", {
207
231
  title: "Switch Bound Deck",
208
232
  description: "Switch the deck for this MCP session only. Does not modify .agent-deck/deck.yaml. Use when multiple agent sessions share the same workspace path.",
209
233
  inputSchema: { deckId: zod_1.z.string().uuid() },
@@ -213,6 +237,7 @@ class AgentDeckMCPServer {
213
237
  const deck = await this.fetchDeck(deckId);
214
238
  this.sessionBinding.setDeckId(sessionId, deckId);
215
239
  const payload = await this.buildBindingPayload(sessionId);
240
+ await this.writeBindingSidecar(sessionId);
216
241
  return {
217
242
  content: [{
218
243
  type: "text",
@@ -228,7 +253,7 @@ class AgentDeckMCPServer {
228
253
  return this.toolError(error);
229
254
  }
230
255
  });
231
- this.server.registerTool("get_session_binding", {
256
+ this.registerTool("get_session_binding", {
232
257
  title: "Get Session Binding",
233
258
  description: "Show workspace and effective deck for this MCP session, including whether the deck comes from a session override or repo deck.yaml.",
234
259
  inputSchema: {},
@@ -242,6 +267,8 @@ class AgentDeckMCPServer {
242
267
  manifestDeckId = manifest?.deck_id;
243
268
  }
244
269
  const deck = await this.callBackendAPI('/api/scope/deck');
270
+ const cardCounts = deck ? (0, shared_1.countDeckCards)(deck) : { mcp: 0, credentials: 0, playbooks: 0 };
271
+ const displaySummary = (0, shared_1.formatDisplayLine)(deck?.name ?? null, cardCounts);
245
272
  return {
246
273
  content: [{
247
274
  type: "text",
@@ -253,6 +280,7 @@ class AgentDeckMCPServer {
253
280
  effective_deck_id: deck?.id,
254
281
  effective_deck_name: deck?.name,
255
282
  effective_deck_source: (0, mcp_session_binding_1.resolveDeckBindingSource)(snapshot, manifestDeckId),
283
+ display_summary: displaySummary,
256
284
  }, null, 2),
257
285
  }],
258
286
  };
@@ -261,7 +289,7 @@ class AgentDeckMCPServer {
261
289
  return this.toolError(error);
262
290
  }
263
291
  });
264
- this.server.registerTool("get_repo_deck_status", {
292
+ this.registerTool("get_repo_deck_status", {
265
293
  title: "Get Repo Deck Status",
266
294
  description: "Check whether .agent-deck/deck.yaml exists in a workspace and whether it links to a valid deck",
267
295
  inputSchema: { workspaceRoot: zod_1.z.string() },
@@ -312,7 +340,7 @@ class AgentDeckMCPServer {
312
340
  };
313
341
  }
314
342
  });
315
- this.server.registerTool("setup_repo_deck", {
343
+ this.registerTool("setup_repo_deck", {
316
344
  title: "Setup Repo Deck",
317
345
  description: "Create or verify .agent-deck/deck.yaml in a repo. Links the workspace to an Agent Deck by deck_id. Optionally writes the file.",
318
346
  inputSchema: {
@@ -403,7 +431,7 @@ class AgentDeckMCPServer {
403
431
  }
404
432
  });
405
433
  // Get all decks (metadata only; credentials stripped unless bound)
406
- this.server.registerTool("get_decks", {
434
+ this.registerTool("get_decks", {
407
435
  title: "Get Decks",
408
436
  description: "Get all available decks from Agent Deck",
409
437
  inputSchema: {}
@@ -420,7 +448,7 @@ class AgentDeckMCPServer {
420
448
  };
421
449
  }
422
450
  });
423
- this.server.registerTool("get_bound_deck", {
451
+ this.registerTool("get_bound_deck", {
424
452
  title: "Get Bound Deck",
425
453
  description: "Get the deck bound to this session (session deckId override, env, or .agent-deck/deck.yaml)",
426
454
  inputSchema: {},
@@ -438,7 +466,7 @@ class AgentDeckMCPServer {
438
466
  }
439
467
  });
440
468
  // Deprecated alias
441
- this.server.registerTool("get_active_deck", {
469
+ this.registerTool("get_active_deck", {
442
470
  title: "Get Active Deck (deprecated)",
443
471
  description: "Deprecated — use get_bound_deck. Returns the workspace-bound deck.",
444
472
  inputSchema: {},
@@ -455,7 +483,7 @@ class AgentDeckMCPServer {
455
483
  };
456
484
  }
457
485
  });
458
- this.server.registerTool("list_bound_deck_services", {
486
+ this.registerTool("list_bound_deck_services", {
459
487
  title: "List Bound Deck Services",
460
488
  description: "List MCP services on the workspace-bound deck",
461
489
  inputSchema: {},
@@ -469,7 +497,7 @@ class AgentDeckMCPServer {
469
497
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
470
498
  }
471
499
  });
472
- this.server.registerTool("list_active_deck_services", {
500
+ this.registerTool("list_active_deck_services", {
473
501
  title: "List Active Deck Services (deprecated)",
474
502
  description: "Deprecated — use list_bound_deck_services",
475
503
  inputSchema: {},
@@ -483,7 +511,7 @@ class AgentDeckMCPServer {
483
511
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
484
512
  }
485
513
  });
486
- this.server.registerTool("list_bound_deck_credentials", {
514
+ this.registerTool("list_bound_deck_credentials", {
487
515
  title: "List Bound Deck Credentials",
488
516
  description: "List API key metadata on the workspace-bound deck",
489
517
  inputSchema: {},
@@ -496,7 +524,7 @@ class AgentDeckMCPServer {
496
524
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
497
525
  }
498
526
  });
499
- this.server.registerTool("list_active_deck_credentials", {
527
+ this.registerTool("list_active_deck_credentials", {
500
528
  title: "List Active Deck Credentials (deprecated)",
501
529
  description: "Deprecated — use list_bound_deck_credentials",
502
530
  inputSchema: {},
@@ -509,7 +537,7 @@ class AgentDeckMCPServer {
509
537
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
510
538
  }
511
539
  });
512
- this.server.registerTool("list_playbooks", {
540
+ this.registerTool("list_playbooks", {
513
541
  title: "List Playbooks",
514
542
  description: "List playbook cards on the bound deck (id, title, triggers)",
515
543
  inputSchema: {},
@@ -522,7 +550,7 @@ class AgentDeckMCPServer {
522
550
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
523
551
  }
524
552
  });
525
- this.server.registerTool("get_playbook", {
553
+ this.registerTool("get_playbook", {
526
554
  title: "Get Playbook",
527
555
  description: "Get full markdown body, metadata, and dependencies for a playbook card by id",
528
556
  inputSchema: { playbook_id: zod_1.z.string() },
@@ -535,7 +563,7 @@ class AgentDeckMCPServer {
535
563
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
536
564
  }
537
565
  });
538
- this.server.registerTool("register_playbook", {
566
+ this.registerTool("register_playbook", {
539
567
  title: "Register Playbook",
540
568
  description: "Create a playbook card, auto-detect API key and MCP dependencies from the content, and add it to the bound deck by default",
541
569
  inputSchema: {
@@ -574,7 +602,7 @@ class AgentDeckMCPServer {
574
602
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
575
603
  }
576
604
  });
577
- this.server.registerTool("update_playbook", {
605
+ this.registerTool("update_playbook", {
578
606
  title: "Update Playbook",
579
607
  description: "Update a playbook on the bound deck. Dependencies are re-detected from the updated content by default.",
580
608
  inputSchema: {
@@ -610,7 +638,7 @@ class AgentDeckMCPServer {
610
638
  return { content: [{ type: "text", text: JSON.stringify({ error: String(error) }, null, 2) }] };
611
639
  }
612
640
  });
613
- this.server.registerTool("list_collection_services", {
641
+ this.registerTool("list_collection_services", {
614
642
  title: "List Collection Services",
615
643
  description: "List all registered MCP services in the collection (metadata only)",
616
644
  inputSchema: {},
@@ -623,7 +651,7 @@ class AgentDeckMCPServer {
623
651
  return this.toolError(error);
624
652
  }
625
653
  });
626
- this.server.registerTool("register_service", {
654
+ this.registerTool("register_service", {
627
655
  title: "Register Service",
628
656
  description: "Register an MCP service in the collection. Optionally add it to the bound deck. OAuth setup still requires the dashboard browser flow.",
629
657
  inputSchema: {
@@ -663,7 +691,7 @@ class AgentDeckMCPServer {
663
691
  return this.toolError(error);
664
692
  }
665
693
  });
666
- this.server.registerTool("update_service", {
694
+ this.registerTool("update_service", {
667
695
  title: "Update Service",
668
696
  description: "Update MCP service metadata in the collection (not OAuth tokens — use dashboard for OAuth)",
669
697
  inputSchema: {
@@ -693,7 +721,7 @@ class AgentDeckMCPServer {
693
721
  return this.toolError(error);
694
722
  }
695
723
  });
696
- this.server.registerTool("delete_service", {
724
+ this.registerTool("delete_service", {
697
725
  title: "Delete Service",
698
726
  description: "Remove an MCP service from the collection entirely",
699
727
  inputSchema: { service_id: zod_1.z.string() },
@@ -706,7 +734,7 @@ class AgentDeckMCPServer {
706
734
  return this.toolError(error);
707
735
  }
708
736
  });
709
- this.server.registerTool("add_service_to_bound_deck", {
737
+ this.registerTool("add_service_to_bound_deck", {
710
738
  title: "Add Service To Bound Deck",
711
739
  description: "Link an existing MCP service from the collection onto the bound deck",
712
740
  inputSchema: {
@@ -727,7 +755,7 @@ class AgentDeckMCPServer {
727
755
  return this.toolError(error);
728
756
  }
729
757
  });
730
- this.server.registerTool("remove_service_from_bound_deck", {
758
+ this.registerTool("remove_service_from_bound_deck", {
731
759
  title: "Remove Service From Bound Deck",
732
760
  description: "Unlink an MCP service from the bound deck (service stays in the collection)",
733
761
  inputSchema: { service_id: zod_1.z.string() },
@@ -745,7 +773,7 @@ class AgentDeckMCPServer {
745
773
  return this.toolError(error);
746
774
  }
747
775
  });
748
- this.server.registerTool("update_service_tool_settings", {
776
+ this.registerTool("update_service_tool_settings", {
749
777
  title: "Update Service Tool Settings",
750
778
  description: "Enable or disable individual tools for an MCP service on the bound deck",
751
779
  inputSchema: {
@@ -765,7 +793,7 @@ class AgentDeckMCPServer {
765
793
  return this.toolError(error);
766
794
  }
767
795
  });
768
- this.server.registerTool("list_collection_credentials", {
796
+ this.registerTool("list_collection_credentials", {
769
797
  title: "List Collection Credentials",
770
798
  description: "List all API key metadata in the collection (no secret values). Use credential ids to link keys to the bound deck after the user stores the secret in the dashboard.",
771
799
  inputSchema: {},
@@ -778,7 +806,7 @@ class AgentDeckMCPServer {
778
806
  return this.toolError(error);
779
807
  }
780
808
  });
781
- this.server.registerTool("add_credential_to_bound_deck", {
809
+ this.registerTool("add_credential_to_bound_deck", {
782
810
  title: "Add Credential To Bound Deck",
783
811
  description: "Link an existing API key (by credential id) to the bound deck. The secret must already be stored via the dashboard or CLI.",
784
812
  inputSchema: {
@@ -799,7 +827,7 @@ class AgentDeckMCPServer {
799
827
  return this.toolError(error);
800
828
  }
801
829
  });
802
- this.server.registerTool("remove_credential_from_bound_deck", {
830
+ this.registerTool("remove_credential_from_bound_deck", {
803
831
  title: "Remove Credential From Bound Deck",
804
832
  description: "Unlink an API key from the bound deck (credential stays in the vault)",
805
833
  inputSchema: { credential_id: zod_1.z.string() },
@@ -817,7 +845,7 @@ class AgentDeckMCPServer {
817
845
  return this.toolError(error);
818
846
  }
819
847
  });
820
- this.server.registerTool("list_collection_playbooks", {
848
+ this.registerTool("list_collection_playbooks", {
821
849
  title: "List Collection Playbooks",
822
850
  description: "List all playbook cards in the collection (for linking existing playbooks to the bound deck)",
823
851
  inputSchema: {},
@@ -830,7 +858,7 @@ class AgentDeckMCPServer {
830
858
  return this.toolError(error);
831
859
  }
832
860
  });
833
- this.server.registerTool("add_playbook_to_bound_deck", {
861
+ this.registerTool("add_playbook_to_bound_deck", {
834
862
  title: "Add Playbook To Bound Deck",
835
863
  description: "Link an existing playbook card from the collection onto the bound deck",
836
864
  inputSchema: {
@@ -851,7 +879,7 @@ class AgentDeckMCPServer {
851
879
  return this.toolError(error);
852
880
  }
853
881
  });
854
- this.server.registerTool("remove_playbook_from_bound_deck", {
882
+ this.registerTool("remove_playbook_from_bound_deck", {
855
883
  title: "Remove Playbook From Bound Deck",
856
884
  description: "Unlink a playbook from the bound deck (playbook stays in the collection)",
857
885
  inputSchema: { playbook_id: zod_1.z.string() },
@@ -869,7 +897,7 @@ class AgentDeckMCPServer {
869
897
  return this.toolError(error);
870
898
  }
871
899
  });
872
- this.server.registerTool("delete_playbook", {
900
+ this.registerTool("delete_playbook", {
873
901
  title: "Delete Playbook",
874
902
  description: "Delete a playbook from the collection (must be on the bound deck for agent clients)",
875
903
  inputSchema: { playbook_id: zod_1.z.string() },
@@ -884,7 +912,7 @@ class AgentDeckMCPServer {
884
912
  return this.toolError(error);
885
913
  }
886
914
  });
887
- this.server.registerTool("create_deck", {
915
+ this.registerTool("create_deck", {
888
916
  title: "Create Deck",
889
917
  description: "Create a new deck in Agent Deck",
890
918
  inputSchema: {
@@ -905,7 +933,7 @@ class AgentDeckMCPServer {
905
933
  }
906
934
  });
907
935
  // Remove duplicate old tools block - list_service_tools follows
908
- this.server.registerTool("list_service_tools", {
936
+ this.registerTool("list_service_tools", {
909
937
  title: "List Service Tools",
910
938
  description: "List all available tools for a specific service in the active deck",
911
939
  inputSchema: { serviceId: zod_1.z.string() }
@@ -919,7 +947,7 @@ class AgentDeckMCPServer {
919
947
  }
920
948
  });
921
949
  // Call a tool on a service in the active deck
922
- this.server.registerTool("call_service_tool", {
950
+ this.registerTool("call_service_tool", {
923
951
  title: "Call Service Tool",
924
952
  description: "Call a tool on a service from the active deck",
925
953
  inputSchema: {
@@ -958,8 +986,32 @@ class AgentDeckMCPServer {
958
986
  });
959
987
  }
960
988
  setupResources() {
989
+ this.server.resource("bound_deck_summary", "agent-deck://bound-deck/summary", {
990
+ description: "One-line summary of the workspace-bound deck for status display",
991
+ mimeType: "text/plain",
992
+ }, async () => {
993
+ try {
994
+ const deck = await this.callBackendAPI('/api/scope/deck');
995
+ const summary = (0, shared_1.formatDisplayLine)(deck?.name ?? null, (0, shared_1.countDeckCards)(deck ?? {}));
996
+ return {
997
+ contents: [{
998
+ uri: "agent-deck://bound-deck/summary",
999
+ mimeType: "text/plain",
1000
+ text: summary,
1001
+ }],
1002
+ };
1003
+ }
1004
+ catch (error) {
1005
+ return {
1006
+ contents: [{
1007
+ uri: "agent-deck://bound-deck/summary",
1008
+ mimeType: "text/plain",
1009
+ text: (0, shared_1.formatDisplayLine)(null, { mcp: 0, credentials: 0, playbooks: 0 }),
1010
+ }],
1011
+ };
1012
+ }
1013
+ });
961
1014
  this.server.resource("bound_deck_services", "agent-deck://bound-deck/services", {
962
- name: "Bound Deck Services",
963
1015
  description: "MCP services on the workspace-bound deck",
964
1016
  mimeType: "application/json"
965
1017
  }, async () => {
@@ -985,7 +1037,6 @@ class AgentDeckMCPServer {
985
1037
  }
986
1038
  });
987
1039
  this.server.resource("active_deck_services", "agent-deck://active-deck/services", {
988
- name: "Active Deck Services (deprecated)",
989
1040
  description: "Deprecated — use agent-deck://bound-deck/services",
990
1041
  mimeType: "application/json"
991
1042
  }, async () => {
@@ -1011,7 +1062,6 @@ class AgentDeckMCPServer {
1011
1062
  }
1012
1063
  });
1013
1064
  this.server.resource("bound_deck_credentials", "agent-deck://bound-deck/credentials", {
1014
- name: "Bound Deck Credentials",
1015
1065
  description: "API key metadata on the workspace-bound deck",
1016
1066
  mimeType: "application/json"
1017
1067
  }, async () => {
@@ -1036,7 +1086,6 @@ class AgentDeckMCPServer {
1036
1086
  }
1037
1087
  });
1038
1088
  this.server.resource("active_deck_credentials", "agent-deck://active-deck/credentials", {
1039
- name: "Active Deck Credentials (deprecated)",
1040
1089
  description: "Deprecated — use agent-deck://bound-deck/credentials",
1041
1090
  mimeType: "application/json"
1042
1091
  }, async () => {
@@ -1061,7 +1110,6 @@ class AgentDeckMCPServer {
1061
1110
  }
1062
1111
  });
1063
1112
  this.server.resource("bound_deck", "agent-deck://bound-deck", {
1064
- name: "Bound Deck",
1065
1113
  description: "Deck bound via .agent-deck/deck.yaml in the workspace",
1066
1114
  mimeType: "application/json"
1067
1115
  }, async () => {
@@ -1086,7 +1134,6 @@ class AgentDeckMCPServer {
1086
1134
  }
1087
1135
  });
1088
1136
  this.server.resource("active_deck", "agent-deck://active-deck", {
1089
- name: "Active Deck (deprecated)",
1090
1137
  description: "Deprecated — use agent-deck://bound-deck",
1091
1138
  mimeType: "application/json"
1092
1139
  }, async () => {
@@ -1112,7 +1159,6 @@ class AgentDeckMCPServer {
1112
1159
  });
1113
1160
  // Register resource for all decks
1114
1161
  this.server.resource("decks", "agent-deck://decks", {
1115
- name: "Agent Deck Decks",
1116
1162
  description: "List of all available decks",
1117
1163
  mimeType: "application/json"
1118
1164
  }, async () => {