@edda-business/mcp 0.66.0 → 0.67.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/package.json +1 -1
- package/src/server.js +44 -4
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -197,6 +197,43 @@ export function createServer() {
|
|
|
197
197
|
|
|
198
198
|
// EfB read-only seat mode stops here: tools/list is exactly search + read, and the write
|
|
199
199
|
// tools below don't exist for the seat at all (unavailable, not merely rejected).
|
|
200
|
+
// ===========================================================================
|
|
201
|
+
// TOOL: orientation — GET /v2/company/orientation
|
|
202
|
+
// The served hot-cache: what is active right now, before you search.
|
|
203
|
+
// ===========================================================================
|
|
204
|
+
server.tool(
|
|
205
|
+
"orientation",
|
|
206
|
+
"START HERE at the beginning of a session: one cheap call that answers 'what is active in " +
|
|
207
|
+
"this company right now?' — each project with its status and its Current-state excerpt " +
|
|
208
|
+
"(from the project's index.md), the most recently updated pages, and how many items wait in " +
|
|
209
|
+
"the Inbox. Use it to orient BEFORE searching; then open the relevant project's index.md or " +
|
|
210
|
+
"search for specifics.",
|
|
211
|
+
{},
|
|
212
|
+
async () => {
|
|
213
|
+
try {
|
|
214
|
+
const r = await get("/v2/company/orientation");
|
|
215
|
+
const lines = [];
|
|
216
|
+
const projects = r?.projects ?? [];
|
|
217
|
+
lines.push(`Active projects (${projects.length}):`);
|
|
218
|
+
for (const p of projects) {
|
|
219
|
+
lines.push(`\n• ${p.name}${p.status ? ` [${p.status}]` : ""}`);
|
|
220
|
+
lines.push(p.current_state ? ` ${p.current_state.replace(/\n/g, "\n ")}` : " (no current-state entries yet)");
|
|
221
|
+
}
|
|
222
|
+
const recent = r?.recent_pages ?? [];
|
|
223
|
+
if (recent.length) {
|
|
224
|
+
lines.push(`\nRecently updated:`);
|
|
225
|
+
for (const pg of recent) lines.push(` · ${[pg.folder, pg.name].filter(Boolean).join("/")} (${String(pg.updated_at).slice(0, 10)})`);
|
|
226
|
+
}
|
|
227
|
+
lines.push(`\nInbox: ${r?.inbox_pending ?? 0} item(s) waiting.`);
|
|
228
|
+
return text(lines.join("\n"));
|
|
229
|
+
} catch (e) {
|
|
230
|
+
const msg = String(e?.message || e);
|
|
231
|
+
if (msg.includes("(404)")) return text("Orientation isn't available on this company's server yet — fall back to search.");
|
|
232
|
+
throw e;
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
);
|
|
236
|
+
|
|
200
237
|
if (readOnly) return server;
|
|
201
238
|
|
|
202
239
|
// ===========================================================================
|
|
@@ -213,7 +250,9 @@ export function createServer() {
|
|
|
213
250
|
"itself (on the next reconcile). You may optionally `suggest` a destination as a hint. Use " +
|
|
214
251
|
"this to promote a finished note from your own work into the shared company brain. Only stage " +
|
|
215
252
|
"what the person has approved sharing — this leaves their private vault. (Their private files " +
|
|
216
|
-
"stay on their disk; this is the shared company layer.)"
|
|
253
|
+
"stay on their disk; this is the shared company layer.) This stages PAGES (content) only — " +
|
|
254
|
+
"NEVER folders: if the person asks to create a folder, call `create` instead; folder creation " +
|
|
255
|
+
"is direct and immediate, it does not go through the Inbox.",
|
|
217
256
|
{
|
|
218
257
|
name: z.string().describe("File/page name, e.g. 'MCP Overview EFB'. A '.md' suffix is added if missing."),
|
|
219
258
|
content: z.string().describe("The full markdown content of the item to share."),
|
|
@@ -322,9 +361,10 @@ export function createServer() {
|
|
|
322
361
|
"are FIXED (Company · Projects · Decisions · Companies · People · Raw Documents · Archive) — you " +
|
|
323
362
|
"cannot add new ones. A bare name (or a path not starting with a fixed folder) becomes a PROJECT " +
|
|
324
363
|
"under Projects: 'Agency' → Projects/Agency. To nest under a specific top-level folder, start the " +
|
|
325
|
-
"path with it, e.g. 'Company/Policies' or 'Projects/Data Centre/Specs'.
|
|
326
|
-
"
|
|
327
|
-
"
|
|
364
|
+
"path with it, e.g. 'Company/Policies' or 'Projects/Data Centre/Specs'. When the person asks to " +
|
|
365
|
+
"create a folder, ALWAYS call this tool directly — never stage a folder request into the Inbox " +
|
|
366
|
+
"(the Inbox is for page content only). A write role is required; the folder appears immediately, " +
|
|
367
|
+
"and you can suggest it as a destination when you submit_company_candidate. Returns the folder id.",
|
|
328
368
|
{ path: z.string().describe("Folder name or path. A bare name → a project under Projects; 'Top-Level/Sub' nests under a fixed top-level folder.") },
|
|
329
369
|
async ({ path }) => {
|
|
330
370
|
try {
|