agent-trellis 0.14.0 → 0.14.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/dist/adapters/piMcp.d.ts
CHANGED
|
@@ -28,8 +28,11 @@ export declare function supportsNativeMcp(version: string | undefined): boolean;
|
|
|
28
28
|
* `pi mcp add` writes (observed 2026-10-11): stdio as
|
|
29
29
|
* `{command, args, env?}`, http as `{url, headers?}`, no `type` field.
|
|
30
30
|
* `env` names render as `${VAR}` references exactly like the other JSON
|
|
31
|
-
* agents; OAuth `auth` metadata is Trellis-side routing information and
|
|
32
|
-
*
|
|
33
|
-
* entry
|
|
31
|
+
* agents; OAuth `auth` metadata is Trellis-side routing information and is
|
|
32
|
+
* never rendered — with one exception: a declared `auth.client_name` becomes
|
|
33
|
+
* the entry's `oauth.clientName`, the field `pi mcp add --oauth-client-name`
|
|
34
|
+
* writes, so providers that gate dynamic client registration by client name
|
|
35
|
+
* (Figma) accept `pi mcp login`'s registration and later syncs compare equal
|
|
36
|
+
* instead of stripping the block (oauth-client-name design.md D2).
|
|
34
37
|
*/
|
|
35
38
|
export declare function piRenderer(def: McpServerDef, _name: string): Record<string, unknown>;
|
package/dist/adapters/piMcp.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* unchanged. sse is not a pi transport — the adapter turns sse servers
|
|
12
12
|
* into conflict items rather than writing entries pi cannot connect.
|
|
13
13
|
*/
|
|
14
|
+
import { isOAuthAuth } from "../core/types.js";
|
|
14
15
|
import { resolvedEnvTextMap } from "../lib/mcpMigrateRead.js";
|
|
15
16
|
/** The pi release that introduced the native MCP client (`pi mcp`,
|
|
16
17
|
* `~/.pi/agent/mcp.json`). */
|
|
@@ -37,9 +38,12 @@ export function supportsNativeMcp(version) {
|
|
|
37
38
|
* `pi mcp add` writes (observed 2026-10-11): stdio as
|
|
38
39
|
* `{command, args, env?}`, http as `{url, headers?}`, no `type` field.
|
|
39
40
|
* `env` names render as `${VAR}` references exactly like the other JSON
|
|
40
|
-
* agents; OAuth `auth` metadata is Trellis-side routing information and
|
|
41
|
-
*
|
|
42
|
-
* entry
|
|
41
|
+
* agents; OAuth `auth` metadata is Trellis-side routing information and is
|
|
42
|
+
* never rendered — with one exception: a declared `auth.client_name` becomes
|
|
43
|
+
* the entry's `oauth.clientName`, the field `pi mcp add --oauth-client-name`
|
|
44
|
+
* writes, so providers that gate dynamic client registration by client name
|
|
45
|
+
* (Figma) accept `pi mcp login`'s registration and later syncs compare equal
|
|
46
|
+
* instead of stripping the block (oauth-client-name design.md D2).
|
|
43
47
|
*/
|
|
44
48
|
export function piRenderer(def, _name) {
|
|
45
49
|
if (def.transport === "http" || def.transport === "sse") {
|
|
@@ -47,6 +51,9 @@ export function piRenderer(def, _name) {
|
|
|
47
51
|
if (def.headers && Object.keys(def.headers).length > 0) {
|
|
48
52
|
entry.headers = def.headers;
|
|
49
53
|
}
|
|
54
|
+
if (isOAuthAuth(def.auth) && typeof def.auth === "object" && def.auth.clientName !== undefined) {
|
|
55
|
+
entry.oauth = { clientName: def.auth.clientName };
|
|
56
|
+
}
|
|
50
57
|
return entry;
|
|
51
58
|
}
|
|
52
59
|
const entry = { command: def.command, args: def.args ?? [] };
|
package/dist/core/canonical.d.ts
CHANGED
|
@@ -10,9 +10,10 @@ import type { BackupSession } from "../lib/backup.js";
|
|
|
10
10
|
* The on-disk shape for one server entry — `static_env`/`env_aliases`
|
|
11
11
|
* (snake_case, like every other multi-word key across `.trellis/*.yaml`)
|
|
12
12
|
* are translated to `McpServerDef.staticEnv`/`envAliases` (camelCase)
|
|
13
|
-
* below, and `auth`'s object form carries `client_id`/`client_secret_env
|
|
14
|
-
* the same way (trellis-mcp-static-env-and-disabled-servers,
|
|
15
|
-
* trellis-migrate-env-var-alias, trellis-mcp-oauth-static-client
|
|
13
|
+
* below, and `auth`'s object form carries `client_id`/`client_secret_env`/
|
|
14
|
+
* `client_name` the same way (trellis-mcp-static-env-and-disabled-servers,
|
|
15
|
+
* trellis-migrate-env-var-alias, trellis-mcp-oauth-static-client,
|
|
16
|
+
* oauth-client-name).
|
|
16
17
|
*/
|
|
17
18
|
type McpServerDefYaml = Omit<McpServerDef, "staticEnv" | "envAliases" | "auth"> & {
|
|
18
19
|
static_env?: Record<string, string>;
|
|
@@ -28,6 +29,7 @@ type McpAuthYaml = string | {
|
|
|
28
29
|
owner?: unknown;
|
|
29
30
|
client_id?: unknown;
|
|
30
31
|
client_secret_env?: unknown;
|
|
32
|
+
client_name?: unknown;
|
|
31
33
|
};
|
|
32
34
|
/** Inverse of `fromServerDefYaml` (trellis-canonical-cli-crud) — strips
|
|
33
35
|
* `undefined` fields so the written YAML never gets a literal `null`
|
package/dist/core/canonical.js
CHANGED
|
@@ -34,12 +34,12 @@ function fromAuthYaml(serverName, auth) {
|
|
|
34
34
|
if (auth === "oauth")
|
|
35
35
|
return "oauth";
|
|
36
36
|
if (typeof auth !== "object" || auth === null) {
|
|
37
|
-
throw new Error(`mcp/servers.yaml: "${serverName}" auth must be the scalar "oauth" or { kind: oauth, client_id?, client_secret_env? }`);
|
|
37
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth must be the scalar "oauth" or { kind: oauth, client_id?, client_secret_env?, client_name? }`);
|
|
38
38
|
}
|
|
39
|
-
const { kind, owner, client_id, client_secret_env, ...extra } = auth;
|
|
39
|
+
const { kind, owner, client_id, client_secret_env, client_name, ...extra } = auth;
|
|
40
40
|
const unknownKey = Object.keys(extra)[0];
|
|
41
41
|
if (unknownKey !== undefined) {
|
|
42
|
-
throw new Error(`mcp/servers.yaml: "${serverName}" auth has unrecognized key "${unknownKey}" — expected kind, owner, client_id, client_secret_env`);
|
|
42
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth has unrecognized key "${unknownKey}" — expected kind, owner, client_id, client_secret_env, client_name`);
|
|
43
43
|
}
|
|
44
44
|
if (kind !== "oauth") {
|
|
45
45
|
throw new Error(`mcp/servers.yaml: "${serverName}" auth.kind must be "oauth" — kind is the only recognized discriminator`);
|
|
@@ -50,6 +50,9 @@ function fromAuthYaml(serverName, auth) {
|
|
|
50
50
|
if (client_secret_env !== undefined && (typeof client_secret_env !== "string" || !isValidSecretVarName(client_secret_env))) {
|
|
51
51
|
throw new Error(`mcp/servers.yaml: "${serverName}" auth.client_secret_env must be a variable NAME (e.g. FIGMA_CLIENT_SECRET), never a secret value`);
|
|
52
52
|
}
|
|
53
|
+
if (client_name !== undefined && typeof client_name !== "string") {
|
|
54
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth.client_name must be a string`);
|
|
55
|
+
}
|
|
53
56
|
const out = { kind: "oauth" };
|
|
54
57
|
if (owner !== undefined && owner !== "agent" && owner !== "trellis")
|
|
55
58
|
throw new Error(`mcp/servers.yaml: "${serverName}" auth.owner must be agent or trellis`);
|
|
@@ -59,6 +62,8 @@ function fromAuthYaml(serverName, auth) {
|
|
|
59
62
|
out.clientId = client_id;
|
|
60
63
|
if (typeof client_secret_env === "string")
|
|
61
64
|
out.clientSecretEnv = client_secret_env;
|
|
65
|
+
if (typeof client_name === "string")
|
|
66
|
+
out.clientName = client_name;
|
|
62
67
|
return out;
|
|
63
68
|
}
|
|
64
69
|
/** Inverse of `fromServerDefYaml` (trellis-canonical-cli-crud) — strips
|
|
@@ -80,6 +85,7 @@ export function toServerDefYaml(def) {
|
|
|
80
85
|
...(auth.owner !== undefined ? { owner: auth.owner } : {}),
|
|
81
86
|
...(auth.clientId !== undefined ? { client_id: auth.clientId } : {}),
|
|
82
87
|
...(auth.clientSecretEnv !== undefined ? { client_secret_env: auth.clientSecretEnv } : {}),
|
|
88
|
+
...(auth.clientName !== undefined ? { client_name: auth.clientName } : {}),
|
|
83
89
|
};
|
|
84
90
|
}
|
|
85
91
|
for (const key of Object.keys(out)) {
|
package/dist/core/types.d.ts
CHANGED
|
@@ -19,6 +19,10 @@ export interface McpAuthConfig {
|
|
|
19
19
|
owner?: "agent" | "trellis";
|
|
20
20
|
clientId?: string;
|
|
21
21
|
clientSecretEnv?: string;
|
|
22
|
+
/** Self-asserted display name an Agent presents at dynamic client
|
|
23
|
+
* registration — for providers that gate DCR by client name (Figma).
|
|
24
|
+
* Public metadata, not a credential (oauth-client-name design.md D1). */
|
|
25
|
+
clientName?: string;
|
|
22
26
|
}
|
|
23
27
|
/** True when `auth` classifies the server as OAuth, in either form. Every
|
|
24
28
|
* former `def.auth === "oauth"` check must go through this now that the
|
package/dist/pi-bridge/bundle.js
CHANGED
|
@@ -7948,12 +7948,12 @@ function fromServerDefYaml(serverName, def) {
|
|
|
7948
7948
|
function fromAuthYaml(serverName, auth2) {
|
|
7949
7949
|
if (auth2 === "oauth") return "oauth";
|
|
7950
7950
|
if (typeof auth2 !== "object" || auth2 === null) {
|
|
7951
|
-
throw new Error(`mcp/servers.yaml: "${serverName}" auth must be the scalar "oauth" or { kind: oauth, client_id?, client_secret_env? }`);
|
|
7951
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth must be the scalar "oauth" or { kind: oauth, client_id?, client_secret_env?, client_name? }`);
|
|
7952
7952
|
}
|
|
7953
|
-
const { kind, owner, client_id, client_secret_env, ...extra } = auth2;
|
|
7953
|
+
const { kind, owner, client_id, client_secret_env, client_name, ...extra } = auth2;
|
|
7954
7954
|
const unknownKey = Object.keys(extra)[0];
|
|
7955
7955
|
if (unknownKey !== void 0) {
|
|
7956
|
-
throw new Error(`mcp/servers.yaml: "${serverName}" auth has unrecognized key "${unknownKey}" \u2014 expected kind, owner, client_id, client_secret_env`);
|
|
7956
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth has unrecognized key "${unknownKey}" \u2014 expected kind, owner, client_id, client_secret_env, client_name`);
|
|
7957
7957
|
}
|
|
7958
7958
|
if (kind !== "oauth") {
|
|
7959
7959
|
throw new Error(`mcp/servers.yaml: "${serverName}" auth.kind must be "oauth" \u2014 kind is the only recognized discriminator`);
|
|
@@ -7964,11 +7964,15 @@ function fromAuthYaml(serverName, auth2) {
|
|
|
7964
7964
|
if (client_secret_env !== void 0 && (typeof client_secret_env !== "string" || !isValidSecretVarName(client_secret_env))) {
|
|
7965
7965
|
throw new Error(`mcp/servers.yaml: "${serverName}" auth.client_secret_env must be a variable NAME (e.g. FIGMA_CLIENT_SECRET), never a secret value`);
|
|
7966
7966
|
}
|
|
7967
|
+
if (client_name !== void 0 && typeof client_name !== "string") {
|
|
7968
|
+
throw new Error(`mcp/servers.yaml: "${serverName}" auth.client_name must be a string`);
|
|
7969
|
+
}
|
|
7967
7970
|
const out = { kind: "oauth" };
|
|
7968
7971
|
if (owner !== void 0 && owner !== "agent" && owner !== "trellis") throw new Error(`mcp/servers.yaml: "${serverName}" auth.owner must be agent or trellis`);
|
|
7969
7972
|
if (owner !== void 0) out.owner = owner;
|
|
7970
7973
|
if (typeof client_id === "string") out.clientId = client_id;
|
|
7971
7974
|
if (typeof client_secret_env === "string") out.clientSecretEnv = client_secret_env;
|
|
7975
|
+
if (typeof client_name === "string") out.clientName = client_name;
|
|
7972
7976
|
return out;
|
|
7973
7977
|
}
|
|
7974
7978
|
function trellisRoot(homeDir) {
|
package/docs/getting-started.md
CHANGED
|
@@ -309,6 +309,22 @@ Two pi-specific behaviors to know:
|
|
|
309
309
|
run `pi mcp login <name>` once; the grant lives in pi's own token store
|
|
310
310
|
(`~/.pi/agent/mcp-auth.json`), and `trellis.mcp.status` reports them as
|
|
311
311
|
`agent-managed`.
|
|
312
|
+
- Some providers (Figma, while in beta) gate OAuth dynamic client
|
|
313
|
+
registration by an allowlisted `client_name`, which rejects pi's default.
|
|
314
|
+
Declare the name canonically and pi registers under it:
|
|
315
|
+
|
|
316
|
+
```yaml
|
|
317
|
+
figma:
|
|
318
|
+
transport: http
|
|
319
|
+
url: https://mcp.figma.com/mcp
|
|
320
|
+
auth:
|
|
321
|
+
kind: oauth
|
|
322
|
+
client_name: Claude Code
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
Trellis then writes `oauth.clientName` into the pi entry — the same field
|
|
326
|
+
`pi mcp add --oauth-client-name` writes — so syncs converge instead of
|
|
327
|
+
stripping it.
|
|
312
328
|
|
|
313
329
|
On pi older than 1.1.0 nothing changes: the bridge extension remains the
|
|
314
330
|
delivery mechanism and `mcp.json` is never written.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-trellis",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "A unified Code Agent Runtime for Skills, MCP, Memory, and shared instructions across Claude Code, Codex, Kiro, pi, Kimi Code, and ZCode.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Paul Leo",
|