@assemblyline-agents/mirror 0.1.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/LICENSE +21 -0
- package/README.md +68 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/package.json +50 -0
- package/skills/mirror/SKILL.md +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OpenEve contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @assemblyline-agents/mirror
|
|
2
|
+
|
|
3
|
+
Official Assembly Line connection plugin for [Mirror](https://github.com/jasonbadeaux/mirror).
|
|
4
|
+
It gives each authenticated agent user an optional, separately authorized path
|
|
5
|
+
to their mirrored source records and connected accounts.
|
|
6
|
+
|
|
7
|
+
## Setup
|
|
8
|
+
|
|
9
|
+
Choose a stable public client id for the agent deployment and set:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
MIRROR_OAUTH_CLIENT_ID=my-assembly-line-agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Mirror accepts Assembly Line's OAuth Authorization Code flow with mandatory PKCE
|
|
16
|
+
S256. The normal callback is:
|
|
17
|
+
|
|
18
|
+
```text
|
|
19
|
+
https://YOUR-AGENT-HOST/openeve/connections/callback
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The runtime also serves `/assembly-line/connections/callback`; callback-URL
|
|
23
|
+
construction still emits the legacy `/openeve/...` path during the rename
|
|
24
|
+
compatibility window, so register the URI shown above until it flips.
|
|
25
|
+
|
|
26
|
+
The hosted service and MCP endpoint are used by default. Self-hosted
|
|
27
|
+
deployments can set `MIRROR_MCP_URL` and, when OAuth is on a different origin,
|
|
28
|
+
`MIRROR_OAUTH_ISSUER`. `MIRROR_OAUTH_REDIRECT_URI` overrides Assembly Line's normal
|
|
29
|
+
callback only when necessary.
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
assembly-line add mirror agent
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The generated connection exposes Mirror reads and hides all write-like tools.
|
|
36
|
+
To permit approval creation, syncs, connection links, registration, or other
|
|
37
|
+
mutations, opt in with an Assembly Line approval policy:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { defineMirrorConnection } from "@assemblyline-agents/mirror";
|
|
41
|
+
|
|
42
|
+
export default defineMirrorConnection({
|
|
43
|
+
access: {
|
|
44
|
+
read: true,
|
|
45
|
+
write: { approval: "always" }
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Mirror still enforces its own account grants and exact-action approval system;
|
|
51
|
+
Assembly Line's approval is an additional outer gate.
|
|
52
|
+
|
|
53
|
+
## Optional Mirror CLI
|
|
54
|
+
|
|
55
|
+
The MCP connection is the default and works without a CLI. If the sandbox
|
|
56
|
+
image already contains the `mirror` executable, opt in to a short-lived CLI
|
|
57
|
+
profile:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
export default defineMirrorConnection({
|
|
61
|
+
materializeCli: true,
|
|
62
|
+
access: { read: true, write: false }
|
|
63
|
+
});
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Assembly Line writes `/root/.mirror/config.json` with mode `0600`. Only the current
|
|
67
|
+
access token is projected. The rotating refresh token stays in the host-side
|
|
68
|
+
grant store and is never written into the sandbox.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type ConnectionAuthDefinition, type McpPluginConnectionOptions } from "@assemblyline-agents/core";
|
|
2
|
+
export interface MirrorCliMaterializationOptions {
|
|
3
|
+
/** Sandbox path for the projected CLI profile. Defaults to /root/.mirror/config.json. */
|
|
4
|
+
path?: string;
|
|
5
|
+
/** Mirror CLI profile name. Defaults to openeve. */
|
|
6
|
+
profile?: string;
|
|
7
|
+
/** Runtime recorded in the projected profile. Defaults to openeve. */
|
|
8
|
+
runtime?: string;
|
|
9
|
+
/** Mirror API origin. Defaults to the configured MCP endpoint's origin. */
|
|
10
|
+
apiUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MirrorConnectionOptions extends Omit<McpPluginConnectionOptions, "auth"> {
|
|
13
|
+
auth?: ConnectionAuthDefinition | false;
|
|
14
|
+
/** Stable public OAuth client id shown on Mirror's consent screen. */
|
|
15
|
+
clientId?: string;
|
|
16
|
+
/** Mirror authorization-server origin. Defaults to the MCP endpoint's origin. */
|
|
17
|
+
issuer?: string;
|
|
18
|
+
/** Override OpenEve's normal /openeve/connections/callback URI. */
|
|
19
|
+
redirectUri?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Project the short-lived access token into a Mirror CLI profile.
|
|
22
|
+
* The sandbox image must already contain the `mirror` CLI. Refresh tokens
|
|
23
|
+
* always remain in OpenEve's host-side grant store.
|
|
24
|
+
*/
|
|
25
|
+
materializeCli?: boolean | MirrorCliMaterializationOptions;
|
|
26
|
+
}
|
|
27
|
+
export declare function defineMirrorConnection(options: MirrorConnectionOptions): import("@assemblyline-agents/core").McpHttpClientConnectionDefinition;
|
|
28
|
+
export declare const openevePlugin: import("@assemblyline-agents/core").PluginModule;
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAChC,MAAM,2BAA2B,CAAC;AAInC,MAAM,WAAW,+BAA+B;IAC9C,yFAAyF;IACzF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAwB,SAAQ,IAAI,CAAC,0BAA0B,EAAE,MAAM,CAAC;IACvF,IAAI,CAAC,EAAE,wBAAwB,GAAG,KAAK,CAAC;IACxC,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,cAAc,CAAC,EAAE,OAAO,GAAG,+BAA+B,CAAC;CAC5D;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,uBAAuB,yEAiDtE;AAED,eAAO,MAAM,aAAa,kDAA0C,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { connectionPluginMetadata, defineMcpPluginConnection, defineOAuthAuthorization, definePlugin } from "@assemblyline-agents/core";
|
|
2
|
+
const PLUGIN = connectionPluginMetadata("mirror");
|
|
3
|
+
export function defineMirrorConnection(options) {
|
|
4
|
+
const { auth, clientId, issuer, redirectUri, materializeCli, ...connection } = options;
|
|
5
|
+
const definition = defineMcpPluginConnection(PLUGIN, {
|
|
6
|
+
...connection,
|
|
7
|
+
auth: auth === false
|
|
8
|
+
? false
|
|
9
|
+
: auth ?? mirrorOAuth({
|
|
10
|
+
...(clientId ? { clientId } : {}),
|
|
11
|
+
...(issuer ? { issuer } : {}),
|
|
12
|
+
...(redirectUri ? { redirectUri } : {}),
|
|
13
|
+
...(connection.url ? { mcpUrl: connection.url } : {})
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
if (materializeCli) {
|
|
17
|
+
const settings = materializeCli === true ? {} : materializeCli;
|
|
18
|
+
const profile = settings.profile?.trim() || "openeve";
|
|
19
|
+
const runtime = settings.runtime?.trim() || "openeve";
|
|
20
|
+
const apiUrl = normalizeIssuer(settings.apiUrl ?? issuer ?? definition.url);
|
|
21
|
+
definition.materialize = {
|
|
22
|
+
files: [{
|
|
23
|
+
path: settings.path?.trim() || "/root/.mirror/config.json",
|
|
24
|
+
content: `${JSON.stringify({
|
|
25
|
+
version: 1,
|
|
26
|
+
currentProfile: profile,
|
|
27
|
+
profiles: {
|
|
28
|
+
[profile]: {
|
|
29
|
+
apiUrl,
|
|
30
|
+
userId: "{{credential.mirror_user_id}}",
|
|
31
|
+
branchId: "{{credential.mirror_branch_id}}",
|
|
32
|
+
bindingId: "{{credential.mirror_binding_id}}",
|
|
33
|
+
bindingToken: "{{token}}",
|
|
34
|
+
runtime
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}, null, 2)}\n`,
|
|
38
|
+
mode: 0o600
|
|
39
|
+
}]
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return definition;
|
|
43
|
+
}
|
|
44
|
+
export const openevePlugin = definePlugin({ connections: [PLUGIN] });
|
|
45
|
+
function mirrorOAuth(input) {
|
|
46
|
+
return ({ env }) => {
|
|
47
|
+
const resolvedClientId = input.clientId?.trim() || env.MIRROR_OAUTH_CLIENT_ID?.trim();
|
|
48
|
+
if (!resolvedClientId) {
|
|
49
|
+
throw new Error("Mirror OAuth requires MIRROR_OAUTH_CLIENT_ID or clientId.");
|
|
50
|
+
}
|
|
51
|
+
const resolvedIssuer = normalizeIssuer(input.issuer
|
|
52
|
+
?? env.MIRROR_OAUTH_ISSUER
|
|
53
|
+
?? input.mcpUrl
|
|
54
|
+
?? env.MIRROR_MCP_URL
|
|
55
|
+
?? PLUGIN.defaultUrl);
|
|
56
|
+
const resolvedRedirectUri = input.redirectUri?.trim() || env.MIRROR_OAUTH_REDIRECT_URI?.trim();
|
|
57
|
+
return defineOAuthAuthorization({
|
|
58
|
+
displayName: "Mirror",
|
|
59
|
+
authorizeUrl: new URL("/oauth/authorize", resolvedIssuer).toString(),
|
|
60
|
+
tokenUrl: new URL("/oauth/token", resolvedIssuer).toString(),
|
|
61
|
+
clientId: resolvedClientId,
|
|
62
|
+
...(resolvedRedirectUri ? { redirectUri: resolvedRedirectUri } : {}),
|
|
63
|
+
pkce: true
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function normalizeIssuer(value) {
|
|
68
|
+
const url = new URL(value);
|
|
69
|
+
return url.origin;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EAGb,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,GAAG,wBAAwB,CAAC,QAAQ,CAAE,CAAC;AA6BnD,MAAM,UAAU,sBAAsB,CAAC,OAAgC;IACrE,MAAM,EACJ,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,WAAW,EACX,cAAc,EACd,GAAG,UAAU,EACd,GAAG,OAAO,CAAC;IACZ,MAAM,UAAU,GAAG,yBAAyB,CAAC,MAAM,EAAE;QACnD,GAAG,UAAU;QACb,IAAI,EAAE,IAAI,KAAK,KAAK;YAClB,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,IAAI,IAAI,WAAW,CAAC;gBAClB,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7B,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACvC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACtD,CAAC;KACP,CAAC,CAAC;IAEH,IAAI,cAAc,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,cAAc,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC;QAC/D,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACtD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;QACtD,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,CAAC,MAAM,IAAI,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QAC5E,UAAU,CAAC,WAAW,GAAG;YACvB,KAAK,EAAE,CAAC;oBACN,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,2BAA2B;oBAC1D,OAAO,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;wBACzB,OAAO,EAAE,CAAC;wBACV,cAAc,EAAE,OAAO;wBACvB,QAAQ,EAAE;4BACR,CAAC,OAAO,CAAC,EAAE;gCACT,MAAM;gCACN,MAAM,EAAE,+BAA+B;gCACvC,QAAQ,EAAE,iCAAiC;gCAC3C,SAAS,EAAE,kCAAkC;gCAC7C,YAAY,EAAE,WAAW;gCACzB,OAAO;6BACR;yBACF;qBACF,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI;oBACf,IAAI,EAAE,KAAK;iBACZ,CAAC;SACH,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAErE,SAAS,WAAW,CAAC,KAKpB;IACC,OAAO,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE;QACjB,MAAM,gBAAgB,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;QACtF,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;QAC/E,CAAC;QACD,MAAM,cAAc,GAAG,eAAe,CACpC,KAAK,CAAC,MAAM;eACT,GAAG,CAAC,mBAAmB;eACvB,KAAK,CAAC,MAAM;eACZ,GAAG,CAAC,cAAc;eAClB,MAAM,CAAC,UAAW,CACtB,CAAC;QACF,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,yBAAyB,EAAE,IAAI,EAAE,CAAC;QAC/F,OAAO,wBAAwB,CAAC;YAC9B,WAAW,EAAE,QAAQ;YACrB,YAAY,EAAE,IAAI,GAAG,CAAC,kBAAkB,EAAE,cAAc,CAAC,CAAC,QAAQ,EAAE;YACpE,QAAQ,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC,QAAQ,EAAE;YAC5D,QAAQ,EAAE,gBAAgB;YAC1B,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpE,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@assemblyline-agents/mirror",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"default": "./dist/index.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@assemblyline-agents/core": "0.1.0"
|
|
13
|
+
},
|
|
14
|
+
"description": "Official OpenEve connection plugin for user-scoped Mirror accounts.",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"skills"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=22.19.0"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "git+https://github.com/jasonbadeaux/openeve.git",
|
|
26
|
+
"directory": "packages/mirror"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/jasonbadeaux/openeve/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/jasonbadeaux/openeve#readme",
|
|
32
|
+
"author": "OpenEve contributors",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"openeve",
|
|
35
|
+
"ai",
|
|
36
|
+
"agents",
|
|
37
|
+
"mirror",
|
|
38
|
+
"mcp",
|
|
39
|
+
"oauth",
|
|
40
|
+
"connected-accounts",
|
|
41
|
+
"plugin"
|
|
42
|
+
],
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc -p tsconfig.json",
|
|
48
|
+
"check": "tsc -p tsconfig.json --noEmit"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mirror
|
|
3
|
+
description: Use a connected Mirror account to inspect the user's allowed connected providers, query mirrored records, perform bounded live reads, and stage approval-gated actions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Mirror
|
|
7
|
+
|
|
8
|
+
Mirror is the user's connected-context layer. It holds downstream provider
|
|
9
|
+
credentials and exposes only the providers and accounts granted to this agent.
|
|
10
|
+
Never ask for, print, or store raw provider credentials.
|
|
11
|
+
|
|
12
|
+
Start with `mirror.whoami`, then `mirror.connected_providers`. Inspect each
|
|
13
|
+
lane's access and mirror policy before choosing a tool:
|
|
14
|
+
|
|
15
|
+
- Use `mirror.query_records` for normal recall from a mirrored lane.
|
|
16
|
+
- Use `mirror.get_source` for one exact raw record.
|
|
17
|
+
- Use `mirror.live_read` only for current state or detail absent from the
|
|
18
|
+
mirror.
|
|
19
|
+
- Use `mirror.get_pending_approvals` to inspect unresolved action requests.
|
|
20
|
+
|
|
21
|
+
Keep reads bounded by provider, account, identifiers, dates, and explicit
|
|
22
|
+
limits. Check message authorship metadata rather than inferring who wrote a
|
|
23
|
+
message from its prose.
|
|
24
|
+
|
|
25
|
+
Write-like provider operations, syncs, setup links, agent registration,
|
|
26
|
+
approval creation/redemption, and credential export are classified as writes
|
|
27
|
+
by Assembly Line. Use them only when the connection exposes write authority and its
|
|
28
|
+
approval gate permits the call. Mirror may apply an additional exact-action
|
|
29
|
+
approval before executing a downstream mutation.
|
|
30
|
+
|
|
31
|
+
The MCP tools are the normal Assembly Line connection surface. If the deployment
|
|
32
|
+
owner installed the optional `mirror` CLI and enabled `materializeCli`, the CLI
|
|
33
|
+
may be used inside the sandbox; its profile contains only a short-lived access
|
|
34
|
+
token. Refresh credentials remain on the Assembly Line host.
|