@agentmesh-p2p/sdk 0.1.0 → 0.2.0
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 +60 -0
- package/dist/auth.d.ts +2 -1
- package/dist/auth.js +3 -2
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +117 -0
- package/dist/controlplane.d.ts +2 -2
- package/dist/controlplane.js +15 -12
- package/dist/discovery.js +3 -3
- package/dist/gen/agentmesh_pb.d.ts +133 -2
- package/dist/gen/agentmesh_pb.js +111 -72
- package/dist/gen/datalog.d.ts +2 -0
- package/dist/gen/datalog.js +9 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp-server.d.ts +8 -0
- package/dist/mcp-server.js +305 -0
- package/dist/mcp.js +1 -1
- package/dist/mesh.d.ts +7 -3
- package/dist/mesh.js +19 -8
- package/dist/session.d.ts +23 -4
- package/dist/session.js +63 -17
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -24,6 +24,66 @@ Requires Node.js 22.18 or later. In a browser, bundle it with the page
|
|
|
24
24
|
[In a browser](https://google.github.io/agentmesh/docs/guides/native-sdks/#in-a-browser)
|
|
25
25
|
section has the details and an example page.
|
|
26
26
|
|
|
27
|
+
## MCP client over stdio
|
|
28
|
+
|
|
29
|
+
The package's `agentmesh` executable joins as its own mesh member and exposes
|
|
30
|
+
five MCP tools: `get_mesh_info`, `discover_remote_services`, `find_remote_tools`,
|
|
31
|
+
`describe_remote_tool` and `call_remote_tool`. A stdio-capable MCP client starts
|
|
32
|
+
and stops the process; no node daemon is needed for this caller. Providers still
|
|
33
|
+
publish their services through `agentmesh-node`.
|
|
34
|
+
|
|
35
|
+
To try the executable from a source checkout:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd sdk/js
|
|
39
|
+
npm ci
|
|
40
|
+
npm run build
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use absolute paths in your MCP client's configuration:
|
|
44
|
+
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"agentmesh": {
|
|
49
|
+
"command": "node",
|
|
50
|
+
"args": ["/absolute/path/to/agentmesh/sdk/js/dist/cli.js"],
|
|
51
|
+
"env": {
|
|
52
|
+
"AGENTMESH_CONTROL_PLANE_URL": "https://your-control-plane.example",
|
|
53
|
+
"AGENTMESH_BOOTSTRAP_TOKEN_PATH": "/absolute/path/to/join-token",
|
|
54
|
+
"AGENTMESH_STATE_DIR": "/absolute/path/to/this-client-identity"
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Get the control plane URL and token file from your mesh operator or
|
|
62
|
+
[`agentmesh-one`](https://google.github.io/agentmesh/docs/guides/native-sdks/).
|
|
63
|
+
Alternatively, set `AGENTMESH_JWT_PATH` to a workload/OIDC token file; do not set
|
|
64
|
+
both token paths. Credentials are read from files, never command-line values.
|
|
65
|
+
|
|
66
|
+
The first run enrolls and saves its identity; later runs resume from the state
|
|
67
|
+
directory without the bootstrap token. JWT enrollment rereads the token file
|
|
68
|
+
when refreshing. Use a distinct state directory for each client identity and
|
|
69
|
+
mesh; do not run multiple processes against the same directory. The default is
|
|
70
|
+
`~/.config/agentmesh/mcp`. Plain HTTP is allowed on loopback only unless
|
|
71
|
+
`AGENTMESH_INSECURE_CONTROL_PLANE=true` explicitly permits it elsewhere.
|
|
72
|
+
|
|
73
|
+
Stdout contains only MCP messages; diagnostics go to stderr. Closing stdin or
|
|
74
|
+
sending SIGINT/SIGTERM shuts down the mesh session. Tool calls use the member's
|
|
75
|
+
existing authenticated streams and policy, including provider label checks.
|
|
76
|
+
Remote tool results retain text, non-text content, structured output and errors.
|
|
77
|
+
Discovery follows tool pagination, rejects looping catalogs and bounds each
|
|
78
|
+
search to 64 providers, 256 services per provider, 256 tools per service and
|
|
79
|
+
1024 results. Requests have a 10-second deadline; narrow a large search by peer
|
|
80
|
+
or service. `intent` is accepted but ignored, matching the node's current tool.
|
|
81
|
+
|
|
82
|
+
This member publishes no services, so it has no `list_local_services` tool.
|
|
83
|
+
Inference and A2A discovery return metadata, but this executable provides no
|
|
84
|
+
HTTP proxy, `/v1` endpoint, local socket or `local_proxy_url`. Use an SDK client
|
|
85
|
+
or an `agentmesh-node` HTTP proxy to invoke those protocols.
|
|
86
|
+
|
|
27
87
|
## Use
|
|
28
88
|
|
|
29
89
|
Both programs below are in
|
package/dist/auth.d.ts
CHANGED
|
@@ -21,8 +21,9 @@ export declare class AuthRejectedError extends Error {
|
|
|
21
21
|
/**
|
|
22
22
|
* Client side: presents frame on a new /mesh/auth/1.0.0 stream and returns
|
|
23
23
|
* the peer's verified credential. trustedKeys are the control plane keys.
|
|
24
|
+
* The handshake has a timeout of its own; outer, when given, can end it sooner.
|
|
24
25
|
*/
|
|
25
|
-
export declare function authenticateWithPeer(conn: Connection, frame: Uint8Array, trustedKeys: Uint8Array[]): Promise<VerifiedBiscuit>;
|
|
26
|
+
export declare function authenticateWithPeer(conn: Connection, frame: Uint8Array, trustedKeys: Uint8Array[], outer?: AbortSignal): Promise<VerifiedBiscuit>;
|
|
26
27
|
export interface AuthServerOptions {
|
|
27
28
|
/** This member's current biscuit, read per handshake so a refresh takes effect. */
|
|
28
29
|
ownBiscuit(): Uint8Array;
|
package/dist/auth.js
CHANGED
|
@@ -45,9 +45,10 @@ function framed(stream) {
|
|
|
45
45
|
/**
|
|
46
46
|
* Client side: presents frame on a new /mesh/auth/1.0.0 stream and returns
|
|
47
47
|
* the peer's verified credential. trustedKeys are the control plane keys.
|
|
48
|
+
* The handshake has a timeout of its own; outer, when given, can end it sooner.
|
|
48
49
|
*/
|
|
49
|
-
export async function authenticateWithPeer(conn, frame, trustedKeys) {
|
|
50
|
-
const signal = AbortSignal.timeout(AUTH_HANDSHAKE_TIMEOUT_MS);
|
|
50
|
+
export async function authenticateWithPeer(conn, frame, trustedKeys, outer) {
|
|
51
|
+
const signal = outer === undefined ? AbortSignal.timeout(AUTH_HANDSHAKE_TIMEOUT_MS) : AbortSignal.any([outer, AbortSignal.timeout(AUTH_HANDSHAKE_TIMEOUT_MS)]);
|
|
51
52
|
// A peer behind a router is reached over a relayed, limited connection.
|
|
52
53
|
const stream = await conn.newStream(AUTH_PROTOCOL, { signal, runOnLimitedConnection: true });
|
|
53
54
|
try {
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Copyright 2026 Google LLC
|
|
3
|
+
//
|
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
// you may not use this file except in compliance with the License.
|
|
6
|
+
// You may obtain a copy of the License at
|
|
7
|
+
//
|
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
//
|
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
// See the License for the specific language governing permissions and
|
|
14
|
+
// limitations under the License.
|
|
15
|
+
import { readFile } from "node:fs/promises";
|
|
16
|
+
import { homedir } from "node:os";
|
|
17
|
+
import { isAbsolute, join } from "node:path";
|
|
18
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
19
|
+
import { AgentMesh } from "./mesh.js";
|
|
20
|
+
import { createMeshMCPServer } from "./mcp-server.js";
|
|
21
|
+
function options() {
|
|
22
|
+
const env = process.env;
|
|
23
|
+
const controlPlaneUrl = env.AGENTMESH_CONTROL_PLANE_URL?.trim();
|
|
24
|
+
if (!controlPlaneUrl)
|
|
25
|
+
throw new Error("AGENTMESH_CONTROL_PLANE_URL is required");
|
|
26
|
+
if (env.AGENTMESH_BOOTSTRAP_TOKEN_PATH && env.AGENTMESH_JWT_PATH) {
|
|
27
|
+
throw new Error("set only one of AGENTMESH_BOOTSTRAP_TOKEN_PATH and AGENTMESH_JWT_PATH");
|
|
28
|
+
}
|
|
29
|
+
if (env.AGENTMESH_INSECURE_CONTROL_PLANE && !["true", "false"].includes(env.AGENTMESH_INSECURE_CONTROL_PLANE)) {
|
|
30
|
+
throw new Error("AGENTMESH_INSECURE_CONTROL_PLANE must be true or false");
|
|
31
|
+
}
|
|
32
|
+
// A client launches this from any working directory; a relative path would
|
|
33
|
+
// silently read credentials or enrol an identity somewhere unexpected.
|
|
34
|
+
for (const name of ["AGENTMESH_BOOTSTRAP_TOKEN_PATH", "AGENTMESH_JWT_PATH", "AGENTMESH_STATE_DIR"]) {
|
|
35
|
+
if (env[name] && !isAbsolute(env[name]))
|
|
36
|
+
throw new Error(`${name} must be an absolute path`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
controlPlaneUrl,
|
|
40
|
+
bootstrapTokenPath: env.AGENTMESH_BOOTSTRAP_TOKEN_PATH || undefined,
|
|
41
|
+
jwtPath: env.AGENTMESH_JWT_PATH || undefined,
|
|
42
|
+
stateDir: env.AGENTMESH_STATE_DIR || join(homedir(), ".config", "agentmesh", "mcp"),
|
|
43
|
+
allowInsecure: env.AGENTMESH_INSECURE_CONTROL_PLANE === "true",
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async function main() {
|
|
47
|
+
if (process.argv.length > 2) {
|
|
48
|
+
if (process.argv.length !== 3 || !["--help", "-h"].includes(process.argv[2])) {
|
|
49
|
+
throw new Error("agentmesh accepts no arguments other than --help; configure it through AGENTMESH_* environment variables");
|
|
50
|
+
}
|
|
51
|
+
console.error("agentmesh: MCP over stdio\n" +
|
|
52
|
+
"AGENTMESH_CONTROL_PLANE_URL Mesh control plane URL (required)\n" +
|
|
53
|
+
"AGENTMESH_BOOTSTRAP_TOKEN_PATH Bootstrap token file for first enrollment\n" +
|
|
54
|
+
"AGENTMESH_JWT_PATH OIDC/workload token file, read again on refresh\n" +
|
|
55
|
+
"AGENTMESH_STATE_DIR Identity directory (default: ~/.config/agentmesh/mcp)\n" +
|
|
56
|
+
"AGENTMESH_INSECURE_CONTROL_PLANE true permits plaintext HTTP beyond loopback (default: false)");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const config = options();
|
|
60
|
+
const { version } = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8"));
|
|
61
|
+
const abort = new AbortController();
|
|
62
|
+
let stop;
|
|
63
|
+
const stopped = new Promise((resolve) => { stop = () => { abort.abort(); resolve(); }; });
|
|
64
|
+
process.once("SIGINT", stop);
|
|
65
|
+
process.once("SIGTERM", stop);
|
|
66
|
+
process.stdin.once("end", stop);
|
|
67
|
+
let session;
|
|
68
|
+
const ready = AgentMesh.enroll({
|
|
69
|
+
...config,
|
|
70
|
+
signal: abort.signal,
|
|
71
|
+
// EnrollOptions.signal bounds pending approval, not every HTTP request.
|
|
72
|
+
// The executable owns this client: shutdown must also cancel enrollment,
|
|
73
|
+
// credential resume and key fetches while the control plane is silent.
|
|
74
|
+
fetch: (input, init) => fetch(input, {
|
|
75
|
+
...init,
|
|
76
|
+
signal: AbortSignal.any([abort.signal, ...(init?.signal ? [init.signal] : [])]),
|
|
77
|
+
}),
|
|
78
|
+
}).then(async (mesh) => {
|
|
79
|
+
session = await mesh.join({ signal: abort.signal });
|
|
80
|
+
return session;
|
|
81
|
+
});
|
|
82
|
+
// Handle startup failure immediately, including before a client calls a tool.
|
|
83
|
+
void ready.catch((err) => {
|
|
84
|
+
if (!abort.signal.aborted) {
|
|
85
|
+
console.error(`agentmesh: ${err instanceof Error ? err.message : String(err)}`);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
}
|
|
88
|
+
stop();
|
|
89
|
+
});
|
|
90
|
+
const server = createMeshMCPServer(ready, version);
|
|
91
|
+
server.server.onclose = stop;
|
|
92
|
+
try {
|
|
93
|
+
await server.connect(new StdioServerTransport());
|
|
94
|
+
await stopped;
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
stop();
|
|
98
|
+
try {
|
|
99
|
+
await server.close();
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
await ready.catch(() => undefined);
|
|
103
|
+
try {
|
|
104
|
+
await session?.close();
|
|
105
|
+
}
|
|
106
|
+
finally {
|
|
107
|
+
process.removeListener("SIGINT", stop);
|
|
108
|
+
process.removeListener("SIGTERM", stop);
|
|
109
|
+
process.stdin.removeListener("end", stop);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
void main().catch((err) => {
|
|
115
|
+
console.error(`agentmesh: ${err instanceof Error ? err.message : String(err)}`);
|
|
116
|
+
process.exitCode = 1;
|
|
117
|
+
});
|
package/dist/controlplane.d.ts
CHANGED
|
@@ -95,12 +95,12 @@ export declare class ControlPlaneClient {
|
|
|
95
95
|
readonly url: URL;
|
|
96
96
|
constructor(options: ControlPlaneClientOptions);
|
|
97
97
|
/** GET /info: OIDC settings, router addresses and the ban list. Unauthenticated. */
|
|
98
|
-
info(): Promise<ControlPlaneInfoResponse>;
|
|
98
|
+
info(signal?: AbortSignal): Promise<ControlPlaneInfoResponse>;
|
|
99
99
|
/**
|
|
100
100
|
* GET /keys: every signing key the control plane currently trusts,
|
|
101
101
|
* verified against a key the caller already trusts (the enrollment key).
|
|
102
102
|
*/
|
|
103
|
-
keys(trusted: Uint8Array[]): Promise<Uint8Array[]>;
|
|
103
|
+
keys(trusted: Uint8Array[], signal?: AbortSignal): Promise<Uint8Array[]>;
|
|
104
104
|
/**
|
|
105
105
|
* POST /enroll with a bootstrap token, then GET /enroll/status until an
|
|
106
106
|
* operator approves the request if the mesh is not on auto-approve.
|
package/dist/controlplane.js
CHANGED
|
@@ -164,16 +164,16 @@ export class ControlPlaneClient {
|
|
|
164
164
|
this.#now = options.now ?? (() => Date.now());
|
|
165
165
|
}
|
|
166
166
|
/** GET /info: OIDC settings, router addresses and the ban list. Unauthenticated. */
|
|
167
|
-
async info() {
|
|
168
|
-
const body = await this.#request("GET", "/info");
|
|
167
|
+
async info(signal) {
|
|
168
|
+
const body = await this.#request("GET", "/info", undefined, {}, signal);
|
|
169
169
|
return fromBinary(ControlPlaneInfoResponseSchema, body);
|
|
170
170
|
}
|
|
171
171
|
/**
|
|
172
172
|
* GET /keys: every signing key the control plane currently trusts,
|
|
173
173
|
* verified against a key the caller already trusts (the enrollment key).
|
|
174
174
|
*/
|
|
175
|
-
async keys(trusted) {
|
|
176
|
-
const body = await this.#request("GET", "/keys");
|
|
175
|
+
async keys(trusted, signal) {
|
|
176
|
+
const body = await this.#request("GET", "/keys", undefined, {}, signal);
|
|
177
177
|
return verifyKeysResponse(fromBinary(KeysResponseSchema, body), trusted, this.#now());
|
|
178
178
|
}
|
|
179
179
|
/**
|
|
@@ -304,14 +304,14 @@ export class ControlPlaneClient {
|
|
|
304
304
|
}
|
|
305
305
|
throw new ControlPlaneError(path, outcome.status, text);
|
|
306
306
|
}
|
|
307
|
-
async #fetchOnce(method, path, body, headers = {}) {
|
|
308
|
-
|
|
309
|
-
const
|
|
307
|
+
async #fetchOnce(method, path, body, headers = {}, signal) {
|
|
308
|
+
// The caller's signal cancels the request itself, not only the wait for it.
|
|
309
|
+
const timeout = AbortSignal.timeout(this.#timeoutMs);
|
|
310
310
|
try {
|
|
311
311
|
const init = {
|
|
312
312
|
method,
|
|
313
313
|
headers: { Accept: PROTOBUF_CONTENT_TYPE, ...headers },
|
|
314
|
-
signal:
|
|
314
|
+
signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),
|
|
315
315
|
};
|
|
316
316
|
if (body !== undefined) {
|
|
317
317
|
init.body = new Uint8Array(body);
|
|
@@ -324,12 +324,15 @@ export class ControlPlaneClient {
|
|
|
324
324
|
}
|
|
325
325
|
return { ok: resp.ok, status: resp.status, buf, dateHeader: resp.headers.get("date") };
|
|
326
326
|
}
|
|
327
|
-
|
|
328
|
-
|
|
327
|
+
catch (err) {
|
|
328
|
+
if (timeout.aborted && signal?.aborted !== true) {
|
|
329
|
+
throw new Error(`control plane ${path}: timed out after ${this.#timeoutMs}ms`);
|
|
330
|
+
}
|
|
331
|
+
throw err;
|
|
329
332
|
}
|
|
330
333
|
}
|
|
331
|
-
async #request(method, path, body, headers = {}) {
|
|
332
|
-
const outcome = await this.#fetchOnce(method, path, body, headers);
|
|
334
|
+
async #request(method, path, body, headers = {}, signal) {
|
|
335
|
+
const outcome = await this.#fetchOnce(method, path, body, headers, signal);
|
|
333
336
|
if (!outcome.ok) {
|
|
334
337
|
throw new ControlPlaneError(path, outcome.status, new TextDecoder().decode(outcome.buf));
|
|
335
338
|
}
|
package/dist/discovery.js
CHANGED
|
@@ -84,7 +84,7 @@ async function ask(conn, req, signal) {
|
|
|
84
84
|
*/
|
|
85
85
|
export async function request(routers, req, signal) {
|
|
86
86
|
const lookup = req.request.case === "findProviders" || req.request.case === "findPeer";
|
|
87
|
-
|
|
87
|
+
const failures = [];
|
|
88
88
|
let asked = 0;
|
|
89
89
|
let empty;
|
|
90
90
|
for (const router of routers) {
|
|
@@ -103,7 +103,7 @@ export async function request(routers, req, signal) {
|
|
|
103
103
|
return resp;
|
|
104
104
|
}
|
|
105
105
|
catch (err) {
|
|
106
|
-
|
|
106
|
+
failures.push(`${router.peerId}: ${err instanceof Error ? err.message : String(err)}`);
|
|
107
107
|
if (signal?.aborted === true) {
|
|
108
108
|
break;
|
|
109
109
|
}
|
|
@@ -115,7 +115,7 @@ export async function request(routers, req, signal) {
|
|
|
115
115
|
if (asked === 0) {
|
|
116
116
|
throw new DirectoryError("no held router to ask");
|
|
117
117
|
}
|
|
118
|
-
throw new DirectoryError(`no held router answered: ${
|
|
118
|
+
throw new DirectoryError(`no held router answered: ${failures.join("; ")}`);
|
|
119
119
|
}
|
|
120
120
|
/**
|
|
121
121
|
* Announces this member as a provider of key, reached at addrs, to a held
|
|
@@ -344,6 +344,37 @@ export type BootstrapEnrollResponse = Message<"agentmesh.v1.BootstrapEnrollRespo
|
|
|
344
344
|
* Use `create(BootstrapEnrollResponseSchema)` to create a new message.
|
|
345
345
|
*/
|
|
346
346
|
export declare const BootstrapEnrollResponseSchema: GenMessage<BootstrapEnrollResponse>;
|
|
347
|
+
/**
|
|
348
|
+
* ServiceIngress configures external router HTTP ingress for an inbound service
|
|
349
|
+
* (a2a, mcp, or inference). Absent means the service is reachable only inside
|
|
350
|
+
* the mesh.
|
|
351
|
+
*
|
|
352
|
+
* @generated from message agentmesh.v1.ServiceIngress
|
|
353
|
+
*/
|
|
354
|
+
export type ServiceIngress = Message<"agentmesh.v1.ServiceIngress"> & {
|
|
355
|
+
/**
|
|
356
|
+
* Defaults to INGRESS_AUTH_MODE_EDGE when UNSPECIFIED.
|
|
357
|
+
*
|
|
358
|
+
* @generated from field: agentmesh.v1.IngressAuthMode auth_mode = 1;
|
|
359
|
+
*/
|
|
360
|
+
authMode: IngressAuthMode;
|
|
361
|
+
/**
|
|
362
|
+
* Optional caller narrowing in PolicyBinding.members syntax
|
|
363
|
+
* (e.g. "email:alice@example.com", "email:*@example.com", "group:eng").
|
|
364
|
+
* Intersected (AND) with mesh Datalog policy: when empty, any caller
|
|
365
|
+
* authorized by mesh policy for this service may invoke it; when non-empty,
|
|
366
|
+
* the verified caller must also match at least one entry here. Only allowed
|
|
367
|
+
* in INGRESS_AUTH_MODE_EDGE.
|
|
368
|
+
*
|
|
369
|
+
* @generated from field: repeated string allow = 2;
|
|
370
|
+
*/
|
|
371
|
+
allow: string[];
|
|
372
|
+
};
|
|
373
|
+
/**
|
|
374
|
+
* Describes the message agentmesh.v1.ServiceIngress.
|
|
375
|
+
* Use `create(ServiceIngressSchema)` to create a new message.
|
|
376
|
+
*/
|
|
377
|
+
export declare const ServiceIngressSchema: GenMessage<ServiceIngress>;
|
|
347
378
|
/**
|
|
348
379
|
* @generated from message agentmesh.v1.ServiceInfo
|
|
349
380
|
*/
|
|
@@ -360,6 +391,12 @@ export type ServiceInfo = Message<"agentmesh.v1.ServiceInfo"> & {
|
|
|
360
391
|
* @generated from field: string description = 3;
|
|
361
392
|
*/
|
|
362
393
|
description: string;
|
|
394
|
+
/**
|
|
395
|
+
* Optional external ingress exposure for this service.
|
|
396
|
+
*
|
|
397
|
+
* @generated from field: agentmesh.v1.ServiceIngress ingress = 4;
|
|
398
|
+
*/
|
|
399
|
+
ingress?: ServiceIngress | undefined;
|
|
363
400
|
};
|
|
364
401
|
/**
|
|
365
402
|
* Describes the message agentmesh.v1.ServiceInfo.
|
|
@@ -621,6 +658,14 @@ export type DirectoryProvide = Message<"agentmesh.v1.DirectoryProvide"> & {
|
|
|
621
658
|
* @generated from field: string service = 4;
|
|
622
659
|
*/
|
|
623
660
|
service: string;
|
|
661
|
+
/**
|
|
662
|
+
* Optional external ingress metadata for a named service record. When set,
|
|
663
|
+
* the router verifies that the provider's credential grants exposing this
|
|
664
|
+
* service with the requested auth_mode before storing or replicating it.
|
|
665
|
+
*
|
|
666
|
+
* @generated from field: agentmesh.v1.ServiceIngress ingress = 5;
|
|
667
|
+
*/
|
|
668
|
+
ingress?: ServiceIngress | undefined;
|
|
624
669
|
};
|
|
625
670
|
/**
|
|
626
671
|
* Describes the message agentmesh.v1.DirectoryProvide.
|
|
@@ -727,6 +772,12 @@ export type PeerRecord = Message<"agentmesh.v1.PeerRecord"> & {
|
|
|
727
772
|
* @generated from field: repeated string addrs = 2;
|
|
728
773
|
*/
|
|
729
774
|
addrs: string[];
|
|
775
|
+
/**
|
|
776
|
+
* Present on service provider records that opted into external ingress.
|
|
777
|
+
*
|
|
778
|
+
* @generated from field: agentmesh.v1.ServiceIngress ingress = 3;
|
|
779
|
+
*/
|
|
780
|
+
ingress?: ServiceIngress | undefined;
|
|
730
781
|
};
|
|
731
782
|
/**
|
|
732
783
|
* Describes the message agentmesh.v1.PeerRecord.
|
|
@@ -753,8 +804,8 @@ export type RouterInfo = Message<"agentmesh.v1.RouterInfo"> & {
|
|
|
753
804
|
* The router's labels, the same labels as a node's: declared at
|
|
754
805
|
* enrollment (agentmesh-router --label), signed by the control plane only
|
|
755
806
|
* if the router's role allows them (PolicyRole.allowed_labels), and
|
|
756
|
-
* carried as label() facts in the router's credential
|
|
757
|
-
*
|
|
807
|
+
* carried as label() facts in the router's credential. A member selects
|
|
808
|
+
* routers by the labels listed here, before it connects
|
|
758
809
|
* (--router-selector, every pair must match) or prefers routers by them
|
|
759
810
|
* (--router-prefer). They place a router; they grant it nothing.
|
|
760
811
|
*
|
|
@@ -775,6 +826,14 @@ export type RouterInfo = Message<"agentmesh.v1.RouterInfo"> & {
|
|
|
775
826
|
* @generated from field: int32 connection_limit = 5;
|
|
776
827
|
*/
|
|
777
828
|
connectionLimit: number;
|
|
829
|
+
/**
|
|
830
|
+
* Base HTTPS/HTTP URL where this router serves external ingress, without a
|
|
831
|
+
* trailing slash (e.g. "https://bananas.sam-mesh.dev/ingress"). Empty when
|
|
832
|
+
* external ingress is disabled on this router.
|
|
833
|
+
*
|
|
834
|
+
* @generated from field: string ingress_url = 6;
|
|
835
|
+
*/
|
|
836
|
+
ingressUrl: string;
|
|
778
837
|
};
|
|
779
838
|
/**
|
|
780
839
|
* Describes the message agentmesh.v1.RouterInfo.
|
|
@@ -840,6 +899,12 @@ export type RouterLeaseRequest = Message<"agentmesh.v1.RouterLeaseRequest"> & {
|
|
|
840
899
|
* @generated from field: int32 connection_limit = 10;
|
|
841
900
|
*/
|
|
842
901
|
connectionLimit: number;
|
|
902
|
+
/**
|
|
903
|
+
* Optional base URL where this router serves external HTTP ingress.
|
|
904
|
+
*
|
|
905
|
+
* @generated from field: string ingress_url = 11;
|
|
906
|
+
*/
|
|
907
|
+
ingressUrl: string;
|
|
843
908
|
};
|
|
844
909
|
/**
|
|
845
910
|
* Describes the message agentmesh.v1.RouterLeaseRequest.
|
|
@@ -914,12 +979,46 @@ export type PolicyRole = Message<"agentmesh.v1.PolicyRole"> & {
|
|
|
914
979
|
* @generated from field: repeated string allowed_publish = 7;
|
|
915
980
|
*/
|
|
916
981
|
allowedPublish: string[];
|
|
982
|
+
/**
|
|
983
|
+
* Inbound services a member with this role may expose on router HTTP
|
|
984
|
+
* ingress, together with the permitted IngressAuthModes. Empty denies all
|
|
985
|
+
* external ingress exposure for this role.
|
|
986
|
+
*
|
|
987
|
+
* @generated from field: repeated agentmesh.v1.IngressGrant allowed_ingress = 8;
|
|
988
|
+
*/
|
|
989
|
+
allowedIngress: IngressGrant[];
|
|
917
990
|
};
|
|
918
991
|
/**
|
|
919
992
|
* Describes the message agentmesh.v1.PolicyRole.
|
|
920
993
|
* Use `create(PolicyRoleSchema)` to create a new message.
|
|
921
994
|
*/
|
|
922
995
|
export declare const PolicyRoleSchema: GenMessage<PolicyRole>;
|
|
996
|
+
/**
|
|
997
|
+
* IngressGrant permits a role to expose matching inbound services on router
|
|
998
|
+
* HTTP ingress under the listed authentication modes.
|
|
999
|
+
*
|
|
1000
|
+
* @generated from message agentmesh.v1.IngressGrant
|
|
1001
|
+
*/
|
|
1002
|
+
export type IngressGrant = Message<"agentmesh.v1.IngressGrant"> & {
|
|
1003
|
+
/**
|
|
1004
|
+
* Inbound service patterns ("a2a://*", "mcp://calc", "*"). Egress
|
|
1005
|
+
* destinations ("egress://...") cannot be exposed as ingress.
|
|
1006
|
+
*
|
|
1007
|
+
* @generated from field: repeated string services = 1;
|
|
1008
|
+
*/
|
|
1009
|
+
services: string[];
|
|
1010
|
+
/**
|
|
1011
|
+
* Permitted auth modes. Empty grants ONLY INGRESS_AUTH_MODE_EDGE.
|
|
1012
|
+
*
|
|
1013
|
+
* @generated from field: repeated agentmesh.v1.IngressAuthMode allowed_auth_modes = 2;
|
|
1014
|
+
*/
|
|
1015
|
+
allowedAuthModes: IngressAuthMode[];
|
|
1016
|
+
};
|
|
1017
|
+
/**
|
|
1018
|
+
* Describes the message agentmesh.v1.IngressGrant.
|
|
1019
|
+
* Use `create(IngressGrantSchema)` to create a new message.
|
|
1020
|
+
*/
|
|
1021
|
+
export declare const IngressGrantSchema: GenMessage<IngressGrant>;
|
|
923
1022
|
/**
|
|
924
1023
|
* HTTPGrant narrows one allowed_services entry to HTTP methods and paths.
|
|
925
1024
|
* The control plane compiles it into granted_method and granted_path_* facts
|
|
@@ -2037,6 +2136,10 @@ export type RouterLease = Message<"agentmesh.v1.RouterLease"> & {
|
|
|
2037
2136
|
* @generated from field: int32 dht_size = 6;
|
|
2038
2137
|
*/
|
|
2039
2138
|
dhtSize: number;
|
|
2139
|
+
/**
|
|
2140
|
+
* @generated from field: string ingress_url = 7;
|
|
2141
|
+
*/
|
|
2142
|
+
ingressUrl: string;
|
|
2040
2143
|
};
|
|
2041
2144
|
/**
|
|
2042
2145
|
* Describes the message agentmesh.v1.RouterLease.
|
|
@@ -2704,6 +2807,34 @@ export declare enum ServiceType {
|
|
|
2704
2807
|
* Describes the enum agentmesh.v1.ServiceType.
|
|
2705
2808
|
*/
|
|
2706
2809
|
export declare const ServiceTypeSchema: GenEnum<ServiceType>;
|
|
2810
|
+
/**
|
|
2811
|
+
* @generated from enum agentmesh.v1.IngressAuthMode
|
|
2812
|
+
*/
|
|
2813
|
+
export declare enum IngressAuthMode {
|
|
2814
|
+
/**
|
|
2815
|
+
* Defaults to INGRESS_AUTH_MODE_EDGE.
|
|
2816
|
+
*
|
|
2817
|
+
* @generated from enum value: INGRESS_AUTH_MODE_UNSPECIFIED = 0;
|
|
2818
|
+
*/
|
|
2819
|
+
UNSPECIFIED = 0,
|
|
2820
|
+
/**
|
|
2821
|
+
* Router and provider node verify a delegated Mesh Biscuit + mesh policy.
|
|
2822
|
+
*
|
|
2823
|
+
* @generated from enum value: INGRESS_AUTH_MODE_EDGE = 1;
|
|
2824
|
+
*/
|
|
2825
|
+
EDGE = 1,
|
|
2826
|
+
/**
|
|
2827
|
+
* Backend authenticates its own requests; requires an explicit PASSTHROUGH
|
|
2828
|
+
* grant on the serving node's PolicyRole.allowed_ingress.
|
|
2829
|
+
*
|
|
2830
|
+
* @generated from enum value: INGRESS_AUTH_MODE_PASSTHROUGH = 2;
|
|
2831
|
+
*/
|
|
2832
|
+
PASSTHROUGH = 2
|
|
2833
|
+
}
|
|
2834
|
+
/**
|
|
2835
|
+
* Describes the enum agentmesh.v1.IngressAuthMode.
|
|
2836
|
+
*/
|
|
2837
|
+
export declare const IngressAuthModeSchema: GenEnum<IngressAuthMode>;
|
|
2707
2838
|
/**
|
|
2708
2839
|
* @generated from enum agentmesh.v1.EgressMode
|
|
2709
2840
|
*/
|