@imenam/mcp-messenger 1.0.7 → 1.0.8

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 CHANGED
@@ -248,6 +248,19 @@ de la boîte seul ne dit pas d'où l'agent écrit. L'annuaire (`list_agents`), `
248
248
  console web montrent donc toujours les deux, sous la forme `Agent · Boîte`. Renommer la
249
249
  boîte ne touche jamais au nom de l'agent.
250
250
 
251
+ **Un nom d'agent ne désigne personne.** C'est le piège de ce modèle : plusieurs boîtes
252
+ portent le même `agent_name`, une par session lancée depuis la même configuration. Un agent
253
+ qui croise son propre nom d'agent dans l'annuaire regarde une *autre* session du même
254
+ projet, jamais la sienne — sa boîte, elle, n'y figure pas du tout. Seule l'adresse identifie
255
+ une session. Ce rappel est servi à trois endroits, du plus tôt au plus tard : les
256
+ instructions du serveur MCP (reçues à la connexion, avant le premier outil), la ligne qui
257
+ suit `Agent:` dans `whoami`, et le pied de l'annuaire dans `list_agents`.
258
+
259
+ **Les adresses ne se recopient pas à la main.** Le serveur attache l'expéditeur et le
260
+ destinataire à chaque message, et le lecteur les voit dans l'en-tête. Écrire son adresse
261
+ dans le corps n'ajoute rien et se met à mentir dès qu'elle est erronée ou périmée —
262
+ `send_message` le dit dans sa description et dans celle de `body`.
263
+
251
264
  ### Nommer les boîtes et les fils
252
265
 
253
266
  Les identifiants (`box_…`, `thr_…`) ne disent rien de ce qui se passe. Deux noms en langue
@@ -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;
@@ -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: { type: "string", description: "Message body, plain text or markdown." },
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: {
@@ -297,7 +300,12 @@ export async function callTool(client, name, rawArgs) {
297
300
  const lines = [
298
301
  `Mailbox address: ${client.agentId}`,
299
302
  " ↳ give this address to another agent so it can write to you.",
300
- `Agent: ${self?.agent_name ?? "unnamed (set MESSENGER_AGENT_NAME in the MCP configuration)"}`,
303
+ self?.agent_name
304
+ ? `Agent: ${self.agent_name}`
305
+ : "Agent: unnamed (set MESSENGER_AGENT_NAME in the MCP configuration)",
306
+ // Le nom vient de la configuration : toutes les sessions du projet le portent. Le
307
+ // dire ici évite qu'un agent prenne une session homonyme pour la sienne.
308
+ " ↳ this name is shared with every session of the same project; only the address above identifies you.",
301
309
  self?.display_name
302
310
  ? `Mailbox name: ${self.display_name}`
303
311
  : "Mailbox name: none — call rename_mailbox so the user can tell this session apart from the others.",
@@ -369,7 +377,7 @@ export async function callTool(client, name, rawArgs) {
369
377
  const agents = await client.listAgents();
370
378
  if (agents.length === 0)
371
379
  return "No other agent on this server yet.";
372
- return agents
380
+ const directory = agents
373
381
  .map((agent) => {
374
382
  const flags = agent.registered ? "" : "never connected";
375
383
  const names = formatAgentNames(agent);
@@ -383,6 +391,16 @@ export async function callTool(client, name, rawArgs) {
383
391
  ].join("\n");
384
392
  })
385
393
  .join("\n");
394
+ // Un nom d'agent est celui d'un projet, pas d'une session : plusieurs boîtes le
395
+ // portent, y compris celle de l'appelant. Sans ce rappel, un agent croise son propre
396
+ // nom d'agent dans cette liste et prend la boîte d'une autre session pour la sienne.
397
+ return [
398
+ directory,
399
+ "",
400
+ "Addresses identify sessions; agent names do not. Several mailboxes above may carry the same",
401
+ "agent name as yours — they are other sessions of the same project, never you: your own mailbox",
402
+ "is never listed here. Always write to an address taken from this list, never to a name.",
403
+ ].join("\n");
386
404
  }
387
405
  case "send_message": {
388
406
  const input = schemas.send_message.parse(args);
@@ -1 +1 @@
1
- export declare const APP_VERSION = "1.0.7";
1
+ export declare const APP_VERSION = "1.0.8";
@@ -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.7";
2
+ export const APP_VERSION = "1.0.8";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imenam/mcp-messenger",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "main": "dist/src/index.js",
5
5
  "scripts": {
6
6
  "test": "npm run build && vitest run",