@markmnl/fmsg-mcp 1.4.0 → 1.4.1
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/CHANGELOG.md +3 -0
- package/dist/build-info.json +3 -3
- package/dist/tools/common.js +4 -1
- package/dist/tools/download.js +1 -1
- package/dist/tools/draft.js +2 -2
- package/dist/tools/read.js +1 -1
- package/dist/tools/send.js +2 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
- Mailbox tools set `openWorldHint: false` (inbox, threads, drafts, mark read, attachment URLs).
|
|
6
|
+
`react` is `destructiveHint: true` because a reaction message cannot be recalled, so a host may ask
|
|
7
|
+
before one. `indicate` stays non-destructive. Sends to other addresses stay open-world and destructive.
|
|
5
8
|
- FMSG-006 indicators. The new `indicate` tool shows the other participants of a message a short-lived
|
|
6
9
|
status such as ⏳ or ✍️, refreshed at half its ttl (every 1–30 s) and cleared when the agent replies in
|
|
7
10
|
that thread, reacts, marks it read, after 5 minutes, or when the session ends; an empty emoji clears it
|
package/dist/build-info.json
CHANGED
package/dist/tools/common.js
CHANGED
|
@@ -4,7 +4,10 @@ import { toolError } from "../errors.js";
|
|
|
4
4
|
import { OAuthRequestError } from "../oauth/errors.js";
|
|
5
5
|
import { FmsgHttpError } from "../client/client.js";
|
|
6
6
|
import { UNTRUSTED_CONTENT_NOTICE, attachmentType, headerValue, isoTime, preview, sortAttachments } from "../render.js";
|
|
7
|
-
|
|
7
|
+
// Mailbox reads stay inside the signed-in address, so openWorldHint is false.
|
|
8
|
+
// Hosts that treat open-world tools as reaching arbitrary other parties otherwise
|
|
9
|
+
// flag an inbox read. SENDS stays open-world: a send can reach any fmsg address.
|
|
10
|
+
export const READ_ONLY = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
8
11
|
export const SENDS = { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true };
|
|
9
12
|
export const idSchema = z.string().regex(/^[0-9]+$/u, "fmsg message ids are decimal integers").describe("fmsg message id");
|
|
10
13
|
/**
|
package/dist/tools/download.js
CHANGED
|
@@ -105,7 +105,7 @@ export const registerDownloadTool = (server, deps) => {
|
|
|
105
105
|
content_type: z.string().regex(/^[\x20-\x7e]+$/u).optional().describe("inferred from the filename when omitted"),
|
|
106
106
|
}),
|
|
107
107
|
outputSchema: outputObject({ draft_id: z.string(), filename: z.string(), ...presignedOutput.shape }),
|
|
108
|
-
annotations: { ...SENDS, destructiveHint: false },
|
|
108
|
+
annotations: { ...SENDS, destructiveHint: false, openWorldHint: false },
|
|
109
109
|
}, async ({ id, filename, size, sha256, content_type }, ctx) => withCaller(deps, ctx, async (caller, signal) => {
|
|
110
110
|
const draft = await caller.client.getMessage(id, signal);
|
|
111
111
|
if (draft.time !== null && draft.time !== undefined)
|
package/dist/tools/draft.js
CHANGED
|
@@ -51,7 +51,7 @@ export const registerDraftTools = (server, deps) => {
|
|
|
51
51
|
next: z.string(),
|
|
52
52
|
hint: hintOutput,
|
|
53
53
|
}),
|
|
54
|
-
annotations: { ...SENDS, destructiveHint: false },
|
|
54
|
+
annotations: { ...SENDS, destructiveHint: false, openWorldHint: false },
|
|
55
55
|
}, async ({ to, topic, reply_to, body, type, important, no_reply, allow_no_reply, include_owner, attachments }, ctx) => {
|
|
56
56
|
if (reply_to && topic)
|
|
57
57
|
return toolError("a reply has no topic: pass topic only for a new message");
|
|
@@ -151,7 +151,7 @@ export const registerDraftTools = (server, deps) => {
|
|
|
151
151
|
description: "Delete an unsent draft and its attachments. Sent messages cannot be deleted.",
|
|
152
152
|
inputSchema: z.strictObject({ id: idSchema.describe("the draft to delete") }),
|
|
153
153
|
outputSchema: outputObject({ id: z.string(), deleted: z.boolean() }),
|
|
154
|
-
annotations: { ...SENDS, idempotentHint: true },
|
|
154
|
+
annotations: { ...SENDS, idempotentHint: true, openWorldHint: false },
|
|
155
155
|
}, async ({ id }, ctx) => withCaller(deps, ctx, async (caller, signal) => {
|
|
156
156
|
const draft = await caller.client.getMessage(id, signal);
|
|
157
157
|
if (draft.time !== null && draft.time !== undefined)
|
package/dist/tools/read.js
CHANGED
|
@@ -166,7 +166,7 @@ export const registerReadTools = (server, deps) => {
|
|
|
166
166
|
marked: z.array(outputObject({ id: z.string(), time_read: z.string().nullable() })),
|
|
167
167
|
failed: z.array(outputObject({ id: z.string(), error: z.string() })),
|
|
168
168
|
}),
|
|
169
|
-
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint:
|
|
169
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
170
170
|
}, async ({ ids }, ctx) => withCaller(deps, ctx, async (caller, signal) => {
|
|
171
171
|
deps.indicators.handled(caller, ids);
|
|
172
172
|
const marked = [];
|
package/dist/tools/send.js
CHANGED
|
@@ -245,7 +245,8 @@ export const registerSendTools = (server, deps) => {
|
|
|
245
245
|
emoji: z.string().max(32).nullable().describe("a single emoji; null or empty clears your reaction"),
|
|
246
246
|
}),
|
|
247
247
|
outputSchema: outputObject({ id: z.string(), reaction_id: z.string().nullable(), time: z.string().nullable(), cleared: z.boolean() }),
|
|
248
|
-
|
|
248
|
+
// A reaction is itself a message and cannot be recalled, so it stays destructive.
|
|
249
|
+
annotations: { ...SENDS, idempotentHint: true },
|
|
249
250
|
}, async ({ id, emoji }, ctx) => withCaller(deps, ctx, async (caller, signal) => {
|
|
250
251
|
const value = emoji && emoji.trim() ? emoji.trim() : null;
|
|
251
252
|
const result = await caller.client.react(id, value, signal);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@markmnl/fmsg-mcp",
|
|
3
3
|
"mcpName": "io.github.markmnl/fmsg-mcp",
|
|
4
|
-
"version": "1.4.
|
|
4
|
+
"version": "1.4.1",
|
|
5
5
|
"description": "MCP server for fmsg: send and receive federated messages from any AI agent via a deployed fmsg Web API",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
"url": "https://github.com/markmnl/fmsg-mcp",
|
|
9
9
|
"source": "github"
|
|
10
10
|
},
|
|
11
|
-
"version": "1.4.
|
|
11
|
+
"version": "1.4.1",
|
|
12
12
|
"packages": [
|
|
13
13
|
{
|
|
14
14
|
"registryType": "npm",
|
|
15
15
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
16
16
|
"identifier": "@markmnl/fmsg-mcp",
|
|
17
|
-
"version": "1.4.
|
|
17
|
+
"version": "1.4.1",
|
|
18
18
|
"transport": {
|
|
19
19
|
"type": "stdio"
|
|
20
20
|
},
|