@imenam/mcp-messenger 1.0.7 → 1.0.9
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 +24 -1
- package/dist/src/mcp/start.js +21 -1
- package/dist/src/mcp/tools.js +27 -6
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -224,9 +224,19 @@ ont deux boîtes distinctes et ne se volent pas leur courrier.
|
|
|
224
224
|
|
|
225
225
|
### Faire communiquer deux agents
|
|
226
226
|
|
|
227
|
-
|
|
227
|
+
Le plus souvent, il n'y a rien à faire : l'agent B ouvre `list_agents` et y trouve
|
|
228
|
+
l'adresse de A. C'est le chemin normal, et le seul qui ne puisse pas se tromper.
|
|
229
|
+
|
|
230
|
+
Si tu veux désigner toi-même l'interlocuteur :
|
|
231
|
+
|
|
232
|
+
1. Demande son adresse à l'agent A (`whoami`) — il te la donne, c'est à toi qu'elle est due.
|
|
228
233
|
2. Transmets-la à l'agent B, qui l'utilise dans `send_message`.
|
|
229
234
|
|
|
235
|
+
Dans les deux cas, une adresse ne circule jamais **dans** un message : le serveur y attache
|
|
236
|
+
déjà l'expéditeur et le destinataire. Un agent qui recopie une adresse dans un corps de
|
|
237
|
+
message écrit une information que le lecteur a déjà, et qui sera fausse le jour où il se
|
|
238
|
+
trompe de session.
|
|
239
|
+
|
|
230
240
|
Comme les adresses sont opaques, demande aux agents de nommer leur boîte
|
|
231
241
|
(`rename_mailbox`) : le nom apparaît dans `list_agents` et dans la console web, ce
|
|
232
242
|
qui permet de retrouver une adresse perdue.
|
|
@@ -248,6 +258,19 @@ de la boîte seul ne dit pas d'où l'agent écrit. L'annuaire (`list_agents`), `
|
|
|
248
258
|
console web montrent donc toujours les deux, sous la forme `Agent · Boîte`. Renommer la
|
|
249
259
|
boîte ne touche jamais au nom de l'agent.
|
|
250
260
|
|
|
261
|
+
**Un nom d'agent ne désigne personne.** C'est le piège de ce modèle : plusieurs boîtes
|
|
262
|
+
portent le même `agent_name`, une par session lancée depuis la même configuration. Un agent
|
|
263
|
+
qui croise son propre nom d'agent dans l'annuaire regarde une *autre* session du même
|
|
264
|
+
projet, jamais la sienne — sa boîte, elle, n'y figure pas du tout. Seule l'adresse identifie
|
|
265
|
+
une session. Ce rappel est servi à trois endroits, du plus tôt au plus tard : les
|
|
266
|
+
instructions du serveur MCP (reçues à la connexion, avant le premier outil), la ligne qui
|
|
267
|
+
suit `Agent:` dans `whoami`, et le pied de l'annuaire dans `list_agents`.
|
|
268
|
+
|
|
269
|
+
**Les adresses ne se recopient pas à la main.** Le serveur attache l'expéditeur et le
|
|
270
|
+
destinataire à chaque message, et le lecteur les voit dans l'en-tête. Écrire son adresse
|
|
271
|
+
dans le corps n'ajoute rien et se met à mentir dès qu'elle est erronée ou périmée —
|
|
272
|
+
`send_message` le dit dans sa description et dans celle de `body`.
|
|
273
|
+
|
|
251
274
|
### Nommer les boîtes et les fils
|
|
252
275
|
|
|
253
276
|
Les identifiants (`box_…`, `thr_…`) ne disent rien de ce qui se passe. Deux noms en langue
|
package/dist/src/mcp/start.js
CHANGED
|
@@ -8,9 +8,29 @@ import { newId } from "../core/ids.js";
|
|
|
8
8
|
import { logger } from "../logger.js";
|
|
9
9
|
import { APP_VERSION } from "../version.js";
|
|
10
10
|
import { TOOLS, callTool } from "./tools.js";
|
|
11
|
+
/**
|
|
12
|
+
* Ce que l'hôte reçoit à la poignée de main, avant le moindre appel d'outil.
|
|
13
|
+
*
|
|
14
|
+
* Deux confusions coûtent cher et n'apparaissent qu'au moment d'écrire, trop tard : croire
|
|
15
|
+
* que le nom d'agent désigne une session (il est partagé par toutes celles du projet), et
|
|
16
|
+
* recopier une adresse dans le corps d'un message (le serveur la pose déjà, la copie ment
|
|
17
|
+
* dès qu'elle vieillit). Les dire ici, c'est les dire avant l'erreur.
|
|
18
|
+
*/
|
|
19
|
+
const INSTRUCTIONS = `mcp-messenger gives this session a mailbox and lets it exchange messages with other agent sessions.
|
|
20
|
+
|
|
21
|
+
Who you are, and who the others are — read this before writing to anyone:
|
|
22
|
+
- A session is identified by its mailbox address, and by nothing else. \`whoami\` gives you yours.
|
|
23
|
+
- The agent name (e.g. "Ai Corrector Dev") comes from the configuration and says which project the agent works on. It is NOT unique: every session started from that configuration carries it.
|
|
24
|
+
- So several mailboxes in \`list_agents\` can carry the same agent name as yours. Recognising your own agent name there does not mean you are looking at yourself — it is another session of the same project, a different agent, with its own mailbox. Compare addresses, never names.
|
|
25
|
+
- Your own mailbox is never listed in \`list_agents\`: every address you see there belongs to someone else.
|
|
26
|
+
|
|
27
|
+
Writing:
|
|
28
|
+
- One message goes to exactly one agent, and never to yourself. To reach several agents, send each one its own message.
|
|
29
|
+
- Never write a mailbox address in the body of a message. The server attaches the sender and the recipient to every message, and the reader sees them: an address copied by hand adds nothing and misleads as soon as it is stale or mistaken.
|
|
30
|
+
- Call \`enable_notifications\` once at the start of the session and arm the watcher it hands you. Until then, no incoming message reaches you.`;
|
|
11
31
|
/** Serveur MCP prêt à être branché sur n'importe quel transport (stdio en production, mémoire en test). */
|
|
12
32
|
export function createMcpServer(client) {
|
|
13
|
-
const server = new Server({ name: "mcp-messenger", version: APP_VERSION }, { capabilities: { tools: {} } });
|
|
33
|
+
const server = new Server({ name: "mcp-messenger", version: APP_VERSION }, { capabilities: { tools: {} }, instructions: INSTRUCTIONS });
|
|
14
34
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));
|
|
15
35
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
16
36
|
const { name, arguments: args } = request.params;
|
package/dist/src/mcp/tools.js
CHANGED
|
@@ -7,7 +7,7 @@ const FOLDER_HINT = `Folder name. System folders: ${SYSTEM_FOLDERS.join(", ")}.
|
|
|
7
7
|
export const TOOLS = [
|
|
8
8
|
{
|
|
9
9
|
name: "whoami",
|
|
10
|
-
description: "Return this session's mailbox address, the server it is connected to, and unread counts per folder. The address is what
|
|
10
|
+
description: "Return this session's mailbox address, the server it is connected to, and unread counts per folder. The address is what identifies this session: tell it to the user when they ask how to reach you. Other agents never need you to send it — list_agents gives it to them, and every message you send already carries it.",
|
|
11
11
|
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
12
12
|
},
|
|
13
13
|
{
|
|
@@ -73,13 +73,16 @@ export const TOOLS = [
|
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
name: "send_message",
|
|
76
|
-
description: "Send a message to one agent, identified by its mailbox address. A message has a single recipient: to reach several agents, send each one its own message. Set reply_to to answer an existing message and keep the thread together.",
|
|
76
|
+
description: "Send a message to one agent, identified by its mailbox address. A message has a single recipient: to reach several agents, send each one its own message. Set reply_to to answer an existing message and keep the thread together. Never write a mailbox address in the body: the server attaches the sender and the recipient to every message, so an address copied by hand adds nothing and misleads as soon as it is wrong.",
|
|
77
77
|
inputSchema: {
|
|
78
78
|
type: "object",
|
|
79
79
|
properties: {
|
|
80
80
|
to: { type: "string", description: "Recipient agent id (mailbox address). Exactly one recipient." },
|
|
81
81
|
subject: { type: "string", description: "Short subject line." },
|
|
82
|
-
body: {
|
|
82
|
+
body: {
|
|
83
|
+
type: "string",
|
|
84
|
+
description: "Message body, plain text or markdown. Do not restate your own address or the recipient's here.",
|
|
85
|
+
},
|
|
83
86
|
priority: { type: "string", enum: [...PRIORITIES], description: "Defaults to normal." },
|
|
84
87
|
reply_to: { type: "string", description: "Id of the message being answered; the reply joins its thread." },
|
|
85
88
|
thread_name: {
|
|
@@ -296,8 +299,16 @@ export async function callTool(client, name, rawArgs) {
|
|
|
296
299
|
const self = await client.getAgent(client.agentId).catch(() => null);
|
|
297
300
|
const lines = [
|
|
298
301
|
`Mailbox address: ${client.agentId}`,
|
|
299
|
-
|
|
300
|
-
|
|
302
|
+
// Personne n'a besoin qu'on la lui envoie : l'annuaire la donne, et chaque message
|
|
303
|
+
// la porte déjà. Le seul destinataire légitime est l'utilisateur, qui le demande.
|
|
304
|
+
" ↳ this identifies this session. Other agents read it from list_agents and from the",
|
|
305
|
+
" messages you send them — tell it to the user if asked, never inside a message body.",
|
|
306
|
+
self?.agent_name
|
|
307
|
+
? `Agent: ${self.agent_name}`
|
|
308
|
+
: "Agent: unnamed (set MESSENGER_AGENT_NAME in the MCP configuration)",
|
|
309
|
+
// Le nom vient de la configuration : toutes les sessions du projet le portent. Le
|
|
310
|
+
// dire ici évite qu'un agent prenne une session homonyme pour la sienne.
|
|
311
|
+
" ↳ this name is shared with every session of the same project; only the address above identifies you.",
|
|
301
312
|
self?.display_name
|
|
302
313
|
? `Mailbox name: ${self.display_name}`
|
|
303
314
|
: "Mailbox name: none — call rename_mailbox so the user can tell this session apart from the others.",
|
|
@@ -369,7 +380,7 @@ export async function callTool(client, name, rawArgs) {
|
|
|
369
380
|
const agents = await client.listAgents();
|
|
370
381
|
if (agents.length === 0)
|
|
371
382
|
return "No other agent on this server yet.";
|
|
372
|
-
|
|
383
|
+
const directory = agents
|
|
373
384
|
.map((agent) => {
|
|
374
385
|
const flags = agent.registered ? "" : "never connected";
|
|
375
386
|
const names = formatAgentNames(agent);
|
|
@@ -383,6 +394,16 @@ export async function callTool(client, name, rawArgs) {
|
|
|
383
394
|
].join("\n");
|
|
384
395
|
})
|
|
385
396
|
.join("\n");
|
|
397
|
+
// Un nom d'agent est celui d'un projet, pas d'une session : plusieurs boîtes le
|
|
398
|
+
// portent, y compris celle de l'appelant. Sans ce rappel, un agent croise son propre
|
|
399
|
+
// nom d'agent dans cette liste et prend la boîte d'une autre session pour la sienne.
|
|
400
|
+
return [
|
|
401
|
+
directory,
|
|
402
|
+
"",
|
|
403
|
+
"Addresses identify sessions; agent names do not. Several mailboxes above may carry the same",
|
|
404
|
+
"agent name as yours — they are other sessions of the same project, never you: your own mailbox",
|
|
405
|
+
"is never listed here. Always write to an address taken from this list, never to a name.",
|
|
406
|
+
].join("\n");
|
|
386
407
|
}
|
|
387
408
|
case "send_message": {
|
|
388
409
|
const input = schemas.send_message.parse(args);
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const APP_VERSION = "1.0.
|
|
1
|
+
export declare const APP_VERSION = "1.0.9";
|
package/dist/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Généré par scripts/generate-version.js — ne pas modifier à la main.
|
|
2
|
-
export const APP_VERSION = "1.0.
|
|
2
|
+
export const APP_VERSION = "1.0.9";
|