@delega-dev/mcp 1.0.5 → 1.0.7

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.
Files changed (3) hide show
  1. package/README.md +7 -0
  2. package/dist/index.js +28 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -34,9 +34,16 @@ Add to your MCP client config (e.g. Claude Desktop `claude_desktop_config.json`)
34
34
  |----------|---------|-------------|
35
35
  | `DELEGA_API_URL` | `http://127.0.0.1:18890` | Delega API endpoint |
36
36
  | `DELEGA_AGENT_KEY` | (none) | Agent API key for authenticated requests |
37
+ | `DELEGA_REVEAL_AGENT_KEYS` | `0` | Set to `1` only if you want MCP tool output to print full agent API keys |
37
38
 
38
39
  For the hosted tier, use `https://api.delega.dev` as the URL.
39
40
 
41
+ ## Security Notes
42
+
43
+ - Non-local `DELEGA_API_URL` values must use `https://`.
44
+ - Agent keys are passed through environment variables rather than command-line arguments, which avoids process-list leakage.
45
+ - MCP tool output redacts full agent API keys by default. Set `DELEGA_REVEAL_AGENT_KEYS=1` only when you explicitly want them printed back to the client.
46
+
40
47
  ## Tools
41
48
 
42
49
  | Tool | Description |
package/dist/index.js CHANGED
@@ -7,14 +7,22 @@ import { z } from "zod";
7
7
 
8
8
  // src/delega-client.ts
9
9
  var DEFAULT_BASE_URL = "http://127.0.0.1:18890";
10
+ var LOCAL_API_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1"]);
11
+ function normalizeBaseUrl(rawUrl) {
12
+ const parsed = new URL(rawUrl);
13
+ if (parsed.protocol !== "https:" && !LOCAL_API_HOSTS.has(parsed.hostname)) {
14
+ throw new Error("Delega API URL must use HTTPS unless it points to localhost");
15
+ }
16
+ return rawUrl.replace(/\/+$/, "");
17
+ }
10
18
  var DelegaClient = class {
11
19
  baseUrl;
12
20
  agentKey;
13
21
  pathPrefix;
14
22
  constructor(baseUrl, agentKey) {
15
- this.baseUrl = (baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
23
+ this.baseUrl = normalizeBaseUrl(baseUrl || DEFAULT_BASE_URL);
16
24
  this.agentKey = agentKey;
17
- this.pathPrefix = this.baseUrl.includes("api.delega.dev") ? "/v1" : "/api";
25
+ this.pathPrefix = new URL(this.baseUrl).hostname === "api.delega.dev" ? "/v1" : "/api";
18
26
  }
19
27
  async request(method, path, body, query) {
20
28
  const url = new URL(path, this.baseUrl);
@@ -130,11 +138,21 @@ function formatTask(t) {
130
138
  function formatProject(p) {
131
139
  return `[#${p.id}] ${p.name}`;
132
140
  }
141
+ function maskApiKey(key) {
142
+ if (key.length <= 12) return key;
143
+ return `${key.slice(0, 8)}...${key.slice(-4)}`;
144
+ }
133
145
  function formatAgent(a) {
134
146
  const lines = [];
135
147
  lines.push(`[#${a.id}] ${a.name}${a.display_name ? ` (${a.display_name})` : ""}`);
136
148
  if (a.description) lines.push(` Description: ${a.description}`);
137
- if (a.api_key) lines.push(` API Key: ${a.api_key}`);
149
+ if (a.api_key) {
150
+ if (process.env.DELEGA_REVEAL_AGENT_KEYS === "1") {
151
+ lines.push(` API Key: ${a.api_key}`);
152
+ } else {
153
+ lines.push(` API Key Preview: ${maskApiKey(a.api_key)}`);
154
+ }
155
+ }
138
156
  if (a.permissions?.length) lines.push(` Permissions: ${a.permissions.join(", ")}`);
139
157
  if (a.active !== void 0) lines.push(` Active: ${a.active ? "yes" : "no"}`);
140
158
  return lines.join("\n");
@@ -169,7 +187,7 @@ server.tool(
169
187
  "get_task",
170
188
  "Get full details of a specific task including subtasks",
171
189
  {
172
- task_id: z.number().int().describe("The task ID")
190
+ task_id: z.union([z.string(), z.number()]).describe("The task ID (use the ID from list_tasks, e.g. '3a7d...')")
173
191
  },
174
192
  async ({ task_id }) => {
175
193
  try {
@@ -208,7 +226,7 @@ server.tool(
208
226
  "update_task",
209
227
  "Update an existing task's fields",
210
228
  {
211
- task_id: z.number().int().describe("The task ID to update"),
229
+ task_id: z.union([z.string(), z.number()]).describe("The task ID to update"),
212
230
  content: z.string().optional().describe("New task title / content"),
213
231
  description: z.string().optional().describe("New description"),
214
232
  labels: z.array(z.string()).optional().describe("New labels"),
@@ -233,7 +251,7 @@ server.tool(
233
251
  "complete_task",
234
252
  "Mark a task as completed",
235
253
  {
236
- task_id: z.number().int().describe("The task ID to complete")
254
+ task_id: z.union([z.string(), z.number()]).describe("The task ID to complete")
237
255
  },
238
256
  async ({ task_id }) => {
239
257
  try {
@@ -253,7 +271,7 @@ server.tool(
253
271
  "delete_task",
254
272
  "Delete a task permanently",
255
273
  {
256
- task_id: z.number().int().describe("The task ID to delete")
274
+ task_id: z.union([z.string(), z.number()]).describe("The task ID to delete")
257
275
  },
258
276
  async ({ task_id }) => {
259
277
  try {
@@ -270,7 +288,7 @@ server.tool(
270
288
  "add_comment",
271
289
  "Add a comment to a task",
272
290
  {
273
- task_id: z.number().int().describe("The task ID to comment on"),
291
+ task_id: z.union([z.string(), z.number()]).describe("The task ID to comment on"),
274
292
  content: z.string().describe("Comment text"),
275
293
  author: z.string().optional().describe("Comment author name")
276
294
  },
@@ -361,12 +379,11 @@ server.tool(
361
379
  async (params) => {
362
380
  try {
363
381
  const agent = await client.registerAgent(params);
382
+ const warning = process.env.DELEGA_REVEAL_AGENT_KEYS === "1" ? "\n\n\u26A0\uFE0F Save the API key \u2014 it won't be shown again." : "\n\nAPI keys are redacted by default in MCP output. Set DELEGA_REVEAL_AGENT_KEYS=1 to reveal them.";
364
383
  return {
365
384
  content: [{ type: "text", text: `Agent registered:
366
385
 
367
- ${formatAgent(agent)}
368
-
369
- \u26A0\uFE0F Save the API key \u2014 it won't be shown again.` }]
386
+ ${formatAgent(agent)}${warning}` }]
370
387
  };
371
388
  } catch (e) {
372
389
  return { content: [{ type: "text", text: `Error: ${e.message}` }], isError: true };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delega-dev/mcp",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "mcpName": "io.github.delega-dev/delega",
5
5
  "description": "MCP server for Delega — task infrastructure for AI agents",
6
6
  "type": "module",