@cpenned/mcp 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Chris Pennington
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # @cpenned/mcp
2
+
3
+ MCP server for Open Brain. A thin adapter over the `/v1` HTTP API: every tool is
4
+ an authenticated call through the same enforced path as any other API consumer,
5
+ so the guard layer remains the single write chokepoint.
6
+
7
+ ## Configuration
8
+
9
+ Set via environment variables:
10
+
11
+ | Variable | Required | Description |
12
+ | ------------------------ | -------- | ------------------------------------------------------------------ |
13
+ | `OPEN_BRAIN_API_URL` | yes | Deployment origin, e.g. `https://<deployment>.convex.site` |
14
+ | `OPEN_BRAIN_API_KEY` | yes | An `obr_` API key with the scopes the tools you use require |
15
+ | `OPEN_BRAIN_CLIENT_TYPE` | no | `X-Client` stamped on the audit log (default `mcp`) |
16
+
17
+ The key's scopes gate the tools: resource tools need `<resource>:read|write`,
18
+ review tools `reviews:*`, and `find_tasks` / `ai_triage` need `ai:invoke`.
19
+
20
+ ## Run
21
+
22
+ The package is published to npm, so the simplest path needs no clone or build -
23
+ just run it with `npx`:
24
+
25
+ ```bash
26
+ OPEN_BRAIN_API_URL=... OPEN_BRAIN_API_KEY=... npx -y @cpenned/mcp
27
+ ```
28
+
29
+ The server speaks MCP over stdio.
30
+
31
+ ### Claude Desktop / CLI
32
+
33
+ ```json
34
+ {
35
+ "mcpServers": {
36
+ "open-brain": {
37
+ "command": "npx",
38
+ "args": ["-y", "@cpenned/mcp"],
39
+ "env": {
40
+ "OPEN_BRAIN_API_URL": "https://<deployment>.convex.site",
41
+ "OPEN_BRAIN_API_KEY": "obr_..."
42
+ }
43
+ }
44
+ }
45
+ }
46
+ ```
47
+
48
+ ### From source (development)
49
+
50
+ Building from the monorepo instead of npm:
51
+
52
+ ```bash
53
+ npm install
54
+ npm run build -w @cpenned/mcp
55
+ OPEN_BRAIN_API_URL=... OPEN_BRAIN_API_KEY=... node packages/mcp/dist/index.js
56
+ ```
57
+
58
+ Point the `args` at the absolute `packages/mcp/dist/index.js` path with
59
+ `"command": "node"` if you wire a source build into Claude Desktop.
60
+
61
+ ## Tools
62
+
63
+ - **Resources** (CRUD, single + batch + multi-get): `create_task`, `list_tasks`,
64
+ `get_task`, `update_task`, `delete_task`, `create_tasks`, `update_tasks`,
65
+ `add_task_tags`, `remove_task_tags`; the `*_project`, `*_garden`, `*_tag`
66
+ equivalents.
67
+ - **Views & reviews**: `get_view`, `get_reviews`, `review_garden`,
68
+ `request_garden_review`, `mark_task_reviewed`, `mark_project_reviewed`.
69
+ - **AI**: `find_tasks` (hybrid search), `ai_triage` (brain-dump triage).
70
+ - **UI (read-only MCPUI)**: `ui_view`, `ui_review_queue`, `ui_garden_board`
71
+ return `ui://` HTML resources.
72
+ - **Key management**: `create_key`, `list_keys`, `rotate_key`, `revoke_key`
73
+ (require the configured key to hold `keys:manage`). A key can only grant
74
+ scopes it itself holds; secrets are returned once. Grant `keys:manage`
75
+ deliberately - it lets the agent mint and revoke keys.
76
+
77
+ ## Publishing
78
+
79
+ MIT-licensed and publish-ready (`files`, `publishConfig`, `prepublishOnly`
80
+ build). To cut a release: bump the version, then `npm publish -w @cpenned/mcp`
81
+ from the repo root (`@cpenned` is the owner's npm username scope, so no org is
82
+ needed; you must be authenticated as that user). `prepublishOnly` rebuilds
83
+ `dist` first.
package/dist/client.js ADDED
@@ -0,0 +1,60 @@
1
+ export class ApiError extends Error {
2
+ status;
3
+ constructor(status, message) {
4
+ super(message);
5
+ this.status = status;
6
+ this.name = "ApiError";
7
+ }
8
+ }
9
+ export class OpenBrainClient {
10
+ config;
11
+ fetchFn;
12
+ constructor(config, fetchFn = fetch) {
13
+ this.config = config;
14
+ this.fetchFn = fetchFn;
15
+ }
16
+ async request(method, path, opts = {}) {
17
+ const url = new URL(this.config.baseUrl + path);
18
+ if (opts.query) {
19
+ for (const [key, value] of Object.entries(opts.query)) {
20
+ if (value !== undefined && value !== null)
21
+ url.searchParams.set(key, String(value));
22
+ }
23
+ }
24
+ const headers = {
25
+ Authorization: `Bearer ${this.config.apiKey}`,
26
+ "X-Client": this.config.clientType,
27
+ };
28
+ if (opts.body !== undefined)
29
+ headers["Content-Type"] = "application/json";
30
+ if (opts.idempotencyKey)
31
+ headers["Idempotency-Key"] = opts.idempotencyKey;
32
+ if (opts.timezone)
33
+ headers["X-Timezone"] = opts.timezone;
34
+ const res = await this.fetchFn(url.toString(), {
35
+ method,
36
+ headers,
37
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
38
+ });
39
+ const text = await res.text();
40
+ const data = text ? JSON.parse(text) : null;
41
+ if (!res.ok) {
42
+ const message = data?.error?.message ?? res.statusText ?? `HTTP ${res.status}`;
43
+ throw new ApiError(res.status, message);
44
+ }
45
+ return data;
46
+ }
47
+ get(path, query) {
48
+ return this.request("GET", path, { query });
49
+ }
50
+ post(path, body, extra) {
51
+ return this.request("POST", path, { body, ...extra });
52
+ }
53
+ patch(path, body) {
54
+ return this.request("PATCH", path, { body });
55
+ }
56
+ del(path) {
57
+ return this.request("DELETE", path);
58
+ }
59
+ }
60
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/config.js ADDED
@@ -0,0 +1,16 @@
1
+ export function loadConfig(env = process.env) {
2
+ const baseUrl = env.OPEN_BRAIN_API_URL;
3
+ const apiKey = env.OPEN_BRAIN_API_KEY;
4
+ if (!baseUrl) {
5
+ throw new Error("OPEN_BRAIN_API_URL is required (e.g. https://<deployment>.convex.site)");
6
+ }
7
+ if (!apiKey) {
8
+ throw new Error("OPEN_BRAIN_API_KEY is required");
9
+ }
10
+ return {
11
+ baseUrl: baseUrl.replace(/\/+$/, "").replace(/\/v1$/, ""),
12
+ apiKey,
13
+ clientType: env.OPEN_BRAIN_CLIENT_TYPE ?? "mcp",
14
+ };
15
+ }
16
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,UAAU,CAAC,MAAyB,OAAO,CAAC,GAAG;IAC7D,MAAM,OAAO,GAAG,GAAG,CAAC,kBAAkB,CAAC;IACvC,MAAM,MAAM,GAAG,GAAG,CAAC,kBAAkB,CAAC;IACtC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;QACzD,MAAM;QACN,UAAU,EAAE,GAAG,CAAC,sBAAsB,IAAI,KAAK;KAChD,CAAC;AACJ,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { OpenBrainClient } from "./client.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { createServer } from "./server.js";
6
+ async function main() {
7
+ const config = loadConfig();
8
+ const client = new OpenBrainClient(config);
9
+ const server = createServer(client);
10
+ await server.connect(new StdioServerTransport());
11
+ // stdout is the protocol channel; logs must go to stderr.
12
+ console.error("Open Brain MCP server running on stdio");
13
+ }
14
+ main().catch((error) => {
15
+ console.error("Fatal error starting Open Brain MCP server:", error);
16
+ process.exit(1);
17
+ });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,oBAAoB,EAAE,CAAC,CAAC;IACjD,0DAA0D;IAC1D,OAAO,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;AAC1D,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,6CAA6C,EAAE,KAAK,CAAC,CAAC;IACpE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/dist/result.js ADDED
@@ -0,0 +1,25 @@
1
+ // Shared shape for tool results. A tool either returns JSON (rendered as a
2
+ // pretty-printed text block) or surfaces an API failure as an MCP tool error
3
+ // (isError) rather than throwing, so the model sees the failure and can react.
4
+ import { ApiError } from "./client.js";
5
+ export function jsonResult(data) {
6
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
7
+ }
8
+ export function errorResult(error) {
9
+ const message = error instanceof ApiError
10
+ ? `API error ${error.status}: ${error.message}`
11
+ : error instanceof Error
12
+ ? error.message
13
+ : String(error);
14
+ return { content: [{ type: "text", text: message }], isError: true };
15
+ }
16
+ // Run a tool body, mapping any thrown error to an MCP tool error result.
17
+ export async function runTool(fn) {
18
+ try {
19
+ return jsonResult(await fn());
20
+ }
21
+ catch (error) {
22
+ return errorResult(error);
23
+ }
24
+ }
25
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,+EAA+E;AAC/E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AASvC,MAAM,UAAU,UAAU,CAAC,IAAa;IACtC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,OAAO,GACX,KAAK,YAAY,QAAQ;QACvB,CAAC,CAAC,aAAa,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,EAAE;QAC/C,CAAC,CAAC,KAAK,YAAY,KAAK;YACtB,CAAC,CAAC,KAAK,CAAC,OAAO;YACf,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACtB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,EAA0B;IACtD,IAAI,CAAC;QACH,OAAO,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,8 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { registerAllTools } from "./tools/index.js";
3
+ export function createServer(client) {
4
+ const server = new McpServer({ name: "open-brain", version: "0.1.0" });
5
+ registerAllTools(server, client);
6
+ return server;
7
+ }
8
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEpD,MAAM,UAAU,YAAY,CAAC,MAAuB;IAClD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACvE,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,49 @@
1
+ // AI tools: hybrid search (find_tasks) and brain-dump triage (ai_triage). Both
2
+ // hit the ai:invoke surface and count against the AI rate limit. Triage assigns
3
+ // gardens from their Markdown context and returns clarifications when unsure
4
+ // rather than guessing, so the result has created / clarifications / errors.
5
+ import { z } from "zod";
6
+ import { runTool } from "../result.js";
7
+ import { idempotencyKey } from "./schemas.js";
8
+ const findTasksSchema = z.object({
9
+ query: z.string().describe("Natural-language or keyword query"),
10
+ limit: z.number().int().positive().optional(),
11
+ deadlineBefore: z
12
+ .string()
13
+ .optional()
14
+ .describe("Only tasks with a deadline at or before this (epoch ms or date string like 'friday')"),
15
+ deadlineAfter: z
16
+ .string()
17
+ .optional()
18
+ .describe("Only tasks with a deadline at or after this (epoch ms or date string)"),
19
+ });
20
+ export function findTasks(client, args) {
21
+ return client.post("/v1/ai/search", {
22
+ query: args.query,
23
+ limit: args.limit,
24
+ deadlineBefore: args.deadlineBefore,
25
+ deadlineAfter: args.deadlineAfter,
26
+ });
27
+ }
28
+ const aiTriageSchema = z.object({
29
+ input: z
30
+ .string()
31
+ .describe("A messy brain dump to triage into structured, garden-assigned tasks"),
32
+ idempotencyKey,
33
+ });
34
+ export function aiTriage(client, args) {
35
+ return client.post("/v1/ai/triage", { input: args.input }, { idempotencyKey: args.idempotencyKey });
36
+ }
37
+ export function registerAiTools(server, client) {
38
+ server.registerTool("find_tasks", {
39
+ title: "Find tasks",
40
+ description: "Hybrid keyword + semantic search over active tasks, optionally narrowed to a deadline window.",
41
+ inputSchema: findTasksSchema.shape,
42
+ }, (args) => runTool(() => findTasks(client, args)));
43
+ server.registerTool("ai_triage", {
44
+ title: "AI triage",
45
+ description: "Triage a brain dump into garden-assigned tasks. Returns { created, clarifications, errors }; resolve clarifications before re-submitting.",
46
+ inputSchema: aiTriageSchema.shape,
47
+ }, (args) => runTool(() => aiTriage(client, args)));
48
+ }
49
+ //# sourceMappingURL=ai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/tools/ai.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gFAAgF;AAChF,6EAA6E;AAC7E,6EAA6E;AAG7E,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,mCAAmC,CAAC;IAC/D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IAC7C,cAAc,EAAE,CAAC;SACd,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,sFAAsF,CACvF;IACH,aAAa,EAAE,CAAC;SACb,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uEAAuE,CAAC;CACrF,CAAC,CAAC;AAEH,MAAM,UAAU,SAAS,CAAC,MAAuB,EAAE,IAAmB;IACpE,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,EAAE;QAClC,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,KAAK,EAAE,CAAC;SACL,MAAM,EAAE;SACR,QAAQ,CAAC,qEAAqE,CAAC;IAClF,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,UAAU,QAAQ,CAAC,MAAuB,EAAE,IAAkB;IAClE,OAAO,MAAM,CAAC,IAAI,CAChB,eAAe,EACf,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EACrB,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CACxC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAuB;IACxE,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,YAAY;QACnB,WAAW,EACT,+FAA+F;QACjG,WAAW,EAAE,eAAe,CAAC,KAAK;KACnC,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CACjD,CAAC;IACF,MAAM,CAAC,YAAY,CACjB,WAAW,EACX;QACE,KAAK,EAAE,WAAW;QAClB,WAAW,EACT,2IAA2I;QAC7I,WAAW,EAAE,cAAc,CAAC,KAAK;KAClC,EACD,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAChD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,82 @@
1
+ // Garden tools: life-domain CRUD. Gardens are not completable; "delete" archives
2
+ // them (soft-delete). The Markdown `context` is what AI triage reads to assign
3
+ // tasks, so it is a first-class field here.
4
+ import { z } from "zod";
5
+ import { runTool } from "../result.js";
6
+ import { idempotencyKey } from "./schemas.js";
7
+ const gardenFields = {
8
+ name: z.string(),
9
+ notes: z.string().optional(),
10
+ context: z
11
+ .string()
12
+ .optional()
13
+ .describe("Markdown context AI triage uses to assign tasks to this garden"),
14
+ color: z.string().optional(),
15
+ icon: z.string().optional(),
16
+ };
17
+ const createGardenSchema = z.object({ ...gardenFields, idempotencyKey });
18
+ export function createGarden(client, args) {
19
+ const { idempotencyKey: key, ...body } = args;
20
+ return client.post("/v1/gardens", body, { idempotencyKey: key });
21
+ }
22
+ const listGardensSchema = z.object({
23
+ ids: z.array(z.string()).optional(),
24
+ includeArchived: z.boolean().optional(),
25
+ limit: z.number().int().positive().optional(),
26
+ });
27
+ export function listGardens(client, args) {
28
+ return client.get("/v1/gardens", {
29
+ ids: args.ids?.length ? args.ids.join(",") : undefined,
30
+ includeArchived: args.includeArchived,
31
+ limit: args.limit,
32
+ });
33
+ }
34
+ const getGardenSchema = z.object({ id: z.string() });
35
+ export function getGarden(client, args) {
36
+ return client.get(`/v1/gardens/${args.id}`);
37
+ }
38
+ const updateGardenSchema = z.object({
39
+ id: z.string(),
40
+ name: z.string().optional(),
41
+ notes: z.string().optional(),
42
+ context: z.string().optional(),
43
+ color: z.string().optional(),
44
+ icon: z.string().optional(),
45
+ archived: z.boolean().optional(),
46
+ });
47
+ export function updateGarden(client, args) {
48
+ const { id, ...patch } = args;
49
+ return client.patch(`/v1/gardens/${id}`, patch);
50
+ }
51
+ const deleteGardenSchema = z.object({ id: z.string() });
52
+ export function deleteGarden(client, args) {
53
+ return client.del(`/v1/gardens/${args.id}`);
54
+ }
55
+ export function registerGardenTools(server, client) {
56
+ server.registerTool("create_garden", {
57
+ title: "Create garden",
58
+ description: "Create a life-domain garden.",
59
+ inputSchema: createGardenSchema.shape,
60
+ }, (args) => runTool(() => createGarden(client, args)));
61
+ server.registerTool("list_gardens", {
62
+ title: "List gardens",
63
+ description: "List gardens, or multi-get by ids.",
64
+ inputSchema: listGardensSchema.shape,
65
+ }, (args) => runTool(() => listGardens(client, args)));
66
+ server.registerTool("get_garden", {
67
+ title: "Get garden",
68
+ description: "Fetch one garden by id (incl. Markdown context).",
69
+ inputSchema: getGardenSchema.shape,
70
+ }, (args) => runTool(() => getGarden(client, args)));
71
+ server.registerTool("update_garden", {
72
+ title: "Update garden",
73
+ description: "Patch garden fields (name, context, color, ...).",
74
+ inputSchema: updateGardenSchema.shape,
75
+ }, (args) => runTool(() => updateGarden(client, args)));
76
+ server.registerTool("delete_garden", {
77
+ title: "Delete garden",
78
+ description: "Soft-delete (archive) a garden.",
79
+ inputSchema: deleteGardenSchema.shape,
80
+ }, (args) => runTool(() => deleteGarden(client, args)));
81
+ }
82
+ //# sourceMappingURL=gardens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gardens.js","sourceRoot":"","sources":["../../src/tools/gardens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { registerAiTools } from "./ai.js";
2
+ import { registerGardenTools } from "./gardens.js";
3
+ import { registerKeyTools } from "./keys.js";
4
+ import { registerListTools } from "./lists.js";
5
+ import { registerProjectTools } from "./projects.js";
6
+ import { registerTagTools } from "./tags.js";
7
+ import { registerTaskTools } from "./tasks.js";
8
+ import { registerUiTools } from "./ui.js";
9
+ import { registerViewTools } from "./views.js";
10
+ export function registerAllTools(server, client) {
11
+ registerTaskTools(server, client);
12
+ registerProjectTools(server, client);
13
+ registerGardenTools(server, client);
14
+ registerTagTools(server, client);
15
+ registerListTools(server, client);
16
+ registerViewTools(server, client);
17
+ registerAiTools(server, client);
18
+ registerUiTools(server, client);
19
+ registerKeyTools(server, client);
20
+ }
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAuB;IACzE,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC"}
@@ -0,0 +1,56 @@
1
+ // Key-management tools (require the configured key to hold `keys:manage`; calls
2
+ // otherwise come back as a 403 tool error). create/rotate return the plaintext
3
+ // secret ONCE - it is never retrievable again. A key can only grant scopes it
4
+ // itself holds (no privilege escalation, enforced server-side).
5
+ import { z } from "zod";
6
+ import { runTool } from "../result.js";
7
+ const createKeySchema = z.object({
8
+ name: z.string(),
9
+ scopes: z
10
+ .array(z.string())
11
+ .describe("e.g. tasks:read, tasks:write, reviews:*, ai:invoke, * (owner)"),
12
+ clientType: z.enum(["cli", "mcp", "web", "integration"]).optional(),
13
+ rateLimit: z
14
+ .object({
15
+ perMin: z.number().int().positive().optional(),
16
+ aiPerMin: z.number().int().positive().optional(),
17
+ concurrency: z.number().int().positive().optional(),
18
+ })
19
+ .optional(),
20
+ });
21
+ export function createKey(client, args) {
22
+ return client.post("/v1/keys", args);
23
+ }
24
+ export function listKeys(client) {
25
+ return client.get("/v1/keys");
26
+ }
27
+ const keyIdSchema = z.object({ id: z.string() });
28
+ export function rotateKey(client, args) {
29
+ return client.post(`/v1/keys/${args.id}/rotate`);
30
+ }
31
+ export function revokeKey(client, args) {
32
+ return client.del(`/v1/keys/${args.id}`);
33
+ }
34
+ export function registerKeyTools(server, client) {
35
+ server.registerTool("create_key", {
36
+ title: "Create API key",
37
+ description: "Mint an API key (secret shown once). Cannot grant scopes the calling key lacks.",
38
+ inputSchema: createKeySchema.shape,
39
+ }, (args) => runTool(() => createKey(client, args)));
40
+ server.registerTool("list_keys", {
41
+ title: "List API keys",
42
+ description: "List the vault's API keys (secrets are never returned).",
43
+ inputSchema: {},
44
+ }, () => runTool(() => listKeys(client)));
45
+ server.registerTool("rotate_key", {
46
+ title: "Rotate API key",
47
+ description: "Issue a new secret for a key and revoke the old one.",
48
+ inputSchema: keyIdSchema.shape,
49
+ }, (args) => runTool(() => rotateKey(client, args)));
50
+ server.registerTool("revoke_key", {
51
+ title: "Revoke API key",
52
+ description: "Soft-revoke an API key.",
53
+ inputSchema: keyIdSchema.shape,
54
+ }, (args) => runTool(() => revokeKey(client, args)));
55
+ }
56
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../../src/tools/keys.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,66 @@
1
+ import { z } from "zod";
2
+ import { runTool } from "../result.js";
3
+ import { priorityEnum, statusEnum, whenEnum } from "./schemas.js";
4
+ const filtersSchema = z
5
+ .object({
6
+ q: z.string().optional().describe("Substring text filter"),
7
+ status: z.array(statusEnum).optional(),
8
+ priority: z.array(priorityEnum).optional(),
9
+ when: z.array(whenEnum).optional(),
10
+ gardenId: z.string().optional(),
11
+ tagIds: z.array(z.string()).optional(),
12
+ includeCanceled: z.boolean().optional(),
13
+ sort: z.string().optional(),
14
+ })
15
+ .describe("Task-list filters, same shape list_tasks accepts");
16
+ const listSavedListsSchema = z.object({
17
+ ids: z.array(z.string()).optional().describe("Multi-get by id"),
18
+ });
19
+ export function listSavedLists(client, args) {
20
+ return client.get("/v1/lists", {
21
+ ids: args.ids?.length ? args.ids.join(",") : undefined,
22
+ });
23
+ }
24
+ const createSavedListSchema = z.object({
25
+ name: z.string(),
26
+ filters: filtersSchema.optional(),
27
+ });
28
+ export function createSavedList(client, args) {
29
+ return client.post("/v1/lists", { name: args.name, filters: args.filters ?? {} });
30
+ }
31
+ const updateSavedListSchema = z.object({
32
+ id: z.string(),
33
+ name: z.string().optional(),
34
+ filters: filtersSchema.optional(),
35
+ });
36
+ export function updateSavedList(client, args) {
37
+ const { id, ...patch } = args;
38
+ return client.patch(`/v1/lists/${id}`, patch);
39
+ }
40
+ const deleteSavedListSchema = z.object({ id: z.string() });
41
+ export function deleteSavedList(client, args) {
42
+ return client.del(`/v1/lists/${args.id}`);
43
+ }
44
+ export function registerListTools(server, client) {
45
+ server.registerTool("list_saved_lists", {
46
+ title: "List saved lists",
47
+ description: "List saved smart lists, or multi-get by ids.",
48
+ inputSchema: listSavedListsSchema.shape,
49
+ }, (args) => runTool(() => listSavedLists(client, args)));
50
+ server.registerTool("create_saved_list", {
51
+ title: "Create saved list",
52
+ description: "Save a named set of task-list filters.",
53
+ inputSchema: createSavedListSchema.shape,
54
+ }, (args) => runTool(() => createSavedList(client, args)));
55
+ server.registerTool("update_saved_list", {
56
+ title: "Update saved list",
57
+ description: "Rename a saved list or replace its filters.",
58
+ inputSchema: updateSavedListSchema.shape,
59
+ }, (args) => runTool(() => updateSavedList(client, args)));
60
+ server.registerTool("delete_saved_list", {
61
+ title: "Delete saved list",
62
+ description: "Delete a saved list.",
63
+ inputSchema: deleteSavedListSchema.shape,
64
+ }, (args) => runTool(() => deleteSavedList(client, args)));
65
+ }
66
+ //# sourceMappingURL=lists.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lists.js","sourceRoot":"","sources":["../../src/tools/lists.ts"],"names":[],"mappings":"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"}