@cpenned/mcp 0.10.0 → 0.12.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 +30 -6
- package/dist/apps.js +109 -0
- package/dist/apps.js.map +1 -0
- package/dist/open.js +94 -0
- package/dist/open.js.map +1 -0
- package/dist/server.js +21 -5
- package/dist/server.js.map +1 -1
- package/dist/tools/index.js +0 -2
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ui.js +4 -37
- package/dist/tools/ui.js.map +1 -1
- package/dist-ui/activity.html +768 -0
- package/dist-ui/agenda.html +773 -0
- package/dist-ui/board.html +778 -0
- package/dist-ui/book.html +770 -0
- package/dist-ui/calendar.html +768 -0
- package/dist-ui/habits.html +773 -0
- package/dist-ui/person.html +769 -0
- package/dist-ui/reading.html +768 -0
- package/dist-ui/receipt.html +772 -0
- package/dist-ui/reviews.html +771 -0
- package/dist-ui/task.html +776 -0
- package/dist-ui/triage.html +774 -0
- package/package.json +6 -4
- package/skills/open-brain-mcp/SKILL.md +14 -4
package/README.md
CHANGED
|
@@ -102,8 +102,8 @@ Point the `args` at the absolute `packages/mcp/dist/index.js` path with
|
|
|
102
102
|
`add_person_links`/`remove_person_links` (link people to tasks, projects,
|
|
103
103
|
gardens, and other people — person-to-person connections are symmetric and
|
|
104
104
|
take an optional label like "spouse", plus `readingListItemIds` and
|
|
105
|
-
`habitIds` on either side). People with an elapsed contact cadence appear in
|
|
106
|
-
|
|
105
|
+
`habitIds` on either side). People with an elapsed contact cadence appear in
|
|
106
|
+
`get_reviews`; `list_tasks` filters by `person` ids.
|
|
107
107
|
- **Reading list**: `create_reading_item` (only `url` is required; title/
|
|
108
108
|
description are fetched from the page in the background), `list_reading_items`,
|
|
109
109
|
`get_reading_item`, `update_reading_item` (drives status
|
|
@@ -170,10 +170,34 @@ Point the `args` at the absolute `packages/mcp/dist/index.js` path with
|
|
|
170
170
|
deadlines resolve against. `yearlyBookGoal` sets the reading-challenge
|
|
171
171
|
target (books finished this calendar year); `null` clears it.
|
|
172
172
|
- **AI**: `find_tasks` (hybrid search), `ai_triage` (brain-dump triage).
|
|
173
|
-
- **
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
- **Interactive cards (MCP Apps)**: in hosts that support
|
|
174
|
+
[MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) (Claude
|
|
175
|
+
desktop and web, ChatGPT, VS Code), these tools render a card in the chat
|
|
176
|
+
alongside their normal JSON:
|
|
177
|
+
|
|
178
|
+
| Tool | Card | Actions |
|
|
179
|
+
| --- | --- | --- |
|
|
180
|
+
| `get_task`, `create_task`, `update_task` | Task | Done / Reopen, Defer to tomorrow, Open |
|
|
181
|
+
| `get_view`, `list_tasks`, `find_tasks` | Task list (view, filter or search) | Tick to complete |
|
|
182
|
+
| `create_tasks` | Created tasks | Undo, Undo all |
|
|
183
|
+
| `ai_triage` | Captured tasks, habits, reading, books + questions | Undo, Undo all, reply to a question |
|
|
184
|
+
| `get_reviews` | Review queue | Reviewed, Contacted |
|
|
185
|
+
| `list_habits` | Habits with streaks and progress | Tick to check in / undo today |
|
|
186
|
+
| `review_garden` | Garden board (status columns) | Tick to complete |
|
|
187
|
+
| `get_person`, `create_person`, `update_person`, `mark_contacted` | Person | Contacted today |
|
|
188
|
+
| `get_book`, `create_book`, `update_book` | Book with page progress | Start reading, Mark finished |
|
|
189
|
+
| `get_reading_item`, `create_reading_item`, `update_reading_item` | Reading item | Mark read / unread, Open article |
|
|
190
|
+
| `get_strava_activity`, `update_strava_activity` | Activity stats | |
|
|
191
|
+
| `list_calendar_events` | Events by day | Open event, open linked task |
|
|
192
|
+
|
|
193
|
+
Titles and Open buttons open the item in the Open Brain Mac app when it is
|
|
194
|
+
installed (`openbrain://` links; activities always use the web), otherwise in
|
|
195
|
+
the web app (its address comes from
|
|
196
|
+
`GET /v1/profile`'s `webUrl`, which needs `settings:read`). Card buttons call
|
|
197
|
+
the normal tools, so they need the same scopes, and each action is reported
|
|
198
|
+
back to the model. Clients without MCP Apps support (Claude Code, the CLI)
|
|
199
|
+
ignore the cards and read the same JSON as before. The old inline `ui_*`
|
|
200
|
+
tools were removed in favor of these cards.
|
|
177
201
|
- **Mind Meld** (shared gardens, guest side - sharing/invites/revoke are
|
|
178
202
|
web-app-only): `list_shares` (gardens shared with the caller: capabilities,
|
|
179
203
|
owner, participants - empty unless the key has `includeGrants`),
|
package/dist/apps.js
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// MCP Apps: interactive cards that UI-capable hosts (Claude, ChatGPT, VS Code)
|
|
2
|
+
// render in place of a tool's JSON. Each card is a static HTML resource built
|
|
3
|
+
// from ui/ into dist-ui/ (scripts/build-ui.mjs); the host feeds it the tool's
|
|
4
|
+
// input and result, and its buttons call back into the regular tools. Clients
|
|
5
|
+
// without UI support ignore the metadata and keep reading the JSON text.
|
|
6
|
+
import { readFile } from "node:fs/promises";
|
|
7
|
+
import { RESOURCE_MIME_TYPE, RESOURCE_URI_META_KEY, registerAppResource, } from "@modelcontextprotocol/ext-apps/server";
|
|
8
|
+
export const APP_CARDS = {
|
|
9
|
+
task: {
|
|
10
|
+
title: "Task card",
|
|
11
|
+
description: "One task with Done / Reopen / Defer to tomorrow actions.",
|
|
12
|
+
},
|
|
13
|
+
agenda: {
|
|
14
|
+
title: "Task list card",
|
|
15
|
+
description: "A view, filtered list or search of tasks with check-to-complete rows.",
|
|
16
|
+
},
|
|
17
|
+
receipt: {
|
|
18
|
+
title: "Created tasks card",
|
|
19
|
+
description: "What a batch create made, with per-task and bulk Undo.",
|
|
20
|
+
},
|
|
21
|
+
reviews: {
|
|
22
|
+
title: "Review queue card",
|
|
23
|
+
description: "Tasks and projects due for review and people to reach out to.",
|
|
24
|
+
},
|
|
25
|
+
habits: {
|
|
26
|
+
title: "Habits card",
|
|
27
|
+
description: "Habits with streaks and progress; tick to check in for today.",
|
|
28
|
+
},
|
|
29
|
+
board: {
|
|
30
|
+
title: "Garden board card",
|
|
31
|
+
description: "A garden's open tasks in status columns, plus its projects.",
|
|
32
|
+
},
|
|
33
|
+
triage: {
|
|
34
|
+
title: "Triage card",
|
|
35
|
+
description: "What a brain-dump triage captured, with Undo and open questions.",
|
|
36
|
+
},
|
|
37
|
+
person: {
|
|
38
|
+
title: "Person card",
|
|
39
|
+
description: "A person from your CRM with contact cadence and Contacted today.",
|
|
40
|
+
},
|
|
41
|
+
book: {
|
|
42
|
+
title: "Book card",
|
|
43
|
+
description: "A book with reading progress and Start / Finish actions.",
|
|
44
|
+
},
|
|
45
|
+
reading: {
|
|
46
|
+
title: "Reading item card",
|
|
47
|
+
description: "A saved article with Mark read and Open article.",
|
|
48
|
+
},
|
|
49
|
+
activity: {
|
|
50
|
+
title: "Activity card",
|
|
51
|
+
description: "A Strava activity's stats: distance, time, pace, elevation.",
|
|
52
|
+
},
|
|
53
|
+
calendar: {
|
|
54
|
+
title: "Calendar card",
|
|
55
|
+
description: "Calendar events grouped by day, with linked tasks.",
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
export const cardUri = (card) => `ui://open-brain/${card}.html`;
|
|
59
|
+
export const TOOL_CARDS = {
|
|
60
|
+
get_task: "task",
|
|
61
|
+
create_task: "task",
|
|
62
|
+
update_task: "task",
|
|
63
|
+
get_view: "agenda",
|
|
64
|
+
list_tasks: "agenda",
|
|
65
|
+
find_tasks: "agenda",
|
|
66
|
+
create_tasks: "receipt",
|
|
67
|
+
get_reviews: "reviews",
|
|
68
|
+
list_habits: "habits",
|
|
69
|
+
review_garden: "board",
|
|
70
|
+
ai_triage: "triage",
|
|
71
|
+
get_person: "person",
|
|
72
|
+
create_person: "person",
|
|
73
|
+
update_person: "person",
|
|
74
|
+
mark_contacted: "person",
|
|
75
|
+
get_book: "book",
|
|
76
|
+
create_book: "book",
|
|
77
|
+
update_book: "book",
|
|
78
|
+
get_reading_item: "reading",
|
|
79
|
+
create_reading_item: "reading",
|
|
80
|
+
update_reading_item: "reading",
|
|
81
|
+
get_strava_activity: "activity",
|
|
82
|
+
update_strava_activity: "activity",
|
|
83
|
+
list_calendar_events: "calendar",
|
|
84
|
+
};
|
|
85
|
+
// Both the current key and the legacy flat key, as registerAppTool emits them.
|
|
86
|
+
export function cardMeta(toolName) {
|
|
87
|
+
const card = TOOL_CARDS[toolName];
|
|
88
|
+
if (!card)
|
|
89
|
+
return undefined;
|
|
90
|
+
const uri = cardUri(card);
|
|
91
|
+
return { ui: { resourceUri: uri }, [RESOURCE_URI_META_KEY]: uri };
|
|
92
|
+
}
|
|
93
|
+
// src/apps.ts and dist/apps.js both sit one level under the package root.
|
|
94
|
+
const UI_DIR = new URL("../dist-ui/", import.meta.url);
|
|
95
|
+
export function registerAppCards(server) {
|
|
96
|
+
for (const [card, { title, description }] of Object.entries(APP_CARDS)) {
|
|
97
|
+
const uri = cardUri(card);
|
|
98
|
+
registerAppResource(server, title, uri, { description, mimeType: RESOURCE_MIME_TYPE }, async () => ({
|
|
99
|
+
contents: [
|
|
100
|
+
{
|
|
101
|
+
uri,
|
|
102
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
103
|
+
text: await readFile(new URL(`${card}.html`, UI_DIR), "utf8"),
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=apps.js.map
|
package/dist/apps.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../src/apps.ts"],"names":[],"mappings":"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"}
|
package/dist/open.js
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
// "Open" from a card: prefer the native app (openbrain:// deep link, handled by
|
|
2
|
+
// the macOS app) and fall back to the web app. The stdio server runs on the
|
|
3
|
+
// user's own machine, so it can launch either itself; a hosted server can't,
|
|
4
|
+
// and hands the web URL back for the card to open through the host.
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { runTool } from "./result.js";
|
|
8
|
+
import { idField } from "./tools/schemas.js";
|
|
9
|
+
export const systemOpener = (url) => {
|
|
10
|
+
const command = process.platform === "darwin"
|
|
11
|
+
? "open"
|
|
12
|
+
: process.platform === "linux"
|
|
13
|
+
? "xdg-open"
|
|
14
|
+
: undefined;
|
|
15
|
+
if (!command)
|
|
16
|
+
return Promise.resolve(false);
|
|
17
|
+
return new Promise((resolve) => {
|
|
18
|
+
execFile(command, [url], (error) => resolve(!error));
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
export const openKindEnum = z.enum([
|
|
22
|
+
"task",
|
|
23
|
+
"project",
|
|
24
|
+
"garden",
|
|
25
|
+
"habit",
|
|
26
|
+
"person",
|
|
27
|
+
"reading",
|
|
28
|
+
"book",
|
|
29
|
+
"activity",
|
|
30
|
+
]);
|
|
31
|
+
// The native apps' DeepLink routes (macOS OpenBrainApp.swift, iOS
|
|
32
|
+
// WidgetLinks.swift); activities have no native page.
|
|
33
|
+
const APP_PATH = {
|
|
34
|
+
task: (id) => `task/${id}`,
|
|
35
|
+
project: (id) => `project/${id}`,
|
|
36
|
+
garden: (id) => `garden/${id}`,
|
|
37
|
+
habit: (id) => `habit/${id}`,
|
|
38
|
+
person: (id) => `person/${id}`,
|
|
39
|
+
reading: (id) => `reading/${id}`,
|
|
40
|
+
book: (id) => `book/${id}`,
|
|
41
|
+
activity: () => undefined,
|
|
42
|
+
};
|
|
43
|
+
// packages/web/src/routes/_authed: task.$taskId, habits_.$habitId, ...
|
|
44
|
+
const WEB_PATH = {
|
|
45
|
+
task: "task",
|
|
46
|
+
project: "project",
|
|
47
|
+
garden: "garden",
|
|
48
|
+
habit: "habits",
|
|
49
|
+
person: "person",
|
|
50
|
+
reading: "reading",
|
|
51
|
+
book: "books",
|
|
52
|
+
activity: "activities",
|
|
53
|
+
};
|
|
54
|
+
export function appUrl(kind, id) {
|
|
55
|
+
const path = APP_PATH[kind](id);
|
|
56
|
+
return path ? `openbrain://${path}` : undefined;
|
|
57
|
+
}
|
|
58
|
+
export function webUrl(origin, kind, id) {
|
|
59
|
+
return `${origin.replace(/\/+$/, "")}/${WEB_PATH[kind]}/${encodeURIComponent(id)}`;
|
|
60
|
+
}
|
|
61
|
+
const openItemSchema = z.object({ kind: openKindEnum, id: idField });
|
|
62
|
+
export function registerOpenTool(server, client, opener) {
|
|
63
|
+
let origin;
|
|
64
|
+
const webOrigin = () => {
|
|
65
|
+
origin ??= client
|
|
66
|
+
.get("/v1/profile")
|
|
67
|
+
.then(({ webUrl }) => {
|
|
68
|
+
if (!webUrl)
|
|
69
|
+
throw new Error("This deployment has no web app URL (SITE_URL).");
|
|
70
|
+
return webUrl;
|
|
71
|
+
})
|
|
72
|
+
.catch((error) => {
|
|
73
|
+
origin = undefined;
|
|
74
|
+
throw error;
|
|
75
|
+
});
|
|
76
|
+
return origin;
|
|
77
|
+
};
|
|
78
|
+
async function openItem({ kind, id }) {
|
|
79
|
+
const native = appUrl(kind, id);
|
|
80
|
+
if (opener && native && (await opener(native)))
|
|
81
|
+
return { opened: "app", url: native };
|
|
82
|
+
const url = webUrl(await webOrigin(), kind, id);
|
|
83
|
+
if (opener && (await opener(url)))
|
|
84
|
+
return { opened: "web", url };
|
|
85
|
+
return { opened: null, url };
|
|
86
|
+
}
|
|
87
|
+
server.registerTool("open_item", {
|
|
88
|
+
title: "Open in Open Brain",
|
|
89
|
+
description: "Card-only: open a task, project, garden, habit, person, reading item, book or Strava activity in the Open Brain app, falling back to the web app.",
|
|
90
|
+
inputSchema: openItemSchema.shape,
|
|
91
|
+
_meta: { ui: { visibility: ["app"] } },
|
|
92
|
+
}, (args) => runTool(() => openItem(args)));
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=open.js.map
|
package/dist/open.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../src/open.ts"],"names":[],"mappings":"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"}
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
1
2
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { cardMeta, registerAppCards } from "./apps.js";
|
|
4
|
+
import { registerOpenTool, systemOpener } from "./open.js";
|
|
2
5
|
import { registerAllTools } from "./tools/index.js";
|
|
3
6
|
import { registerSkillTools, skillsStatus } from "./tools/skills.js";
|
|
4
7
|
// Surfaced to the client on initialize. When the bundled skill isn't installed
|
|
@@ -14,7 +17,7 @@ function buildInstructions(localSkills) {
|
|
|
14
17
|
return (`${base} The bundled agent skill (${missing.map((s) => s.name).join(", ")}) is not installed on this machine. ` +
|
|
15
18
|
"Early in the first conversation, offer once to install it with the install_skills tool (a local copy into ~/.claude/skills) so future sessions drive these tools well; respect the user's answer and don't re-offer.");
|
|
16
19
|
}
|
|
17
|
-
const READ_ONLY_TOOL = /^(get|list|find|search
|
|
20
|
+
const READ_ONLY_TOOL = /^(get|list|find|search)_|^review_garden$/;
|
|
18
21
|
const DESTRUCTIVE_TOOL = /^(delete|revoke|rotate|remove)_/;
|
|
19
22
|
// Derived from the tool naming convention so every new tool is annotated
|
|
20
23
|
// without per-registration boilerplate. Unmatched tools keep the SDK defaults.
|
|
@@ -25,15 +28,28 @@ export function toolAnnotations(name) {
|
|
|
25
28
|
return { destructiveHint: true };
|
|
26
29
|
return undefined;
|
|
27
30
|
}
|
|
28
|
-
|
|
31
|
+
// Annotations and MCP App card metadata both key off the tool name, so tool
|
|
32
|
+
// modules stay plain registerTool calls (convex/chat.ts reuses them as-is).
|
|
33
|
+
function decorateRegistrations(server) {
|
|
29
34
|
const register = server.registerTool.bind(server);
|
|
30
|
-
server.registerTool = ((name, config, cb) =>
|
|
35
|
+
server.registerTool = ((name, config, cb) => {
|
|
36
|
+
const meta = cardMeta(name);
|
|
37
|
+
return register(name, {
|
|
38
|
+
...config,
|
|
39
|
+
annotations: { ...toolAnnotations(name), ...config.annotations },
|
|
40
|
+
...(meta ? { _meta: { ...meta, ...config._meta } } : {}),
|
|
41
|
+
}, cb);
|
|
42
|
+
});
|
|
31
43
|
}
|
|
44
|
+
// src/server.ts and dist/server.js both sit one level under package.json.
|
|
45
|
+
export const SERVER_VERSION = createRequire(import.meta.url)("../package.json").version;
|
|
32
46
|
export function createServer(client, options = {}) {
|
|
33
47
|
const localSkills = options.localSkills ?? true;
|
|
34
|
-
const server = new McpServer({ name: "open-brain", version:
|
|
35
|
-
|
|
48
|
+
const server = new McpServer({ name: "open-brain", version: SERVER_VERSION }, { instructions: buildInstructions(localSkills) });
|
|
49
|
+
decorateRegistrations(server);
|
|
36
50
|
registerAllTools(server, client);
|
|
51
|
+
registerAppCards(server);
|
|
52
|
+
registerOpenTool(server, client, options.opener ?? (localSkills ? systemOpener : undefined));
|
|
37
53
|
if (localSkills)
|
|
38
54
|
registerSkillTools(server);
|
|
39
55
|
return server;
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.js
CHANGED
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAuB;IACzE,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnC,CAAC"}
|
package/dist/tools/ui.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// defer, reschedule from the UI) are a later sub-stage.
|
|
1
|
+
// Legacy read-only MCPUI resources, returned inline in the tool result. The
|
|
2
|
+
// interactive MCP App cards (src/apps.ts) replace these one at a time: ui_view
|
|
3
|
+
// is now the get_view agenda card.
|
|
5
4
|
import { createUIResource } from "@mcp-ui/server";
|
|
6
5
|
import { z } from "zod";
|
|
7
6
|
import { apiPath } from "../client.js";
|
|
@@ -29,33 +28,6 @@ async function uiResult(uri, html, nextCursor) {
|
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
30
|
const cursorOf = (page) => page.hasMore === false ? null : (page.nextCursor ?? null);
|
|
32
|
-
const VIEW_TITLES = {
|
|
33
|
-
today: "Today",
|
|
34
|
-
upcoming: "Upcoming",
|
|
35
|
-
overdue: "Overdue",
|
|
36
|
-
};
|
|
37
|
-
const viewUiSchema = z.object({
|
|
38
|
-
view: z.enum(["today", "upcoming", "overdue"]),
|
|
39
|
-
tz: z.string().optional(),
|
|
40
|
-
limit: z.number().int().positive().optional(),
|
|
41
|
-
cursor: z.string().optional().describe("Cursor from a previous page"),
|
|
42
|
-
});
|
|
43
|
-
export async function viewUi(client, args) {
|
|
44
|
-
try {
|
|
45
|
-
const data = await client.get(apiPath `/v1/views/${args.view}`, {
|
|
46
|
-
tz: args.tz,
|
|
47
|
-
limit: args.limit,
|
|
48
|
-
cursor: args.cursor,
|
|
49
|
-
});
|
|
50
|
-
const title = VIEW_TITLES[args.view];
|
|
51
|
-
const next = cursorOf(data);
|
|
52
|
-
const html = htmlDoc(title, section(title, data.items ?? []) + moreNote(next));
|
|
53
|
-
return uiResult(`ui://open-brain/view/${args.view}`, html, next);
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
return errorResult(error);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
31
|
const reviewQueueUiSchema = z.object({ gardenId: z.string().optional() });
|
|
60
32
|
export async function reviewQueueUi(client, args) {
|
|
61
33
|
try {
|
|
@@ -109,11 +81,6 @@ export async function habitsUi(client, args) {
|
|
|
109
81
|
}
|
|
110
82
|
}
|
|
111
83
|
export function registerUiTools(server, client) {
|
|
112
|
-
server.registerTool("ui_view", {
|
|
113
|
-
title: "View (UI)",
|
|
114
|
-
description: "Render a computed view (today/upcoming/overdue) as an HTML UI. When the page is cut short the result says so and gives the cursor for the next page.",
|
|
115
|
-
inputSchema: viewUiSchema.shape,
|
|
116
|
-
}, (args) => viewUi(client, args));
|
|
117
84
|
server.registerTool("ui_review_queue", {
|
|
118
85
|
title: "Review queue (UI)",
|
|
119
86
|
description: "Render the due-review queue (tasks + projects + people due for contact) as an HTML UI.",
|
|
@@ -126,7 +93,7 @@ export function registerUiTools(server, client) {
|
|
|
126
93
|
}, (args) => gardenBoardUi(client, args));
|
|
127
94
|
server.registerTool("ui_habits", {
|
|
128
95
|
title: "Habits (UI)",
|
|
129
|
-
description: "Render habits with status, due/progress, and streak metadata as an HTML UI.
|
|
96
|
+
description: "Render habits with status, due/progress, and streak metadata as an HTML UI. Pass cursor for the next page.",
|
|
130
97
|
inputSchema: habitsUiSchema.shape,
|
|
131
98
|
}, (args) => habitsUi(client, args));
|
|
132
99
|
}
|
package/dist/tools/ui.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/tools/ui.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../src/tools/ui.ts"],"names":[],"mappings":"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"}
|