@amalgm/tools 0.1.4 → 0.1.5
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/PURPOSE.md +12 -38
- package/README.md +0 -22
- package/dist/artifact-files.d.ts +1 -3
- package/dist/artifact-files.js +3 -11
- package/dist/artifacts.d.ts +6 -8
- package/dist/artifacts.js +6 -19
- package/dist/definition.js +0 -10
- package/dist/http.js +1 -6
- package/dist/index.d.ts +1 -3
- package/dist/index.js +1 -3
- package/dist/mcp-server.d.ts +1 -2
- package/dist/mcp-server.js +2 -3
- package/dist/mcp.d.ts +1 -2
- package/dist/mcp.js +21 -33
- package/dist/notifications.js +3 -4
- package/dist/schema.js +0 -15
- package/dist/store.d.ts +4 -17
- package/dist/store.js +41 -105
- package/dist/toolbox.d.ts +5 -13
- package/dist/toolbox.js +114 -90
- package/dist/types.d.ts +1 -30
- package/dist/updates.d.ts +1 -2
- package/dist/updates.js +1 -12
- package/docs/ENGINE_INTEGRATION.md +2 -5
- package/package.json +4 -4
- package/dist/apply-definition.d.ts +0 -12
- package/dist/apply-definition.js +0 -33
- package/dist/deployment-files.d.ts +0 -10
- package/dist/deployment-files.js +0 -38
- package/dist/deployment-types.d.ts +0 -32
- package/dist/deployment-types.js +0 -1
- package/dist/deployments.d.ts +0 -19
- package/dist/deployments.js +0 -98
- package/dist/host-mcp-tool.d.ts +0 -8
- package/dist/host-mcp-tool.js +0 -40
- package/dist/toolbox-deployments.d.ts +0 -30
- package/dist/toolbox-deployments.js +0 -125
- package/dist/toolbox-projection.d.ts +0 -13
- package/dist/toolbox-projection.js +0 -41
- package/dist/toolbox-view.d.ts +0 -35
- package/dist/toolbox-view.js +0 -75
package/PURPOSE.md
CHANGED
|
@@ -23,14 +23,9 @@ registry or execution implementation.
|
|
|
23
23
|
- An **action** is one model-callable capability owned by exactly one tool.
|
|
24
24
|
- A **Toolbox** is the sole catalog and mutation authority for one local state
|
|
25
25
|
directory.
|
|
26
|
-
- A **tool deployment** is one immutable definition of a stable tool identity,
|
|
27
|
-
including its complete authoritative action set; activation appends the
|
|
28
|
-
deployment and moves that tool's current pointer atomically.
|
|
29
26
|
- A **loadout** is a set of tool or action ids used to derive a read-only view
|
|
30
27
|
of the Toolbox.
|
|
31
28
|
- A **driver** executes actions for one tool type.
|
|
32
|
-
- An **MCP server** is a separately identified runtime endpoint that may expose
|
|
33
|
-
one or more tools; selecting a tool never changes that server's identity.
|
|
34
29
|
- A **system tool** is an embedder-owned definition projected into the catalog;
|
|
35
30
|
it is not user state.
|
|
36
31
|
- A **notification** is one request to inform the current user; a channel
|
|
@@ -38,18 +33,20 @@ registry or execution implementation.
|
|
|
38
33
|
|
|
39
34
|
## Axioms
|
|
40
35
|
|
|
36
|
+
Managed releases bind to one exact published Core version and build from the
|
|
37
|
+
locked dependency graph on the supported Node toolchain.
|
|
38
|
+
|
|
41
39
|
1. Every action belongs to exactly one tool and has the canonical id
|
|
42
40
|
`<tool-id>.<action-name>`.
|
|
43
41
|
2. Tool ids are stable, globally unique within one Toolbox, and never change
|
|
44
42
|
as a side effect of renaming display text.
|
|
45
|
-
3. A tool's portable
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
adapters never keep
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
removing history.
|
|
43
|
+
3. A tool's portable definition is its artifact file: one file per tool,
|
|
44
|
+
the tool and all of its actions together, never a second tool in the
|
|
45
|
+
same file. The Toolbox database is a derived index maintained for
|
|
46
|
+
runtime and realtime sync; SDK, CLI, and MCP adapters never keep
|
|
47
|
+
parallel registries.
|
|
48
|
+
4. Applying a tool definition is atomic and authoritative for that tool: its
|
|
49
|
+
supplied action set replaces the previous set completely.
|
|
53
50
|
5. Deleting a tool deletes all of its actions in the same transaction; an
|
|
54
51
|
orphan action can never be observed.
|
|
55
52
|
6. Disabled tools expose and execute no actions. Disabled actions are likewise
|
|
@@ -87,34 +84,11 @@ registry or execution implementation.
|
|
|
87
84
|
20. Notification channels are host capabilities. Tools owns validation and
|
|
88
85
|
result semantics; an injected channel adapter owns formatting, recipient
|
|
89
86
|
lookup, credentials, and delivery.
|
|
90
|
-
21. Reopening a Toolbox preserves the temporal fields of every semantically
|
|
91
|
-
unchanged system projection already present in its portable index; boot
|
|
92
|
-
never rewrites tracked bytes merely to stamp the current machine's time.
|
|
93
|
-
22. The Toolbox exposes the versioned `deployment.activate` operation and its
|
|
94
|
-
exact definition through one Live surface; SQLite pages are never part of
|
|
95
|
-
that contract. A received activation materializes locally without echo,
|
|
96
|
-
retries are idempotent, and an existing deployment id can never acquire
|
|
97
|
-
different bytes.
|
|
98
|
-
23. A host may separate the synced deployment directory from its machine-local
|
|
99
|
-
database. Amalgm Shell stores immutable deployment documents beneath
|
|
100
|
-
`users/<email>/toolbox/<tool-id>/deployments/` while keeping SQLite
|
|
101
|
-
coordination state below the machine boundary.
|
|
102
|
-
24. A Chat preparation selects one catalog `revisionId` derived from exact
|
|
103
|
-
current deployment ids and system projections. Preparation either resolves
|
|
104
|
-
that exact revision or fails; it never silently substitutes newer tools.
|
|
105
|
-
25. A host MCP source names both its server and its route. Tool identity,
|
|
106
|
-
action identity, server identity, and transport location are distinct even
|
|
107
|
-
when a first-party release currently maps them one-to-one.
|
|
108
|
-
26. A scoped Toolbox MCP server advertises and calls only the selected loadout;
|
|
109
|
-
management actions are included only when the composing host asks for them.
|
|
110
87
|
|
|
111
88
|
## Predictable behavior
|
|
112
89
|
|
|
113
|
-
Applying the same definition twice produces the same catalog
|
|
114
|
-
|
|
115
|
-
same system projection produces the same portable index bytes on every
|
|
116
|
-
machine. Applying a changed action set replaces the old set atomically.
|
|
117
|
-
Selecting a whole tool
|
|
90
|
+
Applying the same definition twice produces the same catalog. Applying a
|
|
91
|
+
changed action set replaces the old set atomically. Selecting a whole tool
|
|
118
92
|
grants all of its enabled actions; selecting one action grants only that
|
|
119
93
|
action. Disabling or deleting a tool immediately removes all of its actions
|
|
120
94
|
from list and call surfaces. CLI arguments are passed directly to a process,
|
package/README.md
CHANGED
|
@@ -36,28 +36,6 @@ verbatim when set, then `AMALGM_DIR/toolbox`, then the scoped layout
|
|
|
36
36
|
`~/.amalgm/users/<scope>/toolbox`. Passing `stateDir` or `databaseFile`
|
|
37
37
|
bypasses resolution entirely.
|
|
38
38
|
|
|
39
|
-
Platform hosts should separate portable deployment documents from local
|
|
40
|
-
coordination state:
|
|
41
|
-
|
|
42
|
-
```js
|
|
43
|
-
const toolbox = new Toolbox({
|
|
44
|
-
deploymentDir: '/amalgm/users/person@example.com/toolbox',
|
|
45
|
-
databaseFile: '/machine-state/services/tools/tools.db',
|
|
46
|
-
});
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
An intentional semantic change appends
|
|
50
|
-
`<deploymentDir>/<tool-id>/deployments/<deployment-id>.json` and atomically
|
|
51
|
-
advances the local head. The database, WAL, `toolbox.index.json`, and legacy
|
|
52
|
-
flat artifacts are projections and must not be synchronized. `catalog()`
|
|
53
|
-
exposes both a local numeric `revision` for presentation freshness and the
|
|
54
|
-
immutable `revisionId` that Chat must use for preparation.
|
|
55
|
-
|
|
56
|
-
`deploymentSurface()` implements the `amalgm.tools.deployments@1` Live
|
|
57
|
-
surface. Its operation is the shared `deployment.activate` envelope. Remote
|
|
58
|
-
application is idempotent and does not echo; `deploymentSnapshot()` and
|
|
59
|
-
`applyDeploymentSnapshot()` are the hydration/recovery boundary.
|
|
60
|
-
|
|
61
39
|
## CLI
|
|
62
40
|
|
|
63
41
|
```sh
|
package/dist/artifact-files.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { ToolboxIndexDocument } from './artifacts.js';
|
|
2
1
|
import type { ActionRecord, Catalog, ToolRecord } from './types.js';
|
|
3
2
|
declare class ArtifactFiles {
|
|
4
3
|
private readonly directory;
|
|
@@ -10,10 +9,9 @@ declare class ArtifactFiles {
|
|
|
10
9
|
}): string;
|
|
11
10
|
removeTool(toolId: string): void;
|
|
12
11
|
writeIndex(catalog: Catalog): void;
|
|
13
|
-
readIndex(): ToolboxIndexDocument | null;
|
|
14
12
|
/** Give every persisted user tool its portable artifact and refresh the
|
|
15
13
|
* index. Additive only: a file for a tool this catalog does not know is
|
|
16
|
-
* never deleted here — removal
|
|
14
|
+
* never deleted here — removal is an explicit mutation. */
|
|
17
15
|
materialize(catalog: Catalog): void;
|
|
18
16
|
/** Execute the legacy `toolbox.json` migration plan: per-tool artifacts
|
|
19
17
|
* first, then the index, and only then the rename that retires the
|
package/dist/artifact-files.js
CHANGED
|
@@ -2,9 +2,8 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { LEGACY_TOOLBOX_FILE_NAME, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId, userArtifactFileName, } from './artifacts.js';
|
|
4
4
|
/**
|
|
5
|
-
* The host adapter for
|
|
6
|
-
*
|
|
7
|
-
* directory. Writes are atomic
|
|
5
|
+
* The host adapter for tool artifacts: it executes the pure documents and
|
|
6
|
+
* plans from `artifacts.ts` against one state directory. Writes are atomic
|
|
8
7
|
* (tmp file + rename) and skipped when the bytes are unchanged, matching
|
|
9
8
|
* Engine `lib/storage.js`.
|
|
10
9
|
*
|
|
@@ -52,16 +51,9 @@ class ArtifactFiles {
|
|
|
52
51
|
writeIndex(catalog) {
|
|
53
52
|
writeJsonIfChanged(this.file(TOOLBOX_INDEX_FILE_NAME), catalogIndexDocument(catalog));
|
|
54
53
|
}
|
|
55
|
-
readIndex() {
|
|
56
|
-
const value = readJson(this.file(TOOLBOX_INDEX_FILE_NAME));
|
|
57
|
-
if (!value || value.version !== 1 || !value.tools || typeof value.tools !== 'object'
|
|
58
|
-
|| !value.toolActions || typeof value.toolActions !== 'object')
|
|
59
|
-
return null;
|
|
60
|
-
return value;
|
|
61
|
-
}
|
|
62
54
|
/** Give every persisted user tool its portable artifact and refresh the
|
|
63
55
|
* index. Additive only: a file for a tool this catalog does not know is
|
|
64
|
-
* never deleted here — removal
|
|
56
|
+
* never deleted here — removal is an explicit mutation. */
|
|
65
57
|
materialize(catalog) {
|
|
66
58
|
for (const tool of catalog.tools) {
|
|
67
59
|
if (tool.origin === 'system')
|
package/dist/artifacts.d.ts
CHANGED
|
@@ -2,11 +2,11 @@ import type { ActionRecord, Catalog, ToolRecord } from './types.js';
|
|
|
2
2
|
/**
|
|
3
3
|
* Tool artifact format laws — the portable representation of a tool.
|
|
4
4
|
*
|
|
5
|
-
* One
|
|
6
|
-
* owns together
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* Engine/
|
|
5
|
+
* One tool is one artifact file: the tool definition and every action it
|
|
6
|
+
* owns travel together, and a file never carries a second tool. Artifact
|
|
7
|
+
* files are the portable definition; the Toolbox database and
|
|
8
|
+
* `toolbox.index.json` are derived caches. The format is ported byte-exact
|
|
9
|
+
* from Engine `runtime/scripts/amalgm-mcp/toolbox/artifacts.js`.
|
|
10
10
|
*
|
|
11
11
|
* Pure laws only: nothing here touches the filesystem. `artifact-files.ts`
|
|
12
12
|
* is the host adapter that executes these documents and plans.
|
|
@@ -57,12 +57,10 @@ declare function artifactDocument(input: {
|
|
|
57
57
|
declare function isToolArtifactDocument(value: unknown): value is ToolArtifactDocument;
|
|
58
58
|
declare function toolboxIndexDocument(tools: Record<string, unknown>, toolActions: Record<string, unknown>): ToolboxIndexDocument;
|
|
59
59
|
declare function catalogIndexDocument(catalog: Pick<Catalog, 'tools' | 'actions'>): ToolboxIndexDocument;
|
|
60
|
-
declare function portableRecordSemantic(value: ToolRecord | ActionRecord): string;
|
|
61
|
-
declare function preserveProjectionTime<T extends ToolRecord | ActionRecord>(candidate: T, previous: unknown): T;
|
|
62
60
|
/** The migration of one legacy aggregate `toolbox.json` catalog, as a pure
|
|
63
61
|
* plan: every user tool becomes a per-tool artifact write, the whole legacy
|
|
64
62
|
* catalog becomes the index, and the aggregate file is renamed out of the
|
|
65
63
|
* way only after each record has a per-tool replacement. */
|
|
66
64
|
declare function legacyMigrationPlan(legacy: unknown): LegacyMigrationPlan;
|
|
67
|
-
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId,
|
|
65
|
+
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId, toolboxIndexDocument, userArtifactFileName, };
|
|
68
66
|
export type { ArtifactFileWrite, LegacyMigrationPlan, ToolArtifactDocument, ToolboxIndexDocument };
|
package/dist/artifacts.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool artifact format laws — the portable representation of a tool.
|
|
3
3
|
*
|
|
4
|
-
* One
|
|
5
|
-
* owns together
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* Engine/
|
|
4
|
+
* One tool is one artifact file: the tool definition and every action it
|
|
5
|
+
* owns travel together, and a file never carries a second tool. Artifact
|
|
6
|
+
* files are the portable definition; the Toolbox database and
|
|
7
|
+
* `toolbox.index.json` are derived caches. The format is ported byte-exact
|
|
8
|
+
* from Engine `runtime/scripts/amalgm-mcp/toolbox/artifacts.js`.
|
|
9
9
|
*
|
|
10
10
|
* Pure laws only: nothing here touches the filesystem. `artifact-files.ts`
|
|
11
11
|
* is the host adapter that executes these documents and plans.
|
|
@@ -81,19 +81,6 @@ function toolboxIndexDocument(tools, toolActions) {
|
|
|
81
81
|
function catalogIndexDocument(catalog) {
|
|
82
82
|
return toolboxIndexDocument(Object.fromEntries(catalog.tools.map((tool) => [tool.id, tool])), Object.fromEntries(catalog.actions.map((action) => [action.id, action])));
|
|
83
83
|
}
|
|
84
|
-
function portableRecordSemantic(value) {
|
|
85
|
-
const { createdAt, updatedAt, ...portable } = value;
|
|
86
|
-
return JSON.stringify(portable);
|
|
87
|
-
}
|
|
88
|
-
function preserveProjectionTime(candidate, previous) {
|
|
89
|
-
if (!previous || typeof previous !== 'object')
|
|
90
|
-
return candidate;
|
|
91
|
-
const record = previous;
|
|
92
|
-
if (typeof record.createdAt !== 'string' || typeof record.updatedAt !== 'string'
|
|
93
|
-
|| portableRecordSemantic(record) !== portableRecordSemantic(candidate))
|
|
94
|
-
return candidate;
|
|
95
|
-
return { ...candidate, createdAt: record.createdAt, updatedAt: record.updatedAt };
|
|
96
|
-
}
|
|
97
84
|
/** The migration of one legacy aggregate `toolbox.json` catalog, as a pure
|
|
98
85
|
* plan: every user tool becomes a per-tool artifact write, the whole legacy
|
|
99
86
|
* catalog becomes the index, and the aggregate file is renamed out of the
|
|
@@ -122,4 +109,4 @@ function legacyMigrationPlan(legacy) {
|
|
|
122
109
|
rename: { from: LEGACY_TOOLBOX_FILE_NAME, to: LEGACY_TOOLBOX_BACKUP_FILE_NAME },
|
|
123
110
|
};
|
|
124
111
|
}
|
|
125
|
-
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId,
|
|
112
|
+
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId, toolboxIndexDocument, userArtifactFileName, };
|
package/dist/definition.js
CHANGED
|
@@ -32,15 +32,6 @@ function refs(value, label) {
|
|
|
32
32
|
result[string(key, label)] = string(reference, `${label}.${key}`);
|
|
33
33
|
return result;
|
|
34
34
|
}
|
|
35
|
-
function hostRoute(value) {
|
|
36
|
-
if (value === undefined)
|
|
37
|
-
return undefined;
|
|
38
|
-
const route = string(value, 'source.route');
|
|
39
|
-
if (!route.startsWith('/') || route.startsWith('//') || route.includes('?') || route.includes('#')) {
|
|
40
|
-
throw new Error('source.route must be an absolute path without query or fragment');
|
|
41
|
-
}
|
|
42
|
-
return route.replace(/\/+$/, '') || '/';
|
|
43
|
-
}
|
|
44
35
|
function base(source) {
|
|
45
36
|
return {
|
|
46
37
|
timeoutMs: positive(source.timeoutMs, DEFAULT_TIMEOUT, 'source.timeoutMs'),
|
|
@@ -100,7 +91,6 @@ function normalizeSource(source) {
|
|
|
100
91
|
...(strings(source.args, 'source.args') ? { args: strings(source.args, 'source.args') } : {}),
|
|
101
92
|
...(source.cwd ? { cwd: string(source.cwd, 'source.cwd') } : {}),
|
|
102
93
|
...(source.serverName ? { serverName: string(source.serverName, 'source.serverName') } : {}),
|
|
103
|
-
...(hostRoute(source.route) ? { route: hostRoute(source.route) } : {}),
|
|
104
94
|
...(refs(source.secretHeaders, 'source.secretHeaders') ? { secretHeaders: refs(source.secretHeaders, 'source.secretHeaders') } : {}),
|
|
105
95
|
...(refs(source.secretEnv, 'source.secretEnv') ? { secretEnv: refs(source.secretEnv, 'source.secretEnv') } : {}),
|
|
106
96
|
};
|
package/dist/http.js
CHANGED
|
@@ -16,12 +16,7 @@ function actionDocument(action) {
|
|
|
16
16
|
return { ...action };
|
|
17
17
|
}
|
|
18
18
|
function catalogDocument(catalog) {
|
|
19
|
-
return
|
|
20
|
-
...toolboxIndexDocument(Object.fromEntries(catalog.tools.map((tool) => [tool.id, toolDocument(tool)])), Object.fromEntries(catalog.actions.map((action) => [action.id, actionDocument(action)]))),
|
|
21
|
-
revision: catalog.revision,
|
|
22
|
-
revisionId: catalog.revisionId,
|
|
23
|
-
deployments: catalog.deployments,
|
|
24
|
-
};
|
|
19
|
+
return toolboxIndexDocument(Object.fromEntries(catalog.tools.map((tool) => [tool.id, toolDocument(tool)])), Object.fromEntries(catalog.actions.map((action) => [action.id, actionDocument(action)])));
|
|
25
20
|
}
|
|
26
21
|
async function readBody(req) {
|
|
27
22
|
const chunks = [];
|
package/dist/index.d.ts
CHANGED
|
@@ -2,12 +2,10 @@ export { ArtifactFiles } from './artifact-files.js';
|
|
|
2
2
|
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId, toolboxIndexDocument, userArtifactFileName, } from './artifacts.js';
|
|
3
3
|
export type { ArtifactFileWrite, LegacyMigrationPlan, ToolArtifactDocument, ToolboxIndexDocument, } from './artifacts.js';
|
|
4
4
|
export { defineTool, normalizeDefinition } from './definition.js';
|
|
5
|
-
export { defineHostMcpTool } from './host-mcp-tool.js';
|
|
6
|
-
export { TOOL_DEPLOYMENT_CONTRACT, TOOL_DEPLOYMENT_KIND, TOOL_DEPLOYMENT_SCHEMA_VERSION, assertToolDeploymentActivation, createToolDeployment, deploymentRevisionId, emptyToolDeploymentSnapshot, } from './deployments.js';
|
|
7
5
|
export { catalogDocument, createToolboxHttpServer } from './http.js';
|
|
8
6
|
export type { ToolboxHttpServer } from './http.js';
|
|
9
7
|
export { actionId, actionName, id, mcpName } from './ids.js';
|
|
10
|
-
export { actionTools, callMcpTool, createMcpTools, findMcpTool,
|
|
8
|
+
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools, } from './mcp.js';
|
|
11
9
|
export { createMcpServer } from './mcp-server.js';
|
|
12
10
|
export { Notifications, createNotificationsDriver, notificationToolDefinition, } from './notifications.js';
|
|
13
11
|
export type { EmailDelivery, EmailDeliveryReceipt, EmailNotificationRequest, NotificationLevel, NotificationsOptions, } from './notifications.js';
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
export { ArtifactFiles } from './artifact-files.js';
|
|
2
2
|
export { LEGACY_TOOLBOX_BACKUP_FILE_NAME, LEGACY_TOOLBOX_FILE_NAME, TOOL_ARTIFACT_KIND, TOOL_ARTIFACT_SCHEMA_VERSION, TOOLBOX_INDEX_FILE_NAME, artifactDocument, catalogIndexDocument, isToolArtifactDocument, legacyMigrationPlan, safeToolId, toolboxIndexDocument, userArtifactFileName, } from './artifacts.js';
|
|
3
3
|
export { defineTool, normalizeDefinition } from './definition.js';
|
|
4
|
-
export { defineHostMcpTool } from './host-mcp-tool.js';
|
|
5
|
-
export { TOOL_DEPLOYMENT_CONTRACT, TOOL_DEPLOYMENT_KIND, TOOL_DEPLOYMENT_SCHEMA_VERSION, assertToolDeploymentActivation, createToolDeployment, deploymentRevisionId, emptyToolDeploymentSnapshot, } from './deployments.js';
|
|
6
4
|
export { catalogDocument, createToolboxHttpServer } from './http.js';
|
|
7
5
|
export { actionId, actionName, id, mcpName } from './ids.js';
|
|
8
|
-
export { actionTools, callMcpTool, createMcpTools, findMcpTool,
|
|
6
|
+
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools, } from './mcp.js';
|
|
9
7
|
export { createMcpServer } from './mcp-server.js';
|
|
10
8
|
export { Notifications, createNotificationsDriver, notificationToolDefinition, } from './notifications.js';
|
|
11
9
|
export { createProxyEmailDelivery } from './proxy-email.js';
|
package/dist/mcp-server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import readline from 'node:readline';
|
|
2
2
|
import type { Readable, Writable } from 'node:stream';
|
|
3
3
|
import { Toolbox } from './toolbox.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type { ToolboxOptions } from './types.js';
|
|
5
5
|
interface Request {
|
|
6
6
|
jsonrpc?: string;
|
|
7
7
|
id?: string | number;
|
|
@@ -10,7 +10,6 @@ interface Request {
|
|
|
10
10
|
}
|
|
11
11
|
declare function createMcpServer(options?: ToolboxOptions & {
|
|
12
12
|
toolbox?: Toolbox;
|
|
13
|
-
mcp?: McpOptions;
|
|
14
13
|
}): {
|
|
15
14
|
toolbox: Toolbox;
|
|
16
15
|
handle: (request: Request) => Promise<unknown>;
|
package/dist/mcp-server.js
CHANGED
|
@@ -7,7 +7,6 @@ function descriptor(tool) {
|
|
|
7
7
|
}
|
|
8
8
|
function createMcpServer(options = {}) {
|
|
9
9
|
const toolbox = options.toolbox || new Toolbox(options);
|
|
10
|
-
const mcpOptions = options.mcp || {};
|
|
11
10
|
async function handle(request) {
|
|
12
11
|
if (request.method === 'initialize') {
|
|
13
12
|
return {
|
|
@@ -18,12 +17,12 @@ function createMcpServer(options = {}) {
|
|
|
18
17
|
}
|
|
19
18
|
if (request.method === 'ping')
|
|
20
19
|
return {};
|
|
21
|
-
const tools = createMcpTools(toolbox
|
|
20
|
+
const tools = createMcpTools(toolbox);
|
|
22
21
|
if (request.method === 'tools/list')
|
|
23
22
|
return { tools: tools.map(descriptor) };
|
|
24
23
|
if (request.method === 'tools/call') {
|
|
25
24
|
try {
|
|
26
|
-
return await callMcpTool(toolbox, String(request.params?.name || ''), request.params?.arguments || {}
|
|
25
|
+
return await callMcpTool(toolbox, String(request.params?.name || ''), request.params?.arguments || {});
|
|
27
26
|
}
|
|
28
27
|
catch (error) {
|
|
29
28
|
if (error instanceof Error && error.message.startsWith('Unknown tool:')) {
|
package/dist/mcp.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { Toolbox } from './toolbox.js';
|
|
2
2
|
import type { JsonSchema, McpOptions, McpTool } from './types.js';
|
|
3
3
|
declare function portable(schema: JsonSchema): JsonSchema;
|
|
4
|
-
declare function managementToolDescriptors(): Array<Omit<McpTool, 'handler'>>;
|
|
5
4
|
declare function managementTools(toolbox: Toolbox): McpTool[];
|
|
6
5
|
declare function actionTools(toolbox: Toolbox, options?: McpOptions): McpTool[];
|
|
7
6
|
declare function createMcpTools(toolbox: Toolbox, options?: McpOptions): McpTool[];
|
|
8
7
|
declare function findMcpTool(toolbox: Toolbox, name: string, options?: McpOptions): McpTool | null;
|
|
9
8
|
declare function callMcpTool(toolbox: Toolbox, name: string, input?: Record<string, unknown>, options?: McpOptions): Promise<import("./types.js").ToolResult>;
|
|
10
|
-
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools,
|
|
9
|
+
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools, portable, };
|
package/dist/mcp.js
CHANGED
|
@@ -21,57 +21,45 @@ function managed(definition, handler) {
|
|
|
21
21
|
},
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function managementTools(toolbox) {
|
|
25
25
|
const idProperty = { id: { type: 'string', description: 'Tool or action id' } };
|
|
26
26
|
return [
|
|
27
|
-
{
|
|
27
|
+
managed({
|
|
28
28
|
name: 'toolbox_tools_list', description: 'List the canonical Toolbox catalog.',
|
|
29
29
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
30
|
-
},
|
|
31
|
-
{
|
|
30
|
+
}, () => toolbox.catalog()),
|
|
31
|
+
managed({
|
|
32
32
|
name: 'toolbox_tool_get', description: 'Get one tool and its actions.',
|
|
33
33
|
inputSchema: { type: 'object', properties: idProperty, required: ['id'], additionalProperties: false },
|
|
34
|
-
},
|
|
35
|
-
|
|
34
|
+
}, ({ id }) => {
|
|
35
|
+
const result = toolbox.get(String(id));
|
|
36
|
+
if (!result)
|
|
37
|
+
throw new Error(`Unknown tool: ${id}`);
|
|
38
|
+
return result;
|
|
39
|
+
}),
|
|
40
|
+
managed({
|
|
36
41
|
name: 'toolbox_tool_apply', description: 'Atomically apply an authoritative tool definition.',
|
|
37
42
|
inputSchema: {
|
|
38
43
|
type: 'object', required: ['tool'], additionalProperties: false,
|
|
39
44
|
properties: { tool: { type: 'object', description: 'Complete tool definition' } },
|
|
40
45
|
},
|
|
41
|
-
},
|
|
42
|
-
{
|
|
46
|
+
}, ({ tool }) => toolbox.apply(tool)),
|
|
47
|
+
managed({
|
|
43
48
|
name: 'toolbox_record_enable', description: 'Enable one user-owned tool or action.',
|
|
44
49
|
inputSchema: { type: 'object', properties: idProperty, required: ['id'], additionalProperties: false },
|
|
45
|
-
},
|
|
46
|
-
{
|
|
50
|
+
}, ({ id }) => toolbox.setStatus(String(id), 'enabled')),
|
|
51
|
+
managed({
|
|
47
52
|
name: 'toolbox_record_disable', description: 'Disable one user-owned tool or action.',
|
|
48
53
|
inputSchema: { type: 'object', properties: idProperty, required: ['id'], additionalProperties: false },
|
|
49
|
-
},
|
|
50
|
-
{
|
|
54
|
+
}, ({ id }) => toolbox.setStatus(String(id), 'disabled')),
|
|
55
|
+
managed({
|
|
51
56
|
name: 'toolbox_record_remove', description: 'Remove one user-owned tool or action.',
|
|
52
57
|
inputSchema: { type: 'object', properties: idProperty, required: ['id'], additionalProperties: false },
|
|
53
|
-
},
|
|
54
|
-
{
|
|
58
|
+
}, ({ id }) => toolbox.remove(String(id))),
|
|
59
|
+
managed({
|
|
55
60
|
name: 'toolbox_mcp_connections', description: 'List external MCP connections for the composing host.',
|
|
56
61
|
inputSchema: { type: 'object', properties: {}, additionalProperties: false },
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
function managementTools(toolbox) {
|
|
61
|
-
const [list, get, apply, enable, disable, remove, connections] = managementToolDescriptors();
|
|
62
|
-
return [
|
|
63
|
-
managed(list, () => toolbox.catalog()),
|
|
64
|
-
managed(get, ({ id }) => {
|
|
65
|
-
const result = toolbox.get(String(id));
|
|
66
|
-
if (!result)
|
|
67
|
-
throw new Error(`Unknown tool: ${id}`);
|
|
68
|
-
return result;
|
|
69
|
-
}),
|
|
70
|
-
managed(apply, ({ tool }) => toolbox.apply(tool)),
|
|
71
|
-
managed(enable, ({ id }) => toolbox.setStatus(String(id), 'enabled')),
|
|
72
|
-
managed(disable, ({ id }) => toolbox.setStatus(String(id), 'disabled')),
|
|
73
|
-
managed(remove, ({ id }) => toolbox.remove(String(id))),
|
|
74
|
-
managed(connections, () => toolbox.connections()),
|
|
62
|
+
}, () => toolbox.connections()),
|
|
75
63
|
];
|
|
76
64
|
}
|
|
77
65
|
function actionTools(toolbox, options = {}) {
|
|
@@ -104,4 +92,4 @@ async function callMcpTool(toolbox, name, input = {}, options = {}) {
|
|
|
104
92
|
throw new Error(`Unknown tool: ${name}`);
|
|
105
93
|
return tool.handler(input);
|
|
106
94
|
}
|
|
107
|
-
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools,
|
|
95
|
+
export { actionTools, callMcpTool, createMcpTools, findMcpTool, managementTools, portable, };
|
package/dist/notifications.js
CHANGED
|
@@ -18,12 +18,11 @@ function contextSessionId(value) {
|
|
|
18
18
|
function notificationToolDefinition() {
|
|
19
19
|
return {
|
|
20
20
|
id: 'notifications',
|
|
21
|
-
name: '
|
|
21
|
+
name: 'Notifications',
|
|
22
22
|
description: 'Notify the current user about important results, completions, and failures.',
|
|
23
23
|
owner: 'amalgm',
|
|
24
24
|
origin: 'system',
|
|
25
|
-
source: { type: 'mcp', transport: 'host', serverName: '
|
|
26
|
-
policy: { firstParty: true },
|
|
25
|
+
source: { type: 'mcp', transport: 'host', serverName: 'notifications' },
|
|
27
26
|
actions: [{
|
|
28
27
|
name: 'notify_user',
|
|
29
28
|
description: 'Send the current user an email notification. Keep it concise and actionable.',
|
|
@@ -92,7 +91,7 @@ function createNotificationsDriver(notifications) {
|
|
|
92
91
|
return tool.id === 'notifications'
|
|
93
92
|
&& tool.source.type === 'mcp'
|
|
94
93
|
&& tool.source.transport === 'host'
|
|
95
|
-
&& tool.source.serverName === '
|
|
94
|
+
&& tool.source.serverName === 'notifications';
|
|
96
95
|
},
|
|
97
96
|
async call({ action, input, options }) {
|
|
98
97
|
if (action.id !== 'notifications.notify_user')
|
package/dist/schema.js
CHANGED
|
@@ -21,21 +21,6 @@ function migrate(db) {
|
|
|
21
21
|
UNIQUE(tool_id, id)
|
|
22
22
|
);
|
|
23
23
|
CREATE INDEX IF NOT EXISTS actions_tool_id ON actions(tool_id);
|
|
24
|
-
|
|
25
|
-
CREATE TABLE IF NOT EXISTS tool_deployments (
|
|
26
|
-
id TEXT PRIMARY KEY,
|
|
27
|
-
tool_id TEXT NOT NULL,
|
|
28
|
-
previous_deployment_id TEXT,
|
|
29
|
-
created_at TEXT NOT NULL,
|
|
30
|
-
record_json TEXT NOT NULL
|
|
31
|
-
);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS tool_deployments_tool_id
|
|
33
|
-
ON tool_deployments(tool_id, created_at, id);
|
|
34
|
-
|
|
35
|
-
CREATE TABLE IF NOT EXISTS tool_heads (
|
|
36
|
-
tool_id TEXT PRIMARY KEY,
|
|
37
|
-
deployment_id TEXT NOT NULL REFERENCES tool_deployments(id)
|
|
38
|
-
);
|
|
39
24
|
`);
|
|
40
25
|
}
|
|
41
26
|
export { migrate };
|
package/dist/store.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Database from 'better-sqlite3';
|
|
2
|
-
import type { ActionRecord, ApplyResult, Catalog,
|
|
2
|
+
import type { ActionRecord, ApplyResult, Catalog, Status, ToolRecord } from './types.js';
|
|
3
3
|
declare class Store {
|
|
4
4
|
readonly db: Database.Database;
|
|
5
5
|
constructor(file: string);
|
|
@@ -8,23 +8,10 @@ declare class Store {
|
|
|
8
8
|
getTool(id: string): ToolRecord | null;
|
|
9
9
|
getAction(id: string): ActionRecord | null;
|
|
10
10
|
actionsFor(toolId: string): ActionRecord[];
|
|
11
|
-
heads(): Record<string, string>;
|
|
12
11
|
catalog(): Catalog;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
allDeployments(): ToolDeployment[];
|
|
17
|
-
deploymentSnapshot(): ToolDeploymentSnapshot;
|
|
18
|
-
/** Add a baseline for a pre-deployment database without changing its catalog bytes. */
|
|
19
|
-
adoptDeployment(activation: ToolDeploymentActivation): void;
|
|
20
|
-
applyDeployment(activation: ToolDeploymentActivation): {
|
|
21
|
-
changed: boolean;
|
|
22
|
-
result: ApplyResult | null;
|
|
23
|
-
};
|
|
24
|
-
replaceDeploymentSnapshot(snapshot: ToolDeploymentSnapshot): void;
|
|
25
|
-
private insertDeployment;
|
|
26
|
-
private setHead;
|
|
27
|
-
private materializeDefinition;
|
|
12
|
+
apply(result: ApplyResult): ApplyResult;
|
|
13
|
+
setStatus(id: string, status: Status, now: string): ToolRecord | ActionRecord | null;
|
|
14
|
+
remove(id: string): ToolRecord | ActionRecord | null;
|
|
28
15
|
close(): void;
|
|
29
16
|
}
|
|
30
17
|
export { Store };
|