totemlayer 0.1.67 → 0.1.68
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 +6 -4
- package/bin/mcp-install.mjs +90 -4
- package/bin/native/darwin-lifetime +0 -0
- package/bin/native/darwin-lifetime.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ To configure execution later, rerun setup with `--provider` and the adapter's se
|
|
|
27
27
|
|
|
28
28
|
## Connect with automatic listener setup
|
|
29
29
|
|
|
30
|
-
Configure a local MCP server using command `npx` and arguments `--yes`, `--ignore-scripts`, `--package=https://totemlayer.com/downloads/totemlayer-0.1.
|
|
30
|
+
Configure a local MCP server using command `npx` and arguments `--yes`, `--ignore-scripts`, `--package=https://totemlayer.com/downloads/totemlayer-0.1.68.tgz`, `totem`, `connect`, `--provider`, and `codex` (or `claude` for Claude Code). The host runs the connection itself; the owner does not run a separate listener command. Node.js 22.14 or newer and the selected signed-in client must be available.
|
|
31
31
|
|
|
32
32
|
During browser sign-in, `totem_get_connection_status` reports progress. Normal tools appear after the approved identity is pinned privately. Codex verifies identity, startup and the saved chat callback before receiving work; reconnect preserves bindings and pauses. Missing capabilities leave work queued. A remote HTTP connector cannot install local software.
|
|
33
33
|
|
|
@@ -45,7 +45,7 @@ For a hosted connection, add these settings to your client's MCP configuration:
|
|
|
45
45
|
For a local stdio connection, install the CLI with Node.js 22.14 or newer:
|
|
46
46
|
|
|
47
47
|
```sh
|
|
48
|
-
npm install --global --ignore-scripts https://totemlayer.com/downloads/totemlayer-0.1.
|
|
48
|
+
npm install --global --ignore-scripts https://totemlayer.com/downloads/totemlayer-0.1.68.tgz
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Save your agent's connection key in a private file. Protect it with mode 0600 on macOS/Linux or your user's filesystem ACL on Windows. Configure these fields in your client's MCP settings:
|
|
@@ -64,7 +64,7 @@ Reload the client if needed, discover the available tools, and call `totem_get_i
|
|
|
64
64
|
Run the guided installer on the host where your agent will execute work:
|
|
65
65
|
|
|
66
66
|
```sh
|
|
67
|
-
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.
|
|
67
|
+
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.68.tgz totem install
|
|
68
68
|
```
|
|
69
69
|
|
|
70
70
|
The installer opens Totem sign-in and saves the approved connection privately. It checks your configured agent runtime, configures supported clients, and starts the listener when an authorized executor is available. The supervised listener is enabled by default for this setup and starts when you sign in to the computer on hosts with a supported user service manager. It recovers after a process exit and retries temporary connection failures. An explicit stop stays paused across restarts.
|
|
@@ -74,7 +74,7 @@ For manual setup, use `totem mcp install` with a supported client and the privat
|
|
|
74
74
|
For a host without a browser:
|
|
75
75
|
|
|
76
76
|
```sh
|
|
77
|
-
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.
|
|
77
|
+
npx --yes --package=https://totemlayer.com/downloads/totemlayer-0.1.68.tgz totem login --device-login --no-browser
|
|
78
78
|
```
|
|
79
79
|
|
|
80
80
|
Open the printed link on your own device and compare the connection code. Preserve existing MCP entries; inspect conflicts before replacing them. If an executor is unavailable, the saved connection remains available while you complete runtime setup.
|
|
@@ -176,3 +176,5 @@ An update changes only the managed code directory. Existing identities, credenti
|
|
|
176
176
|
`totem update status` shows the installed version and last check. `totem update check` checks now. `totem update pause` disables automatic downloads; `totem update resume` enables them. For a plugin connection, add its `--provider codex` or `--provider claude` selection. `TOTEM_AUTO_UPDATE=0` also disables checks. Pausing updates does not pause message receiving.
|
|
177
177
|
|
|
178
178
|
Unverified downloads and failed health checks leave working code installed. A receiver that repeatedly crashes immediately after an update falls back to its retained previous version and quarantines the failed version. An offline or sleeping computer checks after it resumes; updates do not wake a closed laptop or add a wake mechanism to an external AI host.
|
|
179
|
+
|
|
180
|
+
Local Codex setup now defaults to the listener-enabled bound installer with `totem mcp install codex`. The client opens approval and automatically prepares persistent receiving when its MCP connection starts. Verify `totem_get_connection_status` reports `ready=true` and `startupConfigured=true` before reporting installation complete. Use `--transport http` only for an explicit hosted MCP connection; it does not register a host service. Existing settings, identities and owner pauses are preserved.
|
package/bin/mcp-install.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import { resolve, join } from "node:path";
|
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
8
|
|
|
9
9
|
import { installedClientInvocation, localClientEnvironment } from "./platform-client.mjs";
|
|
10
|
-
import { runtimeRoot } from "./runtime-installation.mjs";
|
|
10
|
+
import { runtimeRoot, ensureInstalledRuntime } from "./runtime-installation.mjs";
|
|
11
11
|
import { loadMcpIdentityBinding } from "./mcp-identity-binding.mjs";
|
|
12
12
|
|
|
13
13
|
const DEFAULT_ORIGIN = "https://totemlayer.com";
|
|
@@ -18,7 +18,8 @@ export const MCP_INSTALL_HELP = `Connect Totem to an AI app
|
|
|
18
18
|
|
|
19
19
|
Usage:
|
|
20
20
|
totem mcp install claude Add hosted MCP and open one OAuth approval
|
|
21
|
-
totem mcp install codex Add
|
|
21
|
+
totem mcp install codex Add local MCP with automatic listener setup
|
|
22
|
+
totem mcp install codex --transport http Explicit hosted MCP without a host service
|
|
22
23
|
totem mcp install generic HTTP settings for other hosts
|
|
23
24
|
totem mcp config HTTP settings for any MCP client
|
|
24
25
|
totem mcp config --transport stdio --key-file /absolute/path/to/agent.key
|
|
@@ -31,13 +32,18 @@ Options:
|
|
|
31
32
|
--base-url <origin> Totem origin (default: https://totemlayer.com)
|
|
32
33
|
--name <name> MCP name (default: totem, or totem-local with --key-file)
|
|
33
34
|
--key-file <path> Use an existing private agent key for local stdio instead
|
|
35
|
+
--transport <type> http or stdio (Codex defaults to listener-enabled stdio)
|
|
34
36
|
--agent-id <UUID> Require this credential-derived agent identity
|
|
35
37
|
--environment <env> Require PRODUCTION or SANDBOX
|
|
36
38
|
--codex-thread <ID> Bind a new Codex listener to this owner-selected chat
|
|
37
39
|
--no-start Configure tools only; do not start a local listener
|
|
38
40
|
--help Show this guide
|
|
39
41
|
|
|
40
|
-
Without --key-file,
|
|
42
|
+
Without --key-file, Codex uses the bound browser installer and supervised listener.
|
|
43
|
+
The selected Codex host opens approval and finishes listener setup on connection.
|
|
44
|
+
Settings alone are not setup completion: check totem_get_connection_status until
|
|
45
|
+
ready and startupConfigured are true. Explicit stops remain paused.
|
|
46
|
+
Claude and generic use hosted MCP; --transport http explicitly selects that flow.
|
|
41
47
|
The client saves credentials privately. No Totem website guide, copied key,
|
|
42
48
|
local worker, or model change is required. Existing connections are preserved.
|
|
43
49
|
The host may require reloading tools after adding a server. Call
|
|
@@ -87,6 +93,7 @@ function parseInstallArgs(args, environment) {
|
|
|
87
93
|
"--agent-id",
|
|
88
94
|
"--environment",
|
|
89
95
|
"--codex-thread",
|
|
96
|
+
"--transport",
|
|
90
97
|
].includes(option) ||
|
|
91
98
|
!value ||
|
|
92
99
|
value.startsWith("--")
|
|
@@ -96,6 +103,13 @@ function parseInstallArgs(args, environment) {
|
|
|
96
103
|
values[option] = value;
|
|
97
104
|
}
|
|
98
105
|
const keyFile = values["--key-file"] ?? environment.TOTEM_NETWORK_API_KEY_FILE;
|
|
106
|
+
const transport = values["--transport"] ?? (keyFile || client === "codex" ? "stdio" : "http");
|
|
107
|
+
if (!["http", "stdio"].includes(transport)) fail("Choose --transport http or stdio.");
|
|
108
|
+
if (keyFile && transport === "http") fail("Use a private key file only with stdio transport.");
|
|
109
|
+
if (!keyFile && transport === "stdio" && client !== "codex")
|
|
110
|
+
fail(
|
|
111
|
+
"Keyless local listener setup currently requires Codex. Use this host's supported incoming integration or an explicit private key file.",
|
|
112
|
+
);
|
|
99
113
|
const name = values["--name"] ?? (keyFile ? DEFAULT_NAME : "totem");
|
|
100
114
|
if (!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/.test(name))
|
|
101
115
|
fail(
|
|
@@ -128,6 +142,7 @@ function parseInstallArgs(args, environment) {
|
|
|
128
142
|
fail("--codex-thread requires codex and an owner-selected chat UUID.");
|
|
129
143
|
return {
|
|
130
144
|
client,
|
|
145
|
+
transport,
|
|
131
146
|
codexThreadId: values["--codex-thread"],
|
|
132
147
|
configDirectory: environment.TOTEM_CONFIG_DIR ? runtimeRoot(environment) : undefined,
|
|
133
148
|
noStart: values["--no-start"] === true || environment.TOTEM_AUTO_START === "0",
|
|
@@ -305,7 +320,10 @@ export async function installTotemMcp(args, environment = process.env, runtime =
|
|
|
305
320
|
const options = parseInstallArgs(args, environment);
|
|
306
321
|
if (options.help) return MCP_INSTALL_HELP;
|
|
307
322
|
runtime = { platform: process.platform, spawnProcess: spawnSync, ...runtime };
|
|
308
|
-
if (!options.keyFile)
|
|
323
|
+
if (!options.keyFile)
|
|
324
|
+
return options.transport === "stdio"
|
|
325
|
+
? installBoundTotemMcp(options, environment, runtime)
|
|
326
|
+
: installHostedTotemMcp(options, environment, runtime);
|
|
309
327
|
await validateKeyFile(options.keyFile, runtime.platform);
|
|
310
328
|
|
|
311
329
|
if (options.client === "generic")
|
|
@@ -440,6 +458,74 @@ export async function installTotemMcp(args, environment = process.env, runtime =
|
|
|
440
458
|
return `Connected ${options.name} to ${command} at ${options.baseUrl}.${listener} Restart ${command}, then ask it to call totem_get_identity. The Totem CLI package must remain installed.\n`;
|
|
441
459
|
}
|
|
442
460
|
|
|
461
|
+
/** Persist the self-configuring entry, rather than a tools-only hosted URL.
|
|
462
|
+
* Authorization and readiness happen inside that exact client connection. */
|
|
463
|
+
async function installBoundTotemMcp(options, environment, runtime) {
|
|
464
|
+
if (options.codexThreadId)
|
|
465
|
+
fail("Use the existing private-key setup to bind an explicitly selected Codex chat.");
|
|
466
|
+
const installed = await (runtime.ensureRuntime ?? ensureInstalledRuntime)(environment);
|
|
467
|
+
const args = [
|
|
468
|
+
installed.cli,
|
|
469
|
+
"connect",
|
|
470
|
+
"--provider",
|
|
471
|
+
options.client,
|
|
472
|
+
"--base-url",
|
|
473
|
+
options.baseUrl,
|
|
474
|
+
...(options.expectedAgentId ? ["--agent-id", options.expectedAgentId] : []),
|
|
475
|
+
...(options.expectedEnvironment ? ["--environment", options.expectedEnvironment] : []),
|
|
476
|
+
];
|
|
477
|
+
const savedEnv = options.noStart ? { TOTEM_AUTO_START: "0" } : {};
|
|
478
|
+
const env = localClientEnvironment(environment);
|
|
479
|
+
const get = () => runClient(options.client, ["mcp", "get", options.name, "--json"], env, runtime);
|
|
480
|
+
const matches = (entry) => {
|
|
481
|
+
try {
|
|
482
|
+
const value = JSON.parse(entry.stdout),
|
|
483
|
+
transport = value.transport;
|
|
484
|
+
return (
|
|
485
|
+
entry.status === 0 &&
|
|
486
|
+
value.enabled !== false &&
|
|
487
|
+
transport?.type === "stdio" &&
|
|
488
|
+
transport.command === process.execPath &&
|
|
489
|
+
JSON.stringify(transport.args) === JSON.stringify(args) &&
|
|
490
|
+
JSON.stringify(Object.entries(transport.env ?? {}).sort()) ===
|
|
491
|
+
JSON.stringify(Object.entries(savedEnv).sort()) &&
|
|
492
|
+
(!value.disabled_tools || value.disabled_tools.length === 0) &&
|
|
493
|
+
(!value.enabled_tools || value.enabled_tools.includes("totem_get_connection_status"))
|
|
494
|
+
);
|
|
495
|
+
} catch {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
};
|
|
499
|
+
const existing = get();
|
|
500
|
+
if (existing.status === 0 && !matches(existing))
|
|
501
|
+
fail(
|
|
502
|
+
"This MCP entry already has different or disabled settings. It was preserved. Inspect that exact connection before repairing its automatic receiver; adding tools alone does not complete listener setup.",
|
|
503
|
+
);
|
|
504
|
+
if (existing.status !== 0) {
|
|
505
|
+
if (!/no mcp server|not found|does not exist/i.test(`${existing.stderr}\n${existing.stdout}`))
|
|
506
|
+
fail("The client could not check its existing MCP settings. No configuration was changed.");
|
|
507
|
+
const add = runClient(
|
|
508
|
+
options.client,
|
|
509
|
+
[
|
|
510
|
+
"mcp",
|
|
511
|
+
"add",
|
|
512
|
+
options.name,
|
|
513
|
+
...Object.entries(savedEnv).flatMap(([name, value]) => ["--env", `${name}=${value}`]),
|
|
514
|
+
"--",
|
|
515
|
+
process.execPath,
|
|
516
|
+
...args,
|
|
517
|
+
],
|
|
518
|
+
env,
|
|
519
|
+
runtime,
|
|
520
|
+
);
|
|
521
|
+
if (add.status !== 0 || !matches(get()))
|
|
522
|
+
fail(
|
|
523
|
+
"The listener-enabled MCP settings could not be verified. Inspect this exact entry before retrying.",
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
return "Totem's listener-enabled MCP settings are saved. Reload the selected client's MCP tools to open its bound browser approval and configure the persistent listener automatically. Setup is incomplete until totem_get_connection_status reports ready=true and startupConfigured=true; then verify a permitted incoming message and reply. Existing pauses and permissions are preserved.\n";
|
|
527
|
+
}
|
|
528
|
+
|
|
443
529
|
/** Guided setup owns a distinct entry per profile; the manual installer retains its default. */
|
|
444
530
|
export function managedMcpName(profileName) {
|
|
445
531
|
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(profileName) || profileName.length > 64)
|
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"sourceSha256":"e15dc6cfd6f828dbcb829fc6fa3f5f6ef51062f45462ec6532b8c52f532c7951","binarySha256":"
|
|
1
|
+
{"sourceSha256":"e15dc6cfd6f828dbcb829fc6fa3f5f6ef51062f45462ec6532b8c52f532c7951","binarySha256":"841e12dec0c0269584f5a13793f9a66471af09db73783fcca3d5e1750582aafc","architectures":["arm64","x86_64"],"minimumMacOS":"13.0"}
|