@imenam/mcp-messenger 1.0.35 → 1.0.36
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 +8 -2
- package/dist/src/core/access-store.d.ts +5 -0
- package/dist/src/core/access-store.js +17 -0
- package/dist/src/core/store.js +223 -223
- package/dist/src/index.js +21 -21
- package/dist/src/server/app.js +6 -3
- package/dist/src/server/ui/app.js +62 -1
- package/dist/src/server/ui/markdown.js +340 -340
- package/dist/src/server/ui/styles.css +3826 -3820
- package/package.json +64 -61
- package/dist/src/cli/generate-token.d.ts +0 -7
- package/dist/src/cli/generate-token.js +0 -12
package/dist/src/index.js
CHANGED
|
@@ -3,27 +3,27 @@ import "dotenv/config";
|
|
|
3
3
|
import { ConfigError } from "./config.js";
|
|
4
4
|
import { logger } from "./logger.js";
|
|
5
5
|
import { APP_VERSION } from "./version.js";
|
|
6
|
-
const USAGE = `mcp-messenger v${APP_VERSION} — agent-to-agent mailbox
|
|
7
|
-
|
|
8
|
-
Usage:
|
|
9
|
-
mcp-messenger Start in MCP mode (stdio) — the agent-side client.
|
|
10
|
-
mcp-messenger --server Start the mailbox server (HTTP API + web console).
|
|
11
|
-
mcp-messenger --watch <mailbox>
|
|
12
|
-
Print one line per incoming message, forever. Meant to be
|
|
13
|
-
run by the agent's host as a background watcher, not by hand.
|
|
14
|
-
mcp-messenger --claude-setup-mcp [--server-url <url>] [--api-key <key>] [--force]
|
|
15
|
-
Write the messenger entry into ./.mcp.json.
|
|
16
|
-
mcp-messenger --reset-password
|
|
17
|
-
Give the web console account a new random password and
|
|
18
|
-
close all its sessions. Run it on the server machine.
|
|
19
|
-
mcp-messenger --version Print the version.
|
|
20
|
-
mcp-messenger --help Print this help.
|
|
21
|
-
|
|
22
|
-
MCP mode requires MESSENGER_SERVER_URL and MESSENGER_API_KEY (an API key created in the
|
|
23
|
-
web console); each session gets its own mailbox unless MESSENGER_AGENT_ID pins a fixed
|
|
24
|
-
address.
|
|
25
|
-
Server mode reads MESSENGER_PORT and MESSENGER_DB_PATH and always listens on 127.0.0.1.
|
|
26
|
-
At the first start it prints a setup code: open /ui/ to create the console account.
|
|
6
|
+
const USAGE = `mcp-messenger v${APP_VERSION} — agent-to-agent mailbox
|
|
7
|
+
|
|
8
|
+
Usage:
|
|
9
|
+
mcp-messenger Start in MCP mode (stdio) — the agent-side client.
|
|
10
|
+
mcp-messenger --server Start the mailbox server (HTTP API + web console).
|
|
11
|
+
mcp-messenger --watch <mailbox>
|
|
12
|
+
Print one line per incoming message, forever. Meant to be
|
|
13
|
+
run by the agent's host as a background watcher, not by hand.
|
|
14
|
+
mcp-messenger --claude-setup-mcp [--server-url <url>] [--api-key <key>] [--force]
|
|
15
|
+
Write the messenger entry into ./.mcp.json.
|
|
16
|
+
mcp-messenger --reset-password
|
|
17
|
+
Give the web console account a new random password and
|
|
18
|
+
close all its sessions. Run it on the server machine.
|
|
19
|
+
mcp-messenger --version Print the version.
|
|
20
|
+
mcp-messenger --help Print this help.
|
|
21
|
+
|
|
22
|
+
MCP mode requires MESSENGER_SERVER_URL and MESSENGER_API_KEY (an API key created in the
|
|
23
|
+
web console); each session gets its own mailbox unless MESSENGER_AGENT_ID pins a fixed
|
|
24
|
+
address.
|
|
25
|
+
Server mode reads MESSENGER_PORT and MESSENGER_DB_PATH and always listens on 127.0.0.1.
|
|
26
|
+
At the first start it prints a setup code: open /ui/ to create the console account.
|
|
27
27
|
See .env.example for the full list.`;
|
|
28
28
|
/** Valeur qui suit une option (`--api-key mk_…`), ou null si l'option est absente ou vide. */
|
|
29
29
|
function optionValue(args, name) {
|
package/dist/src/server/app.js
CHANGED
|
@@ -140,11 +140,10 @@ const keyCreateSchema = z
|
|
|
140
140
|
const keyPatchSchema = z
|
|
141
141
|
.object({
|
|
142
142
|
name: z.string().trim().min(1).max(200).optional(),
|
|
143
|
+
agent_name: z.string().trim().min(1).max(200).optional(),
|
|
143
144
|
agent_description: agentDescriptionSchema.optional(),
|
|
144
145
|
})
|
|
145
|
-
.refine((input) => input.name !== undefined || input.agent_description !== undefined, {
|
|
146
|
-
message: "provide `name` and/or `agent_description`",
|
|
147
|
-
});
|
|
146
|
+
.refine((input) => input.name !== undefined || input.agent_name !== undefined || input.agent_description !== undefined, { message: "provide `name`, `agent_name` and/or `agent_description`" });
|
|
148
147
|
const keyExtendSchema = z.object({ days: lifetimeSchema });
|
|
149
148
|
const adminThreadsSchema = z.object({
|
|
150
149
|
search: z.string().trim().min(1).optional(),
|
|
@@ -527,6 +526,10 @@ export function createApp({ store, config, setup = new SetupGate(store.access) }
|
|
|
527
526
|
const input = keyPatchSchema.parse(req.body ?? {});
|
|
528
527
|
const id = String(req.params.id);
|
|
529
528
|
let key = input.name !== undefined ? access.renameApiKey(id, input.name) : null;
|
|
529
|
+
if (input.agent_name !== undefined) {
|
|
530
|
+
key = access.setApiKeyAgentName(id, input.agent_name);
|
|
531
|
+
logger.info(`API key ${key.id} now bound to agent "${key.agent_name}"`);
|
|
532
|
+
}
|
|
530
533
|
if (input.agent_description !== undefined)
|
|
531
534
|
key = access.setApiKeyAgentDescription(id, input.agent_description);
|
|
532
535
|
res.json({ key });
|
|
@@ -3265,6 +3265,7 @@ async function openKeyDetail(id) {
|
|
|
3265
3265
|
function renderKeyDetail({ key, mailboxes }) {
|
|
3266
3266
|
let renaming = false;
|
|
3267
3267
|
let describing = false;
|
|
3268
|
+
let renamingAgent = false;
|
|
3268
3269
|
let extendOpen = false;
|
|
3269
3270
|
const error = node("p", "form-banner");
|
|
3270
3271
|
error.hidden = true;
|
|
@@ -3385,7 +3386,7 @@ function renderKeyDetail({ key, mailboxes }) {
|
|
|
3385
3386
|
for (const part of [].concat(value)) cell.appendChild(typeof part === "string" ? document.createTextNode(part) : part);
|
|
3386
3387
|
list.appendChild(cell);
|
|
3387
3388
|
};
|
|
3388
|
-
add("Agent autorisé", keyAgent(key));
|
|
3389
|
+
add("Agent autorisé", key.agent_name ? agentNameCell() : keyAgent(key));
|
|
3389
3390
|
if (key.agent_name) add("Description", descriptionCell());
|
|
3390
3391
|
add("Créée", `${formatDay(key.created_at)}${key.created_by ? ` par ${key.created_by}` : ""}`);
|
|
3391
3392
|
add(
|
|
@@ -3398,6 +3399,66 @@ function renderKeyDetail({ key, mailboxes }) {
|
|
|
3398
3399
|
return list;
|
|
3399
3400
|
}
|
|
3400
3401
|
|
|
3402
|
+
/**
|
|
3403
|
+
* Nom de l'agent, modifiable sur place : Entrée ou un clic ailleurs enregistre, Échap
|
|
3404
|
+
* annule. Le nouveau nom s'applique aussi aux boîtes déjà ouvertes avec la clé.
|
|
3405
|
+
*/
|
|
3406
|
+
function agentNameCell() {
|
|
3407
|
+
if (!renamingAgent) {
|
|
3408
|
+
const edit = node("button", "btn btn--icon btn--ghost props-edit");
|
|
3409
|
+
edit.type = "button";
|
|
3410
|
+
edit.title = "Renommer l'agent";
|
|
3411
|
+
edit.setAttribute("aria-label", "Renommer l'agent autorisé");
|
|
3412
|
+
edit.appendChild(icon("pencil"));
|
|
3413
|
+
edit.addEventListener("click", () => {
|
|
3414
|
+
renamingAgent = true;
|
|
3415
|
+
render();
|
|
3416
|
+
});
|
|
3417
|
+
return [keyAgent(key), edit];
|
|
3418
|
+
}
|
|
3419
|
+
const input = textInput(key.agent_name, { autocomplete: "off", list: "key-detail-agent-names" });
|
|
3420
|
+
input.className = "inline-input inline-input--small";
|
|
3421
|
+
const datalist = node("datalist");
|
|
3422
|
+
datalist.id = "key-detail-agent-names";
|
|
3423
|
+
for (const name of knownAgentNames()) {
|
|
3424
|
+
const option = document.createElement("option");
|
|
3425
|
+
option.value = name;
|
|
3426
|
+
datalist.appendChild(option);
|
|
3427
|
+
}
|
|
3428
|
+
let saved = false;
|
|
3429
|
+
const save = async () => {
|
|
3430
|
+
if (saved) return;
|
|
3431
|
+
saved = true;
|
|
3432
|
+
const agentName = input.value.trim();
|
|
3433
|
+
if (!agentName || agentName === key.agent_name) {
|
|
3434
|
+
renamingAgent = false;
|
|
3435
|
+
render();
|
|
3436
|
+
return;
|
|
3437
|
+
}
|
|
3438
|
+
try {
|
|
3439
|
+
await patch(`/admin/keys/${encodeURIComponent(key.id)}`, { agent_name: agentName });
|
|
3440
|
+
await reload();
|
|
3441
|
+
} catch (failure) {
|
|
3442
|
+
saved = false;
|
|
3443
|
+
fail(failure);
|
|
3444
|
+
}
|
|
3445
|
+
};
|
|
3446
|
+
input.addEventListener("keydown", (event) => {
|
|
3447
|
+
if (event.key === "Enter") save();
|
|
3448
|
+
if (event.key === "Escape") {
|
|
3449
|
+
// Échap referme la saisie, pas le volet.
|
|
3450
|
+
event.preventDefault();
|
|
3451
|
+
event.stopPropagation();
|
|
3452
|
+
saved = true;
|
|
3453
|
+
renamingAgent = false;
|
|
3454
|
+
render();
|
|
3455
|
+
}
|
|
3456
|
+
});
|
|
3457
|
+
input.addEventListener("blur", save);
|
|
3458
|
+
setTimeout(() => input.focus(), 0);
|
|
3459
|
+
return [input, datalist];
|
|
3460
|
+
}
|
|
3461
|
+
|
|
3401
3462
|
/** Description de l'agent, modifiable sur place : Entrée enregistre, Échap annule. */
|
|
3402
3463
|
function descriptionCell() {
|
|
3403
3464
|
if (!describing) {
|