@axonity-ai/mcp 0.1.0 → 0.3.2
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 +172 -24
- package/dist/client.d.ts +11 -2
- package/dist/client.js +28 -10
- package/dist/client.js.map +1 -1
- package/dist/errors.d.ts +53 -10
- package/dist/errors.js +163 -19
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +21 -0
- package/dist/index.js +135 -4
- package/dist/index.js.map +1 -1
- package/dist/tools/company.d.ts +16 -0
- package/dist/tools/company.js +81 -0
- package/dist/tools/company.js.map +1 -0
- package/dist/tools/conventions.d.ts +10 -4
- package/dist/tools/conventions.js +389 -23
- package/dist/tools/conventions.js.map +1 -1
- package/dist/tools/credentials.d.ts +34 -0
- package/dist/tools/credentials.js +106 -0
- package/dist/tools/credentials.js.map +1 -0
- package/dist/tools/extras.d.ts +14 -5
- package/dist/tools/extras.js +85 -40
- package/dist/tools/extras.js.map +1 -1
- package/dist/tools/promptPlacement.d.ts +15 -0
- package/dist/tools/promptPlacement.js +99 -0
- package/dist/tools/promptPlacement.js.map +1 -0
- package/dist/tools/register.d.ts +67 -10
- package/dist/tools/register.js +77 -22
- package/dist/tools/register.js.map +1 -1
- package/dist/tools/runs.d.ts +14 -0
- package/dist/tools/runs.js +103 -0
- package/dist/tools/runs.js.map +1 -0
- package/dist/tools/triggers.d.ts +13 -0
- package/dist/tools/triggers.js +128 -0
- package/dist/tools/triggers.js.map +1 -0
- package/dist/tools/validation.d.ts +13 -0
- package/dist/tools/validation.js +116 -0
- package/dist/tools/validation.js.map +1 -0
- package/dist/tools/versions.d.ts +37 -0
- package/dist/tools/versions.js +104 -0
- package/dist/tools/versions.js.map +1 -0
- package/dist/tools/workflowMutations.d.ts +22 -0
- package/dist/tools/workflowMutations.js +118 -23
- package/dist/tools/workflowMutations.js.map +1 -1
- package/package.json +2 -2
|
@@ -5,41 +5,136 @@
|
|
|
5
5
|
* backend-authoritative model the Studio uses), never by replacing the whole
|
|
6
6
|
* document. The backend applies and validates the commands and returns the new
|
|
7
7
|
* authoritative document + version.
|
|
8
|
+
*
|
|
9
|
+
* The backend route applies exactly ONE mutation per call — `POST
|
|
10
|
+
* /workflows/{id}/mutations` takes `{ type, payload, expectedVersion }` and there
|
|
11
|
+
* is no batch route. This tool keeps a batch-shaped signature (an agent thinks in
|
|
12
|
+
* whole edits, not round-trips) and sequences the calls itself, threading the
|
|
13
|
+
* version returned by call N into call N+1.
|
|
14
|
+
*
|
|
15
|
+
* Because the sequence is not a transaction, a failure at index k leaves the
|
|
16
|
+
* mutations before it applied. The error says how many landed and which one
|
|
17
|
+
* failed so the caller can re-read and resume rather than blindly retry — a
|
|
18
|
+
* retry from the top would re-apply the successful prefix.
|
|
8
19
|
*/
|
|
9
20
|
import { z } from "zod";
|
|
10
21
|
import { AxonityApiError } from "../errors.js";
|
|
22
|
+
import { guard, jsonResult } from "./result.js";
|
|
23
|
+
/** A required literal — an agent cannot satisfy it by filling in a default. */
|
|
24
|
+
const CONFIRM = z
|
|
25
|
+
.literal(true)
|
|
26
|
+
.describe("Must be true. Acknowledges you understand this is destructive.");
|
|
27
|
+
/**
|
|
28
|
+
* Split one command into the `{ type, payload }` pair the backend expects.
|
|
29
|
+
*
|
|
30
|
+
* Accepts both the explicit form (`{ type, payload: {...} }`) and the flat form
|
|
31
|
+
* (`{ type, ...args }`), because an agent writing these by hand produces either
|
|
32
|
+
* and the difference is not meaningful to it.
|
|
33
|
+
*/
|
|
34
|
+
export function toMutationBody(mutation, index) {
|
|
35
|
+
const { type, payload, ...rest } = mutation;
|
|
36
|
+
if (typeof type !== "string" || type.length === 0) {
|
|
37
|
+
throw new Error(`mutations[${index}] is missing a \`type\` (e.g. "add_step", "add_edge").`);
|
|
38
|
+
}
|
|
39
|
+
if (payload !== undefined) {
|
|
40
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
|
|
41
|
+
throw new Error(`mutations[${index}].payload must be a JSON object.`);
|
|
42
|
+
}
|
|
43
|
+
return { type, payload: payload };
|
|
44
|
+
}
|
|
45
|
+
return { type, payload: rest };
|
|
46
|
+
}
|
|
47
|
+
/** Compose the error for a mutation that failed part-way through a sequence. */
|
|
48
|
+
function sequenceError(index, total, type, version, cause) {
|
|
49
|
+
const reason = cause instanceof AxonityApiError || cause instanceof Error
|
|
50
|
+
? cause.message
|
|
51
|
+
: String(cause);
|
|
52
|
+
const applied = index;
|
|
53
|
+
const summary = JSON.stringify({ appliedCount: applied, failedIndex: index, failedType: type, currentVersion: version }, null, 2);
|
|
54
|
+
return new Error(`Mutation ${index + 1} of ${total} (\`${type}\`) failed: ${reason}\n\n` +
|
|
55
|
+
`${applied} of ${total} mutations were already applied and were NOT rolled back — ` +
|
|
56
|
+
`this sequence is not a transaction. Do not retry the whole list: re-read the ` +
|
|
57
|
+
`workflow, confirm which edits landed, and resume from index ${index}.\n\n` +
|
|
58
|
+
summary);
|
|
59
|
+
}
|
|
11
60
|
export function registerWorkflowMutations(server, client) {
|
|
12
61
|
server.tool("apply_workflow_mutations", "Apply structural mutation commands to a workflow draft (add/remove steps, " +
|
|
13
62
|
"connect edges, set conditions). Read the workflow first for its version. " +
|
|
14
|
-
"
|
|
15
|
-
"
|
|
63
|
+
"Commands are applied IN ORDER, one backend call each, with the version " +
|
|
64
|
+
"threaded automatically — pass the version you read, not one per command. " +
|
|
65
|
+
"Returns the new authoritative document, version, and validation state. " +
|
|
66
|
+
"Not transactional: if command N fails, commands before it stay applied and " +
|
|
67
|
+
"the error reports how many landed. On a 409 conflict, re-read and retry. " +
|
|
68
|
+
'Each command is `{ "type": "add_step", "payload": { … } }`; the flat form ' +
|
|
69
|
+
'`{ "type": "add_step", … }` is accepted too. Valid types: update_workflow, ' +
|
|
70
|
+
"add_trigger, update_trigger, remove_trigger, update_trigger_operator, " +
|
|
71
|
+
"group_triggers, ungroup_triggers, move_trigger, add_step, add_loop, " +
|
|
72
|
+
"update_step, remove_step, move_step, add_edge, update_edge, remove_edge, " +
|
|
73
|
+
"convert_to_loop, setup_loop_decision, advanced_edit.", {
|
|
16
74
|
id: z.string().describe("The workflow's id."),
|
|
17
75
|
expectedVersion: z
|
|
18
76
|
.number()
|
|
19
77
|
.int()
|
|
20
|
-
.describe("The version you last read
|
|
78
|
+
.describe("The version you last read. Only the FIRST command uses it; later " +
|
|
79
|
+
"commands use the version returned by the previous one."),
|
|
21
80
|
mutations: z
|
|
22
81
|
.array(z.record(z.unknown()))
|
|
23
|
-
.
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return { content: [{ type: "text", text: message }], isError: true };
|
|
82
|
+
.min(1)
|
|
83
|
+
.describe("Mutation commands to apply in order, each a JSON object with a " +
|
|
84
|
+
"`type` and its arguments (camelCase), either nested under " +
|
|
85
|
+
"`payload` or inline."),
|
|
86
|
+
}, async ({ id, expectedVersion, mutations }) => guard(async () => {
|
|
87
|
+
// Reject the whole batch on a malformed command before applying any of
|
|
88
|
+
// it — a shape error is the agent's mistake, not a partial failure.
|
|
89
|
+
const bodies = mutations.map((m, i) => toMutationBody(m, i));
|
|
90
|
+
let version = expectedVersion;
|
|
91
|
+
let last;
|
|
92
|
+
for (const [index, body] of bodies.entries()) {
|
|
93
|
+
try {
|
|
94
|
+
last = await client.post(`/api/v1/workflows/${id}/mutations`, { type: body.type, payload: body.payload, expectedVersion: version });
|
|
95
|
+
}
|
|
96
|
+
catch (cause) {
|
|
97
|
+
throw sequenceError(index, bodies.length, body.type, version, cause);
|
|
98
|
+
}
|
|
99
|
+
version = last.version;
|
|
42
100
|
}
|
|
43
|
-
|
|
101
|
+
return jsonResult({ ...last, appliedCount: bodies.length });
|
|
102
|
+
}));
|
|
103
|
+
server.tool("replace_workflow_document", "Replace the ENTIRE workflow document in one atomic call. Read the workflow first to " +
|
|
104
|
+
"get the current version, then call this again only after rereading on a stale " +
|
|
105
|
+
"`409`.\n" +
|
|
106
|
+
"Unlike `apply_workflow_mutations`, this is a single PUT request and treats the " +
|
|
107
|
+
"payload as the complete editable document.", {
|
|
108
|
+
id: z.string().describe("The workflow's id."),
|
|
109
|
+
expectedVersion: z
|
|
110
|
+
.number()
|
|
111
|
+
.int()
|
|
112
|
+
.describe("The version you read before replacing the document."),
|
|
113
|
+
document: z
|
|
114
|
+
.record(z.unknown())
|
|
115
|
+
.describe("The complete workflow document object to persist."),
|
|
116
|
+
}, async ({ id, expectedVersion, document }) => guard(async () => jsonResult(await client.put(`/api/v1/workflows/${id}`, {
|
|
117
|
+
expectedVersion,
|
|
118
|
+
document,
|
|
119
|
+
}))));
|
|
120
|
+
server.tool("read_workflow_trigger_parameters", "Read the input parameters a workflow's triggers expect — what a caller must " +
|
|
121
|
+
"supply to start it. Use this before authoring a webhook/cron/conditional " +
|
|
122
|
+
"trigger, or before start_workflow_run, so the trigger input matches. Read-only.", { workflowId: z.string().describe("The workflow's id.") }, async ({ workflowId }) => guard(async () => jsonResult(await client.get(`/api/v1/workflows/${workflowId}/trigger-parameters`))));
|
|
123
|
+
server.tool("bulk_delete_workflows", "Soft-delete several workflows at once (each recoverable with " +
|
|
124
|
+
"restore_workflow, like single delete_workflow). Each target needs its own " +
|
|
125
|
+
"current version for optimistic locking — read each first. Returns a " +
|
|
126
|
+
"per-workflow success/error result; a partial failure is possible.", {
|
|
127
|
+
workflows: z
|
|
128
|
+
.array(z.object({
|
|
129
|
+
id: z.string().describe("The workflow's id."),
|
|
130
|
+
expectedVersion: z
|
|
131
|
+
.number()
|
|
132
|
+
.int()
|
|
133
|
+
.describe("That workflow's last-read version — 409 if stale."),
|
|
134
|
+
}))
|
|
135
|
+
.min(1)
|
|
136
|
+
.describe("The workflows to delete, each with its expectedVersion."),
|
|
137
|
+
confirm: CONFIRM,
|
|
138
|
+
}, async ({ workflows }) => guard(async () => jsonResult(await client.post("/api/v1/workflows/bulk-delete", { workflows }))));
|
|
44
139
|
}
|
|
45
140
|
//# sourceMappingURL=workflowMutations.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflowMutations.js","sourceRoot":"","sources":["../../src/tools/workflowMutations.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"workflowMutations.js","sourceRoot":"","sources":["../../src/tools/workflowMutations.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axonity-ai/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Model Context Protocol server for Axonity Flow — lets an external agent (e.g. Claude Code) read, draft, and update workflows, agents and tools in an Axonity tenant.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -47,6 +47,6 @@
|
|
|
47
47
|
"@types/node": "^20.14.0",
|
|
48
48
|
"tsx": "^4.16.0",
|
|
49
49
|
"typescript": "^5.5.0",
|
|
50
|
-
"vitest": "^
|
|
50
|
+
"vitest": "^4.1.10"
|
|
51
51
|
}
|
|
52
52
|
}
|