@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.
Files changed (44) hide show
  1. package/README.md +172 -24
  2. package/dist/client.d.ts +11 -2
  3. package/dist/client.js +28 -10
  4. package/dist/client.js.map +1 -1
  5. package/dist/errors.d.ts +53 -10
  6. package/dist/errors.js +163 -19
  7. package/dist/errors.js.map +1 -1
  8. package/dist/index.d.ts +21 -0
  9. package/dist/index.js +135 -4
  10. package/dist/index.js.map +1 -1
  11. package/dist/tools/company.d.ts +16 -0
  12. package/dist/tools/company.js +81 -0
  13. package/dist/tools/company.js.map +1 -0
  14. package/dist/tools/conventions.d.ts +10 -4
  15. package/dist/tools/conventions.js +389 -23
  16. package/dist/tools/conventions.js.map +1 -1
  17. package/dist/tools/credentials.d.ts +34 -0
  18. package/dist/tools/credentials.js +106 -0
  19. package/dist/tools/credentials.js.map +1 -0
  20. package/dist/tools/extras.d.ts +14 -5
  21. package/dist/tools/extras.js +85 -40
  22. package/dist/tools/extras.js.map +1 -1
  23. package/dist/tools/promptPlacement.d.ts +15 -0
  24. package/dist/tools/promptPlacement.js +99 -0
  25. package/dist/tools/promptPlacement.js.map +1 -0
  26. package/dist/tools/register.d.ts +67 -10
  27. package/dist/tools/register.js +77 -22
  28. package/dist/tools/register.js.map +1 -1
  29. package/dist/tools/runs.d.ts +14 -0
  30. package/dist/tools/runs.js +103 -0
  31. package/dist/tools/runs.js.map +1 -0
  32. package/dist/tools/triggers.d.ts +13 -0
  33. package/dist/tools/triggers.js +128 -0
  34. package/dist/tools/triggers.js.map +1 -0
  35. package/dist/tools/validation.d.ts +13 -0
  36. package/dist/tools/validation.js +116 -0
  37. package/dist/tools/validation.js.map +1 -0
  38. package/dist/tools/versions.d.ts +37 -0
  39. package/dist/tools/versions.js +104 -0
  40. package/dist/tools/versions.js.map +1 -0
  41. package/dist/tools/workflowMutations.d.ts +22 -0
  42. package/dist/tools/workflowMutations.js +118 -23
  43. package/dist/tools/workflowMutations.js.map +1 -1
  44. package/package.json +2 -2
@@ -2,51 +2,417 @@
2
2
  * The `axonity_conventions` guidance tool.
3
3
  *
4
4
  * An external agent needs the same authoring rules the internal Builder team
5
- * carries, or its drafts will be low quality. This is a static conventions
6
- * reference for the MLP; a single-sourced `discover_<entity>_operations` tool
7
- * backed by the platform's own discovery contract is a planned refinement
8
- * (epic #652 C4 — "prefer a thin backend read endpoint").
5
+ * carries, or its drafts will be low quality. This is agent-facing GUIDANCE:
6
+ * build order, "complete when…" bars, wiring, and the prompt-placement / Memory
7
+ * V2 model — the parts a schema can't express.
8
+ *
9
+ * The hard facts it references (field names, enum values, required-ness) are NOT
10
+ * a second source of truth: the backend OpenAPI schema is authoritative
11
+ * (axonity-flow#722, Option 1). `test/conformance.test.ts` pins the routes here
12
+ * and the enums quoted below to a vendored snapshot of that schema, so a drift
13
+ * between this prose and the backend fails CI rather than misleading an agent.
14
+ * Keep enum lists in this doc in step with what that test asserts.
9
15
  */
10
16
  const CONVENTIONS = `# Authoring conventions for Axonity entities
11
17
 
12
18
  Read this before creating or updating anything.
13
19
 
20
+ ## What this connector is for
21
+ - AUTHORING: composing an entity from intent — drafting a tool, an agent, a
22
+ workflow, and wiring them together so the result is CORRECT and COMPLETE
23
+ (every required field set, every reference pointing at something real).
24
+ - REPRODUCING a setup is just authoring it again, from scratch. To recreate an
25
+ agent/workflow/tool, CREATE NEW entities and wire them by their NEW ids —
26
+ never reuse an id you read. There is no "migration" and no "import an id":
27
+ this connector only ever acts in the ONE tenant its token points at (see
28
+ Tenant), and ids are tenant-local, so an id from anywhere else points at
29
+ nothing (or the wrong thing) here. Read the source for its SHAPE and intent —
30
+ names, field values, which tools an agent uses, which agents a workflow's
31
+ steps run — then build fresh and capture the ids the create calls return.
32
+ Recreating into a DIFFERENT tenant means running that build while the
33
+ connector is configured with THAT tenant's token — a separate session. See
34
+ "Reproducing a setup" below.
35
+
36
+ ## The authoring loop
37
+ 1. \`read_*\` the entity (and \`read_*_published\` if you need to see what is live).
38
+ 2. Edit the DRAFT: \`update_*\`, or workflow-edit tools for workflow structure.
39
+ 3. Validate before publish: \`validate_workflow\` / \`analyze_workflow_reachable_outputs\` /
40
+ \`validate_tool_code\` / \`format_tool_code\`. These four are stateless and work with
41
+ read-only tokens.
42
+ 4. Re-read and verify with a saved tool command: \`execute_tool\` / \`execute_stored_connector\`.
43
+ 5. Fix any issues and re-read again.
44
+ 6. \`request_publish_*\` — this only QUEUES a human approval.
45
+ 7. \`list_publish_approvals\` / \`get_publish_approval\` to see whether it was
46
+ approved or rejected.
47
+ 8. If something went wrong:
48
+ - Bad edit, entity still exists → \`list_*_versions\` then \`restore_*_version\`
49
+ to roll the draft back to an earlier version.
50
+ - Never published, want a clean slate → \`discard_*_draft\` resets the draft to
51
+ the last published state (fails if it was never published — there's nothing
52
+ to fall back to).
53
+ - Deleted by mistake → \`restore_*\` (see "Delete is recoverable" below).
54
+
14
55
  ## Drafts, not live
15
56
  - \`create_*\` and \`update_*\` produce a DRAFT. The live runtime is unaffected
16
- until a human publishes it in Axonity. You cannot publish directly.
57
+ until a human publishes it in Axonity. \`flow\` has the same rule: runtime uses
58
+ the published snapshot from \`read_flow_published\` until \`request_publish_flow\`
59
+ is approved.
60
+ - You cannot publish directly — the backend refuses a direct publish from a service
61
+ token with a 403, so there is no tool for it and no way around it.
62
+ - A read-only token can only read: any write returns 403. If you see that, ask
63
+ your human for a write-scoped token rather than retrying.
17
64
  - \`request_publish_*\` does NOT publish — it creates a pending approval a human
18
65
  approves in Axonity. Use it when a draft is ready; then tell the user to
19
66
  approve it in their Axonity approvals inbox.
20
67
 
21
68
  ## Optimistic locking (always read-then-write)
22
69
  - Before \`update_*\`, call \`read_*\` and use the \`version\` you get as
23
- \`expectedVersion\`. If the update returns a 409 conflict, someone else changed
24
- it — read again and re-apply your change onto the new version.
70
+ \`expectedVersion\` — in the request BODY. If the update returns a 409
71
+ conflict, someone else changed it — read again and re-apply your change onto
72
+ the new version.
73
+ - \`delete_*\` also takes \`expectedVersion\`, but as an argument on the tool call
74
+ only — the connector maps it to whatever query-parameter spelling that
75
+ entity's route actually expects (it differs per entity on the wire; you never
76
+ need to know which).
77
+ - \`restore_*\` and \`restore_deleted_*_version\` take NO version at all — a
78
+ restore must never lose to a stale-version guard.
79
+
80
+ ## Errors: branch on the failure, not the words
81
+ - Every error names what went wrong as plainly as the backend allows. For a 409
82
+ specifically, two different problems share that status code and need
83
+ different responses:
84
+ - **Version conflict** — you had a stale read. Re-read, re-apply, retry.
85
+ - **Reference conflict** — the entity is referenced by something published or
86
+ live. Retrying will never help. Detach the reference or unpublish the
87
+ referencing entity first.
88
+ The error message tells you which one you hit — read it, don't assume 409
89
+ always means "retry."
90
+ - A 403 on any write means the token is read-only, or (for a direct publish
91
+ attempt, which no tool makes) that publishing must go through
92
+ \`request_publish_*\`. Either way: stop, don't retry, tell your human.
93
+ - A 401 means the service token is dead — missing, wrong, expired, or revoked.
94
+ **The backend deliberately returns the identical message for all four
95
+ causes** so it doesn't leak which applies; you have no way to tell them
96
+ apart and no way to check a token's remaining lifetime in advance (every
97
+ token now expires — 7, 15, 30, 60 or 90 days, chosen when it was minted;
98
+ there is no "never"). On any 401: stop, do not retry, and tell your human
99
+ plainly that the configured token is no longer valid and a new one must be
100
+ minted from Axonity → Settings → API tokens. Do not guess or imply the cause.
25
101
 
26
102
  ## Field shape
27
103
  - All fields are camelCase JSON (e.g. \`capabilityTier\`, not \`capability_tier\`).
104
+ ONE documented exception: validator specs (\`permissions.outputValidators\`,
105
+ \`permissions.exposedValidatorTools\`) use snake_case keys (\`function\`,
106
+ \`target\`, \`args\`, \`error_message\`, \`tool_name\`, \`validator_name\`) — they are
107
+ the same shape at every level and are stored verbatim, so they are NOT
108
+ camel-aliased. Send them in snake_case.
28
109
  - \`update_*\` is a partial change for agents/tools and a partial patch for
29
- workflows: send only the fields you are changing.
30
- - The backend validates fields; a 422 error tells you exactly which field is wrong.
31
-
32
- ## Per entity
33
- - **workflow**: \`create_workflow\` makes a stub (name, description). Build its
34
- steps/edges with \`apply_workflow_mutations\` (a list of mutation commands) —
35
- the workflow document is edited through commands, never by replacing it wholesale.
36
- - **agent**: fields include name, avatar, capabilityTier, creativityTier,
37
- learningMode, permissions, delegationTargetIds, toolIds, systemToolIds, status.
38
- - **tool**: fields include name, description, type
39
- ("function" | "connector" | "validator" | "evaluator"), inputSchema,
40
- outputSchema, implementation, authConfig, status. For a connector, set
41
- \`type: "connector"\`; NEVER put real credentials in authConfig — use
42
- placeholders and let a human fill secrets in the Axonity tool editor.
110
+ workflows: send only the fields you are changing (plus \`expectedVersion\`).
111
+ - The backend validates fields; a 422 error names the offending field and why
112
+ (e.g. \`body.capabilityTier: Input should be 'economy', 'standard', 'smart' or
113
+ 'reasoning'\`). Fix that field and retry — do not guess at the whole shape.
114
+ - **create/update for tool and agent are STRICT** (\`extra="forbid"\`): an
115
+ undeclared OR MISSPELLED key is a 422 that names it, not a silent drop. So
116
+ spelling matters and you get told when it is wrong — good. Other entities are
117
+ more lenient and may drop an unknown key silently; never rely on that.
118
+ - \`agent.tags\` is not cosmetic: it drives which policies apply to the agent at
119
+ runtime. An untagged agent looks correct everywhere in the UI and silently
120
+ skips policies scoped to those tags. If you create or update an agent that
121
+ should be governed by a policy, check its tags match what the policy expects.
122
+
123
+ ## After you write, verify
124
+ - A 200 means the request was accepted, NOT that it did what you meant. Re-read
125
+ the entity after a mutation and diff it against your intent — a partial update
126
+ only changes what you sent, and on the lenient (non-tool/agent) entities an
127
+ unknown key can be dropped silently rather than rejected.
128
+ - Re-reading the ENTITY is not enough for an \`attach_*\`: those links are stored
129
+ outside the entity body and never appear in \`read_agent\`. Read them back with
130
+ \`list_agent_skills\` / \`list_agent_policies\` / \`list_agent_reference_docs\`
131
+ (see Wiring, mechanism B).
132
+ - "Complete" is your job, not the backend's. A create succeeds with only the
133
+ required fields set; it does not tell you the entity is USABLE. An agent with
134
+ no \`toolIds\` runs with no tools; a connector tool with an empty
135
+ \`implementation\` has no endpoint to call; a workflow with steps but no
136
+ trigger never fires. After creating, check the entity has everything its
137
+ purpose needs — see the per-entity and wiring sections.
138
+ - To test a whole workflow end to end, \`start_workflow_run\` then read the result
139
+ (\`read_run\` / \`read_run_trace\` / \`read_run_cost\`). Note it runs the PUBLISHED
140
+ workflow and really executes (cost, connector side effects), so publish first,
141
+ and only test-run when a human is expecting it.
142
+
143
+ ## Delete is recoverable — but not everything is
144
+ - \`delete_*\` soft-deletes: the entity disappears from \`list_*\` but is not gone.
145
+ \`restore_*\` brings it back; \`list_deleted_*\` shows what's waiting. This
146
+ applies uniformly to workflow, agent, tool, skill, policy, reference_doc,
147
+ persona, output_schema, prompt_snippet, and flow.
148
+ - The same applies one level down, to version HISTORY:
149
+ \`delete_*_version\` removes one entry from history (the current draft and
150
+ published version are protected and can't be targeted this way);
151
+ \`list_deleted_*_versions\` / \`restore_deleted_*_version\` undo it. Deleted
152
+ version numbers stay reserved rather than reused, so gaps in the numbering
153
+ are normal, not a sign of corruption.
154
+ - \`restore_*\` can itself 409 if a live entity now holds the same name/slot —
155
+ the error names the conflicting one.
156
+ - There is no "archive" state for these ten entities — delete + restore IS the
157
+ lifecycle. Runs are the one exception with a true archive/unarchive (see below).
158
+
159
+ ## Per entity — what to create, and what "complete" means
160
+
161
+ Build in dependency order: a thing you will REFERENCE must exist before the
162
+ thing that references it. So: tools and output-schemas first, then agents (which
163
+ list tool ids), then workflows (whose steps name agents and tools), then
164
+ triggers (which make a workflow fire). Skills/policies/reference-docs can be
165
+ made any time before you attach them.
166
+
167
+ ### tool (\`create_tool\`, strict body)
168
+ - Required: \`name\`. Also: \`description\`, \`type\`, \`inputSchema\`,
169
+ \`outputSchema\`, \`implementation\`, \`authConfig\`, \`surfacing\`.
170
+ - \`type\`: \`"function"\` (default) | \`"connector"\` | \`"validator"\` |
171
+ \`"evaluator"\`. \`surfacing\`: \`"always"\` (in the agent's tool list) |
172
+ \`"on_demand"\`.
173
+ - \`inputSchema\` / \`outputSchema\` are JSON-Schema objects describing the tool's
174
+ params and result. Set them — an agent binds to a tool by its declared I/O; a
175
+ tool with no inputSchema is hard to call correctly.
176
+ - \`implementation\` is what makes the tool DO something, and its shape depends on
177
+ \`type\`:
178
+ - **function** — carries the Python. Author and check the code with
179
+ \`validate_tool_code\` and \`format_tool_code\`, and prove it runs with
180
+ \`execute_tool\`, BEFORE \`create_tool\`. A function tool whose
181
+ \`implementation\` is empty is an inert stub.
182
+ - **connector** — carries the HTTP call: typically \`connectorType\`
183
+ ("rest"/"graphql"), \`baseUrl\`, \`method\`, \`path\`, \`headers\`,
184
+ \`queryParams\`, \`body\`, \`responseMapping\`, \`pagination\`. Prefer the
185
+ \`create_connector\` tool, which sets \`type:"connector"\` for you. NEVER put
186
+ a real credential in \`authConfig\` — placeholders only ("{{ MY_SECRET }}"
187
+ or ""); a human fills the secret in Axonity. Test with
188
+ \`execute_stored_connector\` (uses the real, server-side-decrypted secret;
189
+ you see only the result).
190
+ - **validator / evaluator** — a constrained kind that wraps a builtin;
191
+ \`implementation\` names the builtin registry key plus its args. Look at the
192
+ tenant's existing validator/evaluator tools (\`list_tools\`) for the keys in
193
+ use rather than inventing one.
194
+ - Complete check: the tool has the I/O schemas its callers need AND a non-empty
195
+ implementation of the right shape for its type.
196
+
197
+ ### agent (\`create_agent\`, strict body)
198
+ - Required: \`name\`. Enumerated fields, with their ONLY valid values:
199
+ - \`capabilityTier\`: \`economy\` | \`standard\` (default) | \`smart\` | \`reasoning\`
200
+ - \`creativityTier\`: \`low\` | \`medium\` (default) | \`high\`
201
+ - \`learningMode\`: \`none\` (default) | \`adaptive\` | \`strict\`
202
+ - \`avatar\`, \`tags\` (role tags — see Field shape; set them or policies silently
203
+ skip the agent), \`canOwnProcess\` (bool; must be true for an agent to own a
204
+ workflow step's flow), \`episodicMemoryEnabled\` (bool).
205
+ - \`permissions\` (object): \`planning\`, \`delegation\`, \`verboseOutput\` (bools);
206
+ \`outputValidators\` / \`exposedValidatorTools\` (snake_case specs, see Field
207
+ shape); \`expectedOutputSchemaId\` (an output_schema id — MANDATORY whenever you
208
+ attach validators here).
209
+ - Wiring fields — see the Wiring section: \`toolIds\`, \`systemToolIds\`,
210
+ \`delegationTargetIds\`.
211
+ - Complete check: an agent with no \`toolIds\`/\`systemToolIds\` has no tools and
212
+ can only reason/talk. If it is meant to DO something, give it the tools.
213
+
214
+ ### workflow (\`create_workflow\`, then edit the document)
215
+ - \`create_workflow\` makes a STUB (name, description) with an empty document.
216
+ You then build the graph with either
217
+ - \`apply_workflow_mutations\` — a LIST of command mutations applied in order
218
+ (preferred: the backend validates each and threads the version), or
219
+ - \`replace_workflow_document\` — a full-document atomic PUT.
220
+ - The document is a graph: \`steps.all[]\` (each \`{ id, type, name, ... }\`) and
221
+ \`steps.edges[]\` (each \`{ id, from, to, type? }\`) plus \`triggers\`. Step
222
+ \`type\` is one of: \`manual\`, \`agent\`, \`automation\`, \`subprocess\`,
223
+ \`connector\`, \`decision\`, \`loop\`, \`for_each\`, \`end\`.
224
+ - Referential integrity is enforced: step and trigger ids must be unique, and
225
+ every edge \`from\`/\`to\` must reference an id that exists in the document
226
+ (\`from\` may be a trigger or step; \`to\` must be a step). A dangling edge is a
227
+ hard error.
228
+ - Complete check: run \`validate_workflow\` on the document — it returns
229
+ \`launchable\` plus an \`issues\` list. A workflow is not done until it is
230
+ launchable AND has a trigger (see Triggers).
231
+
232
+ ### persona
233
+ - An agent's character — 1:1 with an agent. Created only through its agent
234
+ (\`create_agent_persona\`: \`name\`, \`characterText\`); then a normal entity
235
+ (\`read_persona\`, \`update_persona\`, delete/restore/versions).
236
+
237
+ ### output_schema
238
+ - A reusable output contract, versioned and publishable. Referenced BY id from a
239
+ tool's validators or an agent's \`permissions.expectedOutputSchemaId\` — so
240
+ create it first, then point things at the id the create call returns.
241
+
242
+ ### skill / policy / reference_doc
243
+ - Memory entities attached to agents (and skills also to workflows). Create them,
244
+ then wire with the \`attach_*\` tools — see Wiring.
245
+
246
+ ### prompt_snippet
247
+ - Reusable prompt fragments; a normal entity. Wire-level oddity:
248
+ \`list_deleted_prompt_snippets\` returns the backend \`items\` envelope.
249
+
250
+ ### flow
251
+ - A reusable workflow fragment in the authored-entity lifecycle. \`create_flow\` /
252
+ \`update_flow\` write draft state; runtime uses \`read_flow_published\` until
253
+ approval. \`request_publish_flow\` to publish, \`discard_flow_draft\` to reset.
254
+
255
+ ### company
256
+ - The tenant's single company document (mission, value streams, org structure).
257
+ A SINGLETON — one per tenant, no id, so there is no list/create/delete:
258
+ \`read_company\`, \`update_company\` (a WHOLE-document save with
259
+ \`expectedVersion\`, like \`replace_workflow_document\`), \`list_company_versions\`,
260
+ \`read_company_version\`, \`restore_company_version\`, \`read_company_published\`.
261
+ Publish it like anything else with \`request_publish_company\` — but because it
262
+ is a singleton this takes NO id (the server resolves your tenant's one
263
+ company). Direct company publish is closed to machine tokens, so the approval
264
+ queue is the only path.
265
+
266
+ ## Wiring — how the pieces connect
267
+ There are THREE mechanisms, and using the wrong one silently no-ops. Know which
268
+ each link uses.
269
+
270
+ **A) Set a field on the entity (via create/update)** — an id or id-array that
271
+ lives in the entity body:
272
+ - tool → agent: add the tool's id to the agent's \`toolIds\`. This is how an
273
+ agent gets a (non-system) tool. There is no attach_tool_to_agent route.
274
+ - system tool → agent: add the catalog id to \`systemToolIds\`. Get ids from
275
+ \`list_system_tools\`. No grant/revoke tool — you set the array via
276
+ \`update_agent\`. \`toolIds\` and \`systemToolIds\` are DIFFERENT lists; a
277
+ system-tool id does not go in \`toolIds\`.
278
+ - agent → agent (delegation): add the callee agent's id to the caller's
279
+ \`delegationTargetIds\` (and set \`permissions.delegation: true\`).
280
+ - output_schema → agent: \`permissions.expectedOutputSchemaId\` (a single id).
281
+ - Changing any of these is read-then-write under optimistic locking: read the
282
+ agent, edit the field — an id-array is a FULL replace, so include the ids you
283
+ are keeping — then \`update_agent\` with \`expectedVersion\`.
284
+
285
+ **B) Call an attach route (a link, not a field).** \`attach_*\`/\`detach_*\` POST/
286
+ DELETE a link and do NOT touch the entity body:
287
+ - skill → agent: \`attach_skill_to_agent\`; skill → workflow:
288
+ \`attach_skill_to_workflow\`.
289
+ - policy → agent: \`attach_policy_to_agent\`.
290
+ - reference_doc → agent: \`attach_reference_to_agent\` (agents only — there is no
291
+ workflow-scoped reference-doc route).
292
+ - VERIFY every one of these with the read-back before \`request_publish_*\`:
293
+ \`list_agent_skills\`, \`list_agent_policies\`, \`list_agent_reference_docs\`.
294
+ This is not optional politeness — because a link lives OUTSIDE the entity body,
295
+ \`read_agent\` will not show it, so the read-back is the only way to tell an
296
+ attach that landed from one that silently did nothing. (Mechanism A is
297
+ different: those ids ARE in the body, so re-reading the agent proves them.
298
+ \`attach_skill_to_workflow\` has no read-back — the backend has no list route
299
+ for it.)
300
+
301
+ **C) Reference an id INSIDE the workflow document** (this is how agents and tools
302
+ get "into" a workflow — there is no attach route for it):
303
+ - agent → workflow: an \`agent\` step names its agent in the step's
304
+ \`contract.owners[]\` as \`{ "type": "agent", "id": "<agentId>" }\`.
305
+ - tool → workflow: on an \`agent\` step, list tool ids under
306
+ \`contract.tools.toolIds[]\` (and/or per plan-step \`contract.activities[]\`
307
+ entries of \`{ "kind": "tool", "toolId": "<id>" }\`). On an \`automation\` step,
308
+ set \`config.automationType: "tool"\` and \`config.toolId\`. A \`connector\` step
309
+ references a connector tool the same way.
310
+ - Every id you place in a document must be a REAL id in THIS tenant. The workflow
311
+ validator flags a step whose owner agent or referenced tool no longer exists —
312
+ \`validate_workflow\` is how you catch a bad reference before publishing.
313
+ - Prefer \`apply_workflow_mutations\` (e.g. \`add_step\`, \`update_step\`,
314
+ \`add_edge\`) over hand-building this JSON: the backend fills defaults and
315
+ validates each edit. Read the returned document to see the exact shape it
316
+ produced, then adjust.
317
+
318
+ ## Prompt elements & placement (Memory V2)
319
+ A prompt snippet is a LIBRARY item — creating it changes nothing on its own. It
320
+ only shapes a run once it is PLACED into a flow step's prompt stack. Placement is
321
+ per flow step, in one of two channels, at an order:
322
+ - \`read_workflow_prompt_stacks(workflowId)\` (or \`read_flow_prompt_stacks(flowId)\`)
323
+ resolves a workflow/flow to its steps and each step's system/user stacks — this
324
+ is how you DISCOVER the \`flowStepId\`s you place against. Start here.
325
+ - \`attach_prompt_snippet_to_flow_step(flowStepId, snippetId, target, displayOrder?)\`
326
+ — \`target\` is \`"system"\` (instructions the model is steered by) or \`"user"\`
327
+ (content presented as the user turn).
328
+ - \`list_flow_step_prompts\` shows a step's current system/user stacks (with each
329
+ attachment's \`linkId\`); \`update_flow_step_prompt(linkId, …)\` moves/reorders one;
330
+ \`reorder_flow_step_prompts(flowStepId, snippetIds)\` sets the whole order;
331
+ \`detach_prompt_snippet_from_flow_step(linkId)\` unlinks (the snippet survives).
332
+ - A WILDCARD snippet applies to EVERY step (top of every stack) — use it for
333
+ cross-cutting instructions instead of attaching the same snippet everywhere.
334
+ \`list_wildcard_prompts\` shows them.
335
+
336
+ Where each kind of instruction belongs — the decision map:
337
+ - reusable voice/character for one agent → a **persona** (1:1 with the agent), or a
338
+ reusable **snippet** if it is shared prompt text.
339
+ - a rule that must hold everywhere → a **wildcard** snippet, or a **policy** if it
340
+ is a guardrail (policies are governance; snippets are prompt text).
341
+ - a step-specific instruction → a flow-step **\`system\`** prompt.
342
+ - user-turn scaffolding for a step → a flow-step **\`user\`** prompt.
343
+ - background knowledge the agent reads → a **reference doc** (attach to the agent).
344
+ - a capability the agent uses → a **tool** (\`agent.toolIds\`) or **skill** (attach).
345
+ - long-term recall for an agent → the agent's **\`episodicMemoryEnabled\`** flag
346
+ (Memory V2, opt-in). Session/workflow memory are RUNTIME, not authored: they are
347
+ written by a run, never set here. This connector does not expose them — the
348
+ backend serves them per run, but no tool wraps those reads yet, so do not
349
+ promise a user you can show them.
350
+
351
+ ## Reproducing a setup (recreate, never copy ids)
352
+ To rebuild an agent/workflow/tool graph as NEW entities — in this tenant, or in
353
+ another tenant by pointing the connector at THAT tenant's token in a separate
354
+ session — author it fresh and wire by the NEW ids. An id from a read is
355
+ meaningful only in the tenant it came from; sending it back in a create/update
356
+ elsewhere points at nothing. Do this instead:
357
+ 1. Read the source graph (in the session pointed at it) for its SHAPE: names,
358
+ field values, which tools each agent lists, which agents/tools each workflow
359
+ step references. For each source agent also read its LINKS —
360
+ \`list_agent_skills\`, \`list_agent_policies\`, \`list_agent_reference_docs\` —
361
+ they are not in the agent body, so a plain \`read_agent\` misses them and you
362
+ would rebuild an agent that quietly lost its skills and guardrails.
363
+ 2. Create the leaf dependencies first (tools, output_schemas). Keep a map from
364
+ each OLD id to the NEW id the create call returns.
365
+ 3. Create agents, translating every referenced id through your map:
366
+ old toolId → new toolId in \`toolIds\`, etc. Never send an old id. If the
367
+ source agent has a persona, recreate it with \`create_agent_persona\` on the
368
+ new agent.
369
+ 4. Create workflows; when you add agent/tool references into the document,
370
+ translate through the map the same way.
371
+ 5. Attach skills/policies/reference-docs by the new ids, then read them back
372
+ (\`list_agent_*\`) and diff against what you read in step 1.
373
+ 6. \`validate_workflow\` and re-read each entity to confirm every reference
374
+ resolved, then \`request_publish_*\`.
375
+ The connector never carries a secret across: \`authConfig\` stays placeholders in
376
+ the new tenant too, and a human fills the real value there.
377
+
378
+ ## Structural workflow edits
379
+ - \`apply_workflow_mutations\` takes a LIST of commands and applies them in order,
380
+ threading the version for you — pass the version you read, not one per command.
381
+ - It is NOT transactional. If command N fails, the ones before it stay applied;
382
+ the error tells you how many landed and which index failed. Re-read and resume
383
+ from that index rather than replaying the whole list.
384
+
385
+ ## Triggers
386
+ - A published workflow still does nothing until it has a trigger. Add one with
387
+ \`create_cron_schedule\`, \`create_webhook_trigger\`, or
388
+ \`create_conditional_trigger\`.
389
+ - Trigger deletes are HARD deletes — no restore. Webhook tokens are shown once
390
+ at create/rotate and are never retrievable; hand them straight to your human
391
+ and never store one in an entity field.
392
+
393
+ ## Evaluating what you built
394
+ - There is no findings endpoint and no evaluator entity. To judge a run, read it:
395
+ \`read_run\` (its \`validatorVerdicts\` and \`agentInvocations\`) and
396
+ \`read_run_trace\` (the step-by-step tool calls).
397
+ - Runs are the only thing with a real archive state — \`archive_run\` is
398
+ reversible, \`bulk_delete_runs\` is not.
399
+
400
+ ## Secrets
401
+ - Never handle a real credential. A connector's \`authConfig\` takes placeholders
402
+ only ("{{ MY_SECRET }}" or ""); a human fills the real value in Axonity. This
403
+ is enforced — a write carrying something that looks like a real secret is
404
+ rejected before it leaves this connector.
43
405
 
44
406
  ## Tenant
45
407
  - Your token fixes the tenant. You cannot act across tenants; never send a
46
408
  tenant id in a body.
47
409
  `;
48
410
  export function registerConventions(server) {
49
- server.tool("axonity_conventions", "Read the authoring conventions (drafts vs live, optimistic locking, field " +
50
- "shapes per entity). Call this before creating or updating entities.", {}, async () => ({ content: [{ type: "text", text: CONVENTIONS }] }));
411
+ server.tool("axonity_conventions", "Read the authoring conventions BEFORE creating or updating anything: the " +
412
+ "draft→publish lifecycle, optimistic locking, per-entity create contracts " +
413
+ "(required fields, valid enum values, what 'complete' means), how to WIRE " +
414
+ "tools→agents, agents/tools→workflows and delegation, and how to reproduce " +
415
+ "a setup by creating new entities and remapping ids (never copy an id " +
416
+ "across tenants).", {}, async () => ({ content: [{ type: "text", text: CONVENTIONS }] }));
51
417
  }
52
418
  //# sourceMappingURL=conventions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conventions.js","sourceRoot":"","sources":["../../src/tools/conventions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCnB,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,4EAA4E;QAC1E,qEAAqE,EACvE,EAAE,EACF,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAC1E,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"conventions.js","sourceRoot":"","sources":["../../src/tools/conventions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyYnB,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,MAAiB;IACnD,MAAM,CAAC,IAAI,CACT,qBAAqB,EACrB,2EAA2E;QACzE,2EAA2E;QAC3E,2EAA2E;QAC3E,4EAA4E;QAC5E,uEAAuE;QACvE,kBAAkB,EACpB,EAAE,EACF,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC,CAC1E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The connector credential guard.
3
+ *
4
+ * A connector's `authConfig` must carry PLACEHOLDERS only — a human fills the
5
+ * real secret in Axonity, and the value never passes through an agent. This
6
+ * module enforces that on every path that can write a connector.
7
+ *
8
+ * Two independent defences, mirroring the backend's `secret_scrub` module:
9
+ *
10
+ * 1. **Structural** — credential-ish leaves (`clientSecret`, `apiKey`, …) must
11
+ * be a placeholder. Applied only to keys that actually name a credential, so
12
+ * legitimate neighbours (`authType: "bearer"`, `tokenUrl: "https://…"`)
13
+ * are left alone. The earlier guard required EVERY value to be a placeholder,
14
+ * which rejected correct connectors while missing nested ones entirely.
15
+ * 2. **Shape scan** — every string leaf, at any depth, is swept for known secret
16
+ * formats, catching a credential parked in a field nobody thought to name.
17
+ *
18
+ * Findings name WHERE and WHAT KIND, never the matched value — an error message
19
+ * is not a safe place to echo a secret.
20
+ */
21
+ /** Empty, or a `{{ … }}` template the human replaces in Axonity. */
22
+ export declare function isPlaceholder(value: unknown): boolean;
23
+ /**
24
+ * Walk `value` depth-first and collect every violation as `path: reason`.
25
+ * Exported for testing; `assertPlaceholderCredentials` is the enforcement point.
26
+ */
27
+ export declare function findCredentialViolations(value: unknown, path?: string): string[];
28
+ /**
29
+ * Throw if a connector's fields carry anything that looks like a real
30
+ * credential. Safe to call with any tool's fields — it is a no-op when there is
31
+ * no `authConfig`, which is what makes it cheap to apply to `create_tool` and
32
+ * `update_tool` as well as the connector-specific verbs.
33
+ */
34
+ export declare function assertPlaceholderCredentials(fields: Record<string, unknown>): void;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The connector credential guard.
3
+ *
4
+ * A connector's `authConfig` must carry PLACEHOLDERS only — a human fills the
5
+ * real secret in Axonity, and the value never passes through an agent. This
6
+ * module enforces that on every path that can write a connector.
7
+ *
8
+ * Two independent defences, mirroring the backend's `secret_scrub` module:
9
+ *
10
+ * 1. **Structural** — credential-ish leaves (`clientSecret`, `apiKey`, …) must
11
+ * be a placeholder. Applied only to keys that actually name a credential, so
12
+ * legitimate neighbours (`authType: "bearer"`, `tokenUrl: "https://…"`)
13
+ * are left alone. The earlier guard required EVERY value to be a placeholder,
14
+ * which rejected correct connectors while missing nested ones entirely.
15
+ * 2. **Shape scan** — every string leaf, at any depth, is swept for known secret
16
+ * formats, catching a credential parked in a field nobody thought to name.
17
+ *
18
+ * Findings name WHERE and WHAT KIND, never the matched value — an error message
19
+ * is not a safe place to echo a secret.
20
+ */
21
+ /** Keys whose value is a credential. Matched case- and separator-insensitively. */
22
+ const CREDENTIAL_KEY = /(secret|password|passphrase|token|credential|apikey|privatekey|signingkey|authorization|clientkey)/;
23
+ /**
24
+ * Suffixes that make a credential-ish key a LOCATOR rather than the secret
25
+ * itself — `tokenUrl` is an OAuth endpoint, `apiKeyName` is a header name.
26
+ * Without this, correct configs are rejected, which is what pushes an agent to
27
+ * work around the guard. The shape scan still covers these fields, so a real
28
+ * credential parked in one is caught anyway.
29
+ */
30
+ const LOCATOR_SUFFIX = /(url|uri|endpoint|name|type|id|path|method|location|scope|expiresin|ttl)$/;
31
+ /** Known secret shapes, mirroring the backend's `_SECRET_PATTERNS`. */
32
+ const SECRET_PATTERNS = [
33
+ ["private key block", /-----BEGIN [A-Z ]*PRIVATE KEY-----/],
34
+ ["aws access key id", /\bAKIA[0-9A-Z]{16}\b/],
35
+ ["github token", /\bgh[pousr]_[A-Za-z0-9]{36,}\b/],
36
+ ["slack token", /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/],
37
+ ["google api key", /\bAIza[0-9A-Za-z_-]{35}\b/],
38
+ ["stripe secret key", /\bsk_(?:live|test)_[A-Za-z0-9]{16,}\b/],
39
+ ["jwt", /\beyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}\b/],
40
+ ["credentials in url", /:\/\/[^/\s:@]+:[^/\s:@]+@/],
41
+ ];
42
+ /** Empty, or a `{{ … }}` template the human replaces in Axonity. */
43
+ export function isPlaceholder(value) {
44
+ if (value === "" || value === null || value === undefined)
45
+ return true;
46
+ return typeof value === "string" && /^\s*\{\{.*\}\}\s*$/.test(value);
47
+ }
48
+ function isCredentialKey(key) {
49
+ const normalized = key.replace(/[_\-\s]/g, "").toLowerCase();
50
+ if (LOCATOR_SUFFIX.test(normalized))
51
+ return false;
52
+ return CREDENTIAL_KEY.test(normalized);
53
+ }
54
+ /**
55
+ * Walk `value` depth-first and collect every violation as `path: reason`.
56
+ * Exported for testing; `assertPlaceholderCredentials` is the enforcement point.
57
+ */
58
+ export function findCredentialViolations(value, path = "authConfig") {
59
+ const findings = [];
60
+ const walk = (node, at, keyIsCredential) => {
61
+ if (Array.isArray(node)) {
62
+ node.forEach((item, i) => walk(item, `${at}[${i}]`, keyIsCredential));
63
+ return;
64
+ }
65
+ if (node !== null && typeof node === "object") {
66
+ for (const [key, child] of Object.entries(node)) {
67
+ walk(child, `${at}.${key}`, isCredentialKey(key));
68
+ }
69
+ return;
70
+ }
71
+ if (typeof node === "string") {
72
+ for (const [label, pattern] of SECRET_PATTERNS) {
73
+ if (pattern.test(node)) {
74
+ findings.push(`${at}: looks like a real ${label}`);
75
+ return;
76
+ }
77
+ }
78
+ }
79
+ // A credential-named leaf must be a placeholder whatever its type.
80
+ if (keyIsCredential && !isPlaceholder(node)) {
81
+ findings.push(`${at}: must be a placeholder, not a real value`);
82
+ }
83
+ };
84
+ walk(value, path, false);
85
+ return findings;
86
+ }
87
+ /**
88
+ * Throw if a connector's fields carry anything that looks like a real
89
+ * credential. Safe to call with any tool's fields — it is a no-op when there is
90
+ * no `authConfig`, which is what makes it cheap to apply to `create_tool` and
91
+ * `update_tool` as well as the connector-specific verbs.
92
+ */
93
+ export function assertPlaceholderCredentials(fields) {
94
+ const authConfig = fields.authConfig;
95
+ if (authConfig === undefined || authConfig === null)
96
+ return;
97
+ const findings = findCredentialViolations(authConfig);
98
+ if (findings.length === 0)
99
+ return;
100
+ throw new Error("authConfig must contain placeholders only — a human fills real secrets in " +
101
+ "the Axonity tool editor, and a credential must never pass through an " +
102
+ `agent. Use "{{ MY_SECRET }}" or "" instead.\n\n${findings
103
+ .map((f) => ` - ${f}`)
104
+ .join("\n")}`);
105
+ }
106
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/tools/credentials.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,23 @@
1
1
  /**
2
- * Secondary MCP tools (epic #652 C5): personas (agent-scoped), connectors
3
- * (a tool subtype), and attaching memory to a target.
2
+ * Secondary MCP tools: the agent-scoped persona create/read (personas
3
+ * themselves are a full generic entity — see index.ts — but creation and the
4
+ * by-agent read have no equivalent generic route), connectors (a tool
5
+ * subtype), attaching memory to a target, and a few standalone one-offs.
4
6
  *
5
7
  * These use routes with shapes that don't fit the generic entity registrar:
6
- * personas are 1:1 with an agent (no standalone list), connectors are a tool
7
- * with `type: "connector"` and MUST NOT carry real credentials, and attach is a
8
- * path-only link.
8
+ * a persona is created only through its agent, connectors are a tool with
9
+ * `type: "connector"` and MUST NOT carry real credentials, and attach/detach
10
+ * is a path-only link.
9
11
  */
10
12
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
13
  import type { AxonityClient } from "../client.js";
12
14
  export declare function registerPersonaTools(server: McpServer, client: AxonityClient): void;
13
15
  export declare function registerConnectorTools(server: McpServer, client: AxonityClient): void;
14
16
  export declare function registerAttachTools(server: McpServer, client: AxonityClient): void;
17
+ /**
18
+ * Small standalone tools that don't fit any of the other groupings: the
19
+ * system-tools catalog (read-only — there is no grant/revoke route; enabling
20
+ * one for an agent means writing `systemToolIds` via `update_agent`), and
21
+ * cloning a flow/prompt-snippet into a tenant-owned copy.
22
+ */
23
+ export declare function registerCatalogTools(server: McpServer, client: AxonityClient): void;