@edda-business/mcp 0.56.0 → 0.57.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 +46 -11
package/package.json
CHANGED
package/src/server.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* Tools, by group (v0.56 — consolidated, Cerebras-style):
|
|
14
14
|
* RETRIEVE search (unified, scope=all|company|personal|notes) · get_context ·
|
|
15
15
|
* get_account · who_knows · query · attention · verify
|
|
16
|
-
* WRITE save_note · save_to_vault · propose_company_file
|
|
16
|
+
* WRITE save_note · save_to_vault · update_vault_file · propose_company_file
|
|
17
17
|
* FIX merge_contacts (action=merge|split)
|
|
18
18
|
* RUN list_integrations · connect_integration
|
|
19
19
|
*
|
|
@@ -26,7 +26,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
26
26
|
import { z } from "zod";
|
|
27
27
|
import { get, post, del } from "./client.js";
|
|
28
28
|
|
|
29
|
-
export const SERVER_VERSION = "0.
|
|
29
|
+
export const SERVER_VERSION = "0.57.0";
|
|
30
30
|
|
|
31
31
|
// ─── helpers ──────────────────────────────────────────────────────────────────
|
|
32
32
|
|
|
@@ -610,7 +610,7 @@ export function createServer() {
|
|
|
610
610
|
},
|
|
611
611
|
async ({ folder, name, content, subfolder }) => {
|
|
612
612
|
const r = await post("/v2/personal/files", { folder, name, content, subfolder });
|
|
613
|
-
return { content: [{ type: "text", text: `
|
|
613
|
+
return { content: [{ type: "text", text: `"${name}" is waiting in your Inbox to approve — once you do, it files into ${r?.folder || folder}.` }] };
|
|
614
614
|
},
|
|
615
615
|
);
|
|
616
616
|
|
|
@@ -800,13 +800,14 @@ export function createServer() {
|
|
|
800
800
|
// ===========================================================================
|
|
801
801
|
server.tool(
|
|
802
802
|
"save_to_vault",
|
|
803
|
-
"Save a file into the MEMBER'S OWN private knowledge vault
|
|
804
|
-
"(inbox, projects, decisions, companies, people,
|
|
805
|
-
"
|
|
806
|
-
"
|
|
807
|
-
"
|
|
808
|
-
"
|
|
809
|
-
"propose_company_file), NOT a note on a
|
|
803
|
+
"Save a file into the MEMBER'S OWN private knowledge vault. It lands in their INBOX for review " +
|
|
804
|
+
"with the target folder you name remembered (inbox, projects, decisions, companies, people, " +
|
|
805
|
+
"resources, archive, thoughts); the member approves it in the app, which files it into that folder " +
|
|
806
|
+
"and makes it searchable. Nothing enters their knowledge without their approval. Use it when the " +
|
|
807
|
+
"member asks you to keep or file something — 'save this to resources', 'put this PDF in projects'. " +
|
|
808
|
+
"Pass markdown/text as `content`, OR a PDF/DOCX as base64 in `file` (extracted to text automatically). " +
|
|
809
|
+
"PRIVATE to the member. NOT the shared company vault (use propose_company_file), NOT a note on a " +
|
|
810
|
+
"contact (use save_note).",
|
|
810
811
|
{
|
|
811
812
|
folder: z.string().describe("The vault folder: inbox | projects | decisions | companies | people | resources | archive | thoughts."),
|
|
812
813
|
name: z.string().describe("The file name, e.g. 'Q3 Plan.md' or 'vendor-contract.pdf'."),
|
|
@@ -818,7 +819,7 @@ export function createServer() {
|
|
|
818
819
|
async ({ folder, name, content, file, mime, subfolder }) => {
|
|
819
820
|
try {
|
|
820
821
|
const r = await post("/v2/personal/files", { folder, name, content, file_base64: file, mime, subfolder });
|
|
821
|
-
return { content: [{ type: "text", text: `
|
|
822
|
+
return { content: [{ type: "text", text: `"${name}" is waiting in your Inbox to approve — once you do, it files into ${r?.folder || folder} and becomes searchable.` }] };
|
|
822
823
|
} catch (e) {
|
|
823
824
|
const msg = String(e?.message || e);
|
|
824
825
|
if (msg.includes("no_text_extracted")) return { content: [{ type: "text", text: `Couldn't read any text from that file — a scanned/image-only PDF has no extractable text. Text, markdown, or a text-based PDF/DOCX works.` }] };
|
|
@@ -828,6 +829,40 @@ export function createServer() {
|
|
|
828
829
|
}
|
|
829
830
|
);
|
|
830
831
|
|
|
832
|
+
// ===========================================================================
|
|
833
|
+
// TOOL: update_vault_file — POST /v2/personal/files/update
|
|
834
|
+
// Edit an existing personal file. Snapshots the old content to version history,
|
|
835
|
+
// then replaces/appends + re-embeds. save_to_vault is for NEW files (→ Inbox);
|
|
836
|
+
// this edits one that's already live.
|
|
837
|
+
// ===========================================================================
|
|
838
|
+
server.tool(
|
|
839
|
+
"update_vault_file",
|
|
840
|
+
"Edit an EXISTING file in the member's own vault — revise it or append to it. Identify the file by " +
|
|
841
|
+
"`file_id` (from a search or save result) or by `path` ('folder/[subfolder/]name.md'). The previous " +
|
|
842
|
+
"content is saved to version history FIRST (never lost), then your new content replaces it — or is added " +
|
|
843
|
+
"to the end with append:true — and the file is re-embedded; the member sees a fresh 'updated' time. Use " +
|
|
844
|
+
"this to keep a living document current: a rolling brief, a spec, a running log. For a NEW file use " +
|
|
845
|
+
"save_to_vault (which lands in the Inbox for approval); this edits one that already exists and is live.",
|
|
846
|
+
{
|
|
847
|
+
file_id: z.string().optional().describe("The file's id (from a search/save result). Provide this OR path."),
|
|
848
|
+
path: z.string().optional().describe("The file's vault path, e.g. 'resources/Edda Architecture.md'. Provide this OR file_id."),
|
|
849
|
+
content: z.string().describe("The new markdown content. Replaces the file's content unless append is true."),
|
|
850
|
+
append: z.boolean().optional().describe("If true, append this to the end of the file instead of replacing it."),
|
|
851
|
+
},
|
|
852
|
+
async ({ file_id, path, content, append }) => {
|
|
853
|
+
try {
|
|
854
|
+
const r = await post("/v2/personal/files/update", { file_id, path, content, append });
|
|
855
|
+
return { content: [{ type: "text", text: r?.note || "Updated the file." }] };
|
|
856
|
+
} catch (e) {
|
|
857
|
+
const msg = String(e?.message || e);
|
|
858
|
+
if (msg.includes("not_found")) return { content: [{ type: "text", text: "Couldn't find that file — check the file_id or path (folder/name.md)." }] };
|
|
859
|
+
if (msg.includes("file_id_or_path_required")) return { content: [{ type: "text", text: "Tell me which file to edit — pass file_id or path." }] };
|
|
860
|
+
if (msg.includes("content_required")) return { content: [{ type: "text", text: "Give me the new content to write." }] };
|
|
861
|
+
throw e;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
);
|
|
865
|
+
|
|
831
866
|
server.tool(
|
|
832
867
|
"list_integrations",
|
|
833
868
|
"List the integrations connected to this workspace (Gmail, HubSpot, Apollo, Instantly, LinkedIn, …) " +
|