callman-mcp 0.10.0 → 0.10.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/CHANGELOG.md +15 -0
- package/README.md +1 -0
- package/dist/client/api.d.ts +8 -1
- package/dist/client/api.d.ts.map +1 -1
- package/dist/client/api.js +4 -0
- package/dist/client/api.js.map +1 -1
- package/dist/client/types.d.ts +17 -1
- package/dist/client/types.d.ts.map +1 -1
- package/dist/domain/requestShape.d.ts +28 -2
- package/dist/domain/requestShape.d.ts.map +1 -1
- package/dist/domain/requestShape.js +7 -0
- package/dist/domain/requestShape.js.map +1 -1
- package/dist/resources/docs/overview.d.ts +1 -1
- package/dist/resources/docs/overview.d.ts.map +1 -1
- package/dist/resources/docs/overview.js +3 -1
- package/dist/resources/docs/overview.js.map +1 -1
- package/dist/resources/docs/requestSchema.d.ts +1 -1
- package/dist/resources/docs/requestSchema.d.ts.map +1 -1
- package/dist/resources/docs/requestSchema.js +3 -0
- package/dist/resources/docs/requestSchema.js.map +1 -1
- package/dist/resources/generated/aiPacks.d.ts +1 -1
- package/dist/resources/generated/aiPacks.js +2 -2
- package/dist/run/loadBundle.d.ts.map +1 -1
- package/dist/run/loadBundle.js +17 -3
- package/dist/run/loadBundle.js.map +1 -1
- package/dist/tools/catalog.d.ts.map +1 -1
- package/dist/tools/catalog.js +1 -0
- package/dist/tools/catalog.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/knowledge.d.ts +4 -0
- package/dist/tools/knowledge.d.ts.map +1 -0
- package/dist/tools/knowledge.js +44 -0
- package/dist/tools/knowledge.js.map +1 -0
- package/dist-cjs/client/api.js +4 -0
- package/dist-cjs/domain/requestShape.js +7 -0
- package/dist-cjs/resources/docs/overview.js +3 -1
- package/dist-cjs/resources/docs/requestSchema.js +3 -0
- package/dist-cjs/resources/generated/aiPacks.js +2 -2
- package/dist-cjs/run/loadBundle.js +17 -3
- package/dist-cjs/tools/catalog.js +1 -0
- package/dist-cjs/tools/index.js +2 -0
- package/dist-cjs/tools/knowledge.js +47 -0
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../../src/tools/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAUjD,eAAO,MAAM,sBAAsB,GAAI,QAAQ,SAAS,EAAE,KAAK,WAAW,KAAG,IAuC5E,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { guarded, ok, READ } from "./shared.js";
|
|
3
|
+
// search_knowledge — the organisation's own material an administrator set up
|
|
4
|
+
// in Callman (admin panel → AI Knowledge): API definitions, existing
|
|
5
|
+
// collections and their tests, conventions and known defects, scoped to the
|
|
6
|
+
// token owner's tribe and squad. A model should read it before writing
|
|
7
|
+
// requests, tests or scenarios, so what it writes follows the organisation's
|
|
8
|
+
// conventions and the real API shapes instead of generic guesses.
|
|
9
|
+
export const registerKnowledgeTools = (server, ctx) => {
|
|
10
|
+
server.registerTool("search_knowledge", {
|
|
11
|
+
title: "Search the organisation's knowledge",
|
|
12
|
+
description: "Search the reference material your Callman administrator set up for AI work (AI Knowledge): OpenAPI definitions of the organisation's services, existing collections (requests, contract checks, tests), conventions — naming, priorities, review rules, which are BINDING — and known defect patterns. Results are limited to sources for everyone and for your own groups. Call it before writing requests, tests or scenarios, and give `method` + `url` when you work on a specific endpoint to get its definition and existing tests first. Empty when nothing is set up or the AI Knowledge feature is off.",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
query: z.string().min(1).max(4_000).describe("What you are about to do or look up, in plain words."),
|
|
15
|
+
method: z.string().max(10).optional().describe("HTTP method of the endpoint you work on."),
|
|
16
|
+
url: z.string().max(2_000).optional().describe("URL or path of the endpoint you work on."),
|
|
17
|
+
maxChars: z.number().int().min(500).max(20_000).default(8_000).describe("Size budget of the result."),
|
|
18
|
+
},
|
|
19
|
+
annotations: READ,
|
|
20
|
+
}, guarded(async ({ query, method, url, maxChars }) => {
|
|
21
|
+
const result = await ctx.api.searchKnowledge({
|
|
22
|
+
feature: "mcp",
|
|
23
|
+
query,
|
|
24
|
+
method: method ?? null,
|
|
25
|
+
url: url ?? null,
|
|
26
|
+
budgetChars: maxChars,
|
|
27
|
+
});
|
|
28
|
+
const items = result.snippets.map((snippet) => ({
|
|
29
|
+
source: snippet.sourceName,
|
|
30
|
+
kind: snippet.kind,
|
|
31
|
+
title: snippet.title,
|
|
32
|
+
text: snippet.text,
|
|
33
|
+
why: snippet.reason === "endpoint" ? "same endpoint" : snippet.reason === "always" ? "always included (binding)" : "relevant",
|
|
34
|
+
}));
|
|
35
|
+
return ok({
|
|
36
|
+
sources: result.sources.map((source) => ({ name: source.name, kind: source.kind })),
|
|
37
|
+
items,
|
|
38
|
+
...(items.length === 0
|
|
39
|
+
? { note: "Nothing matched: no organisation knowledge applies to this request (or none is set up)." }
|
|
40
|
+
: { rule: "Conventions are binding; prefer these API definitions and tests over assumptions." }),
|
|
41
|
+
});
|
|
42
|
+
}));
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=knowledge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/tools/knowledge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEhD,6EAA6E;AAC7E,qEAAqE;AACrE,4EAA4E;AAC5E,uEAAuE;AACvE,6EAA6E;AAC7E,kEAAkE;AAElE,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,MAAiB,EAAE,GAAgB,EAAQ,EAAE;IAClF,MAAM,CAAC,YAAY,CACjB,kBAAkB,EAClB;QACE,KAAK,EAAE,qCAAqC;QAC5C,WAAW,EACT,mlBAAmlB;QACrlB,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,sDAAsD,CAAC;YACpG,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YAC1F,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,0CAA0C,CAAC;YAC1F,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,4BAA4B,CAAC;SACtG;QACD,WAAW,EAAE,IAAI;KAClB,EACD,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE;QACjD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC;YAC3C,OAAO,EAAE,KAAK;YACd,KAAK;YACL,MAAM,EAAE,MAAM,IAAI,IAAI;YACtB,GAAG,EAAE,GAAG,IAAI,IAAI;YAChB,WAAW,EAAE,QAAQ;SACtB,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAC9C,MAAM,EAAE,OAAO,CAAC,UAAU;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,OAAO,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,UAAU;SAC9H,CAAC,CAAC,CAAC;QACJ,OAAO,EAAE,CAAC;YACR,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACnF,KAAK;YACL,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;gBACpB,CAAC,CAAC,EAAE,IAAI,EAAE,yFAAyF,EAAE;gBACrG,CAAC,CAAC,EAAE,IAAI,EAAE,mFAAmF,EAAE,CAAC;SACnG,CAAC,CAAC;IACL,CAAC,CAAC,CACH,CAAC;AACJ,CAAC,CAAC"}
|
package/dist-cjs/client/api.js
CHANGED
|
@@ -223,6 +223,10 @@ class CallmanApi {
|
|
|
223
223
|
return this.http.request("GET", `/scenarios/${id}/reports/${reportId}`, { workspaceId: ws });
|
|
224
224
|
}
|
|
225
225
|
// ── diagrams (user-owned, not workspace-scoped) ─────────────────────
|
|
226
|
+
// AI Knowledge (organisation reference material), scoped to the token owner.
|
|
227
|
+
searchKnowledge(body) {
|
|
228
|
+
return this.http.request("POST", "/ai/grounding", { body });
|
|
229
|
+
}
|
|
226
230
|
listDiagrams() {
|
|
227
231
|
return this.http.request("GET", "/diagrams");
|
|
228
232
|
}
|
|
@@ -64,6 +64,9 @@ exports.bodyInputSchema = zod_1.z
|
|
|
64
64
|
const secret = (what) => zod_1.z.string().max(10_000).describe(`${what}. {{variable}} references are fine`);
|
|
65
65
|
exports.authInputSchema = zod_1.z.discriminatedUnion("type", [
|
|
66
66
|
(0, strict_js_1.strictObject)({ type: zod_1.z.literal("none") }, "auth field"),
|
|
67
|
+
// Use the collection's auth (set on the collection in the app); falls back
|
|
68
|
+
// to no auth when the collection has none.
|
|
69
|
+
(0, strict_js_1.strictObject)({ type: zod_1.z.literal("inherit") }, "inherit auth field"),
|
|
67
70
|
(0, strict_js_1.strictObject)({ type: zod_1.z.literal("bearer"), token: secret("Bearer token") }, "bearer auth field"),
|
|
68
71
|
(0, strict_js_1.strictObject)({ type: zod_1.z.literal("basic"), username: zod_1.z.string().max(5000), password: zod_1.z.string().max(5000).default("") }, "basic auth field"),
|
|
69
72
|
(0, strict_js_1.strictObject)({
|
|
@@ -227,6 +230,8 @@ const toAuthPayload = (auth) => {
|
|
|
227
230
|
if (!auth)
|
|
228
231
|
return { ...EMPTY_AUTH };
|
|
229
232
|
switch (auth.type) {
|
|
233
|
+
case "inherit":
|
|
234
|
+
return { ...EMPTY_AUTH, type: "inherit" };
|
|
230
235
|
case "bearer":
|
|
231
236
|
return { ...EMPTY_AUTH, type: "bearer", bearerToken: auth.token };
|
|
232
237
|
case "basic":
|
|
@@ -247,6 +252,8 @@ exports.toAuthPayload = toAuthPayload;
|
|
|
247
252
|
const authInputView = (auth, reveal = false) => {
|
|
248
253
|
const hide = (value) => (value ? (reveal ? value : (0, mask_js_1.maskSecret)(value)) : "");
|
|
249
254
|
switch (auth?.type) {
|
|
255
|
+
case "inherit":
|
|
256
|
+
return { type: "inherit" };
|
|
250
257
|
case "bearer":
|
|
251
258
|
return { type: "bearer", token: hide(auth.bearerToken) };
|
|
252
259
|
case "basic":
|
|
@@ -12,7 +12,9 @@ whose token is configured, limited to that token's permissions and the user's wo
|
|
|
12
12
|
1. \`whoami\` — proves the connection and tells you the workspaces, features and which tools
|
|
13
13
|
this token can use.
|
|
14
14
|
2. Look before you create: \`list_collections\` / \`get_collection_tree\` / \`search_requests\`.
|
|
15
|
-
Creating a collection whose name exists is refused on purpose.
|
|
15
|
+
Creating a collection whose name exists is refused on purpose. Before writing requests,
|
|
16
|
+
tests or scenarios, \`search_knowledge\` returns the organisation's own API definitions,
|
|
17
|
+
conventions (binding) and known defects, when an administrator set them up.
|
|
16
18
|
3. Arguments are strict: a misspelled or unknown argument is an error that lists the valid
|
|
17
19
|
ones — read it and retry; nothing is silently ignored.
|
|
18
20
|
4. Names work as references everywhere an id does (collection, folder, request, environment,
|
|
@@ -56,6 +56,7 @@ body as \`bodyPreview\` (with \`body: null\`) unless \`full: true\` — never wr
|
|
|
56
56
|
## Auth
|
|
57
57
|
\`\`\`jsonc
|
|
58
58
|
{ "type": "none" }
|
|
59
|
+
{ "type": "inherit" } // the collection's auth (Inherited)
|
|
59
60
|
{ "type": "bearer", "token": "{{accessToken}}" }
|
|
60
61
|
{ "type": "basic", "username": "{{user}}", "password": "{{pass}}" }
|
|
61
62
|
{ "type": "apiKey", "key": "X-API-Key", "value": "{{apiKey}}", "location": "header" } // or "query"
|
|
@@ -66,6 +67,8 @@ body as \`bodyPreview\` (with \`body: null\`) unless \`full: true\` — never wr
|
|
|
66
67
|
"username": "", "password": "", "refreshToken": "" } // password / refresh_token grants
|
|
67
68
|
\`\`\`
|
|
68
69
|
Prefer \`{{variables}}\` over literal secrets — the environment keeps them out of the request.
|
|
70
|
+
\`inherit\` sends the collection's own auth (set on the collection in the app); a collection
|
|
71
|
+
without auth makes it send none. Runs (desktop, callme, run_collection, run_load_test) resolve it.
|
|
69
72
|
|
|
70
73
|
## Masked secrets
|
|
71
74
|
get_request masks auth secrets and sensitive headers (Authorization, Cookie, X-API-Key …) as
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AI_PACKS = exports.AI_PACKS_CORE_VERSION = void 0;
|
|
4
|
-
// GENERATED by scripts/build-static-resources.mjs from callman-core@1.
|
|
5
|
-
exports.AI_PACKS_CORE_VERSION = "1.
|
|
4
|
+
// GENERATED by scripts/build-static-resources.mjs from callman-core@1.42.0 ai-packs — do not edit.
|
|
5
|
+
exports.AI_PACKS_CORE_VERSION = "1.42.0";
|
|
6
6
|
exports.AI_PACKS = {
|
|
7
7
|
"db-queries": "<!-- GENERATED FILE — do not edit by hand. Source: callman_core (npm run ai:packs). -->\n\n# Callman data access from scripts (`pm.db.query` / `pm.redis.command`)\n\n`pm.db.query({ connectionId, query })` — ALWAYS `await`. `query` is coerced to a string, `{{tokens}}` are resolved, then dispatched by the connection's type. `connectionId` may be omitted to use the request's configured DB connection. IMPORTANT: `pm.db.query` does NOT accept a `params`/bind array — inline values (quote strings) or use `{{env.X}}` tokens; SQL placeholders like `$1` or `?` are NOT bound.\n\n## MongoDB\n`query` MUST be a JSON STRING of a command object (use `JSON.stringify`), NOT a `db.coll.find(...)` shell string. The match key is `filter` (a top-level `query` key is rejected).\n\n```js\nconst body = pm.response.json();\nconst res = await pm.db.query({\n connectionId: \"…\",\n query: JSON.stringify({\n collection: \"users\",\n operation: \"findOne\", // find | findOne | aggregate | countDocuments | insertOne | insertMany | updateOne | updateMany | deleteOne | deleteMany | findOneAndUpdate | findOneAndReplace | findOneAndDelete\n filter: { email: body.data.user.email },\n }),\n});\npm.expect(res.rowCount).to.be.above(0); // existence check\n```\n\nPer-operation fields: `find`/`findOne` use `filter` (+ optional `projection`,`sort`,`limit`,`skip`); `aggregate` uses `pipeline` (array); `insertOne` uses `document`, `insertMany` uses `documents`; `updateOne`/`updateMany`/`findOneAndUpdate` use `filter`+`update` (Mongo update operators, e.g. `{ $set: { … } }`); `deleteOne`/`deleteMany` use `filter`; `findOneAndUpdate`/`findOneAndReplace` accept `returnDocument: \"before\"|\"after\"`. The command text is MongoDB Extended JSON (relaxed): `{ \"$oid\": \"…\" }`, `{ \"$date\": \"2026-01-01T00:00:00Z\" }`, `{ \"$numberDecimal\": \"9.99\" }` and `{ \"$numberLong\": \"…\" }` become real BSON values anywhere in the command; a 24-hex string in a filter is also coerced to ObjectId. Rows are in `res.rows`; write ops surface counts in `res.rowCount`.\n\n## PostgreSQL / MySQL / Oracle (SQL)\n`query` is plain SQL text. Because `pm.db.query` binds no params, inline the value and quote strings yourself (or use a `{{token}}`):\n\n```js\nconst email = pm.response.json().data.user.email;\nconst res = await pm.db.query({\n connectionId: \"…\",\n query: `SELECT id FROM users WHERE email = '${email}'`,\n});\npm.expect(res.rowCount).to.be.above(0);\n```\n\nNotes: a trailing `;` is stripped (except Oracle PL/SQL blocks, which keep it). **Oracle** returns column names UPPERCASE — read `res.rows[0].EMAIL`, not `.email`. `res.rowCount` is the row count for SELECT and the affected-row count for INSERT/UPDATE/DELETE.\n\n## SQL Server (mssql)\nSingle statement per query; a trailing `;` is stripped; `GO` batch separators are REJECTED (client-tool syntax, not T-SQL). Positional params bind as named inputs: `params[0]` → `@p1`, `params[1]` → `@p2`… (scenario db node only — `pm.db.query` has no params).\n\n```sql\nSELECT TOP 1 id, amount FROM dbo.orders WHERE customer_id = @p1 ORDER BY created_at DESC\n```\n\n## Redis (`pm.redis.command`)\n`command` is a single string. Supported commands: **GET, SET, DEL, EXISTS, TTL, HGET, HSET, HGETALL, HDEL, LPUSH, RPUSH, LRANGE, LLEN, SADD, SMEMBERS, SISMEMBER, INCR, DECR, INCRBY, EXPIRE, PERSIST, TYPE, ZADD, ZRANGE, ZSCORE, SCAN**. Quote a value that contains spaces.\n\nStructured replies land in `res.result` as real values: `HGETALL` → object, `LRANGE`/`SMEMBERS`/`ZRANGE` → array, `EXISTS`/`SISMEMBER`/`EXPIRE`/`PERSIST` → boolean; `res.resultText` is the stringified form. `SCAN pattern [count]` is Callman-managed: the cursor loop runs internally (capped at 1000 keys / 100 iterations) and returns `{ keys, count, truncated }` — no raw cursors.\n\n```js\nconst res = await pm.redis.command({ connectionId: \"…\", command: `GET session:${id}` });\npm.expect(res.success).to.be.true;\n// res.result / res.resultText hold the value; res.commandName, res.key are set.\n```\n",
|
|
8
8
|
"diagram-components": "<!-- GENERATED FILE — do not edit by hand. Source: callman_core (npm run ai:packs). -->\n\n# Diagram components and edge notation\n\nA diagram node's `type` MUST be one of the keys below (`callman-core` `DIAGRAM_COMPONENT_CATALOG`). Sizes are the defaults the studio uses; `container` types hold children via `parentId`.\n\n## Edge notation\n\n| Semantic | Meaning | Style tuple |\n| --- | --- | --- |\n| `sync` | Request / response call | dashed=false, strokeWidth=1.5 |\n| `async` | Fire-and-forget, event or callback | dashed=true, dashPattern=\"6 4\", strokeWidth=1.5 |\n| `fallback` | Retry, fallback or optional path | dashed=true, dashPattern=\"1 3\", strokeWidth=1.25 |\n| `bus` | Message bus or stream | dashed=false, strokeWidth=3 |\n\n## Generic (`generic`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `line` | Line | 160×0 | connector, edge, link |\n| `arrow` | Arrow | 160×0 | connector, directed, link |\n| `line.dashed` | Dashed Line | 160×0 | dotted, connector |\n| `rect` | Rectangle | 140×64 | box, card |\n| `square` | Square | 90×90 | |\n| `ellipse` | Ellipse | 140×64 | oval |\n| `circle` | Circle | 90×90 | |\n| `diamond` | Diamond | 140×64 | rhombus |\n| `triangle` | Triangle | 140×64 | |\n| `hexagon` | Hexagon | 140×64 | |\n| `pentagon` | Pentagon | 140×64 | |\n| `octagon` | Octagon | 140×64 | |\n| `parallelogram` | Parallelogram | 140×64 | |\n| `trapezoid` | Trapezoid | 140×64 | |\n| `cylinder` | Cylinder | 140×64 | can, tube |\n| `cloud-shape` | Cloud | 140×64 | |\n| `callout` | Callout | 140×64 | speech, bubble |\n| `text` | Text | 120×36 | |\n| `sticky` | Sticky note | 140×100 | postit, comment |\n| `card` | Card | 140×64 | |\n| `frame` | Frame / Container (container) | 220×160 | group, container, boundary |\n| `pool.horizontal` | Pool (horizontal) (swimlane) | 360×220 | swimlane, lane, container, subsystem |\n| `pool.vertical` | Pool (vertical) (swimlane) | 220×360 | swimlane, lane, container, subsystem |\n| `image` | Image | 140×64 | picture |\n\n## Flowchart (`flowchart`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `flow.process` | Process | 140×64 | step, action |\n| `flow.alt-process` | Alternate Process | 140×64 | |\n| `flow.decision` | Decision | 140×100 | if, branch |\n| `flow.terminator` | Start / End | 130×56 | terminator, begin, stop |\n| `flow.data` | Data (I/O) | 140×64 | input, output, io |\n| `flow.document` | Document | 140×64 | |\n| `flow.multi-document` | Multi-Document | 140×64 | |\n| `flow.predefined` | Predefined Process | 140×64 | subroutine |\n| `flow.manual-input` | Manual Input | 140×64 | |\n| `flow.manual-op` | Manual Operation | 140×64 | |\n| `flow.preparation` | Preparation | 140×64 | |\n| `flow.stored-data` | Stored Data | 140×64 | |\n| `flow.database` | Database | 140×64 | db, store |\n| `flow.display` | Display | 140×64 | |\n| `flow.delay` | Delay | 140×64 | |\n| `flow.merge` | Merge | 140×64 | |\n| `flow.or` | Or | 140×64 | |\n| `flow.connector` | On-page Connector | 48×48 | |\n| `flow.off-page` | Off-page Connector | 140×64 | |\n| `flow.annotation` | Annotation | 140×64 | |\n\n## UML (`uml`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `uml.class` | Class | 140×64 | entity |\n| `uml.abstract` | Abstract Class | 140×64 | |\n| `uml.interface` | Interface | 140×64 | |\n| `uml.enum` | Enum | 140×64 | |\n| `uml.object` | Object | 140×64 | |\n| `uml.package` | Package | 140×64 | |\n| `uml.component` | Component | 140×64 | |\n| `uml.node` | Node / Deployment | 140×64 | |\n| `uml.actor` | Actor | 60×100 | user, role |\n| `uml.usecase` | Use Case | 140×64 | |\n| `uml.boundary` | Boundary | 140×64 | |\n| `uml.control` | Control | 140×64 | |\n| `uml.entity` | Entity | 140×64 | |\n| `uml.state` | State | 140×64 | |\n| `uml.initial` | Initial State | 36×36 | |\n| `uml.final` | Final State | 40×40 | |\n| `uml.decision` | Decision | 60×60 | |\n| `uml.note` | Note / Comment | 140×64 | comment |\n\n## ERD (`erd`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `erd.entity` | Entity | 140×64 | table |\n| `erd.weak-entity` | Weak Entity | 140×64 | |\n| `erd.attribute` | Attribute | 140×64 | |\n| `erd.key-attribute` | Key Attribute | 140×64 | pk, primary key |\n| `erd.multivalued` | Multivalued Attribute | 140×64 | |\n| `erd.derived` | Derived Attribute | 140×64 | |\n| `erd.relationship` | Relationship | 140×64 | |\n| `erd.identifying` | Identifying Relationship | 140×64 | |\n\n## Architecture (`networking`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `net.user` | User / Client | 60×100 | client, person |\n| `net.admin` | Admin | 60×100 | |\n| `net.browser` | Browser | 140×64 | |\n| `net.mobile` | Mobile Device | 90×130 | phone |\n| `net.desktop` | Desktop | 140×64 | |\n| `net.iot` | IoT Device | 140×64 | |\n| `net.server` | Server | 140×64 | |\n| `net.service` | Service | 140×64 | microservice |\n| `net.monolith` | Monolith | 140×64 | |\n| `net.api-gateway` | API Gateway | 140×64 | api, gateway |\n| `net.load-balancer` | Load Balancer | 140×64 | lb |\n| `net.reverse-proxy` | Reverse Proxy | 140×64 | proxy |\n| `net.firewall` | Firewall | 140×64 | waf |\n| `net.router` | Router | 140×64 | |\n| `net.switch` | Switch | 140×64 | |\n| `net.dns` | DNS | 140×64 | |\n| `net.cdn` | CDN | 140×64 | edge |\n| `net.cache` | Cache | 140×64 | |\n| `net.queue` | Queue | 140×64 | mq |\n| `net.websocket` | Web Socket | 140×64 | ws |\n| `net.rest` | REST endpoint | 140×64 | http, api |\n| `net.internet` | Internet / Cloud | 140×64 | wan |\n| `net.datacenter` | Datacenter | 140×64 | |\n| `net.container` | Container | 140×64 | |\n| `net.pod` | Pod | 140×64 | |\n| `net.vm` | Virtual Machine | 140×64 | vm |\n\n## Databases (`database`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `db.postgres` | PostgreSQL | 176×56 | postgres, pg |\n| `db.mysql` | MySQL | 176×56 | |\n| `db.mariadb` | MariaDB | 176×56 | |\n| `db.mongodb` | MongoDB | 176×56 | mongo |\n| `db.redis` | Redis | 176×56 | |\n| `db.sqlite` | SQLite | 176×56 | |\n| `db.mssql` | MS SQL Server | 176×56 | sqlserver, mssql |\n| `db.oracle` | Oracle | 176×56 | |\n| `db.cassandra` | Cassandra | 176×56 | |\n| `db.elasticsearch` | Elasticsearch | 176×56 | elastic, es |\n| `db.neo4j` | Neo4j | 176×56 | graph |\n| `db.couchdb` | CouchDB | 176×56 | couch |\n| `db.couchbase` | Couchbase | 176×56 | |\n| `db.clickhouse` | ClickHouse | 176×56 | |\n| `db.cockroachdb` | CockroachDB | 176×56 | cockroach |\n| `db.influxdb` | InfluxDB | 176×56 | influx, tsdb |\n| `db.snowflake` | Snowflake | 176×56 | |\n| `db.supabase` | Supabase | 176×56 | |\n\n## Messaging (`messaging`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `mq.kafka` | Apache Kafka | 176×56 | kafka |\n| `mq.rabbitmq` | RabbitMQ | 176×56 | rabbit, amqp |\n| `mq.nats` | NATS | 176×56 | |\n| `mq.pulsar` | Apache Pulsar | 176×56 | pulsar |\n| `mq.mqtt` | MQTT | 176×56 | |\n| `mq.pubsub` | Pub/Sub | 176×56 | pubsub |\n| `mq.activemq` | ActiveMQ | 176×56 | jms |\n\n## Languages (`language`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `lang.node` | Node.js | 176×56 | node, js runtime |\n| `lang.python` | Python | 176×56 | py |\n| `lang.java` | Java | 176×56 | jvm |\n| `lang.go` | Go | 176×56 | golang |\n| `lang.rust` | Rust | 176×56 | |\n| `lang.dotnet` | C# / .NET | 176×56 | csharp, c# |\n| `lang.typescript` | TypeScript | 176×56 | ts |\n| `lang.javascript` | JavaScript | 176×56 | js |\n| `lang.ruby` | Ruby | 176×56 | |\n| `lang.php` | PHP | 176×56 | |\n| `lang.kotlin` | Kotlin | 176×56 | |\n| `lang.swift` | Swift | 176×56 | |\n| `lang.scala` | Scala | 176×56 | |\n| `lang.elixir` | Elixir | 176×56 | |\n| `lang.cpp` | C++ | 176×56 | cpp |\n\n## Frameworks (`framework`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `fw.express` | Express | 176×56 | |\n| `fw.nestjs` | NestJS | 176×56 | nest |\n| `fw.spring` | Spring Boot | 176×56 | spring |\n| `fw.django` | Django | 176×56 | |\n| `fw.flask` | Flask | 176×56 | |\n| `fw.fastapi` | FastAPI | 176×56 | |\n| `fw.rails` | Rails | 176×56 | ruby on rails |\n| `fw.laravel` | Laravel | 176×56 | |\n| `fw.dotnet` | .NET | 176×56 | |\n| `fw.react` | React | 176×56 | |\n| `fw.vue` | Vue | 176×56 | vuejs |\n| `fw.angular` | Angular | 176×56 | |\n| `fw.next` | Next.js | 176×56 | nextjs |\n| `fw.nuxt` | Nuxt | 176×56 | nuxtjs |\n| `fw.svelte` | Svelte | 176×56 | sveltekit |\n| `fw.electron` | Electron | 176×56 | |\n| `fw.tailwind` | Tailwind | 176×56 | tailwindcss |\n| `fw.graphql` | GraphQL | 176×56 | |\n\n## DevOps / CI-CD (`devops`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `ops.docker` | Docker | 176×56 | |\n| `ops.k8s` | Kubernetes | 176×56 | k8s |\n| `ops.nginx` | Nginx | 176×56 | |\n| `ops.haproxy` | HAProxy | 176×56 | lb |\n| `ops.traefik` | Traefik | 176×56 | traefik |\n| `ops.terraform` | Terraform | 176×56 | iac |\n| `ops.ansible` | Ansible | 176×56 | |\n| `ops.jenkins` | Jenkins | 176×56 | ci |\n| `ops.gha` | GitHub Actions | 176×56 | ci, actions |\n| `ops.gitlab` | GitLab CI | 176×56 | ci |\n| `ops.argocd` | ArgoCD | 176×56 | gitops |\n| `ops.helm` | Helm | 176×56 | |\n| `ops.istio` | Istio | 176×56 | service mesh |\n| `ops.envoy` | Envoy | 176×56 | proxy |\n| `ops.consul` | Consul | 176×56 | |\n| `ops.vault` | Vault | 176×56 | secrets |\n| `ops.pm2` | PM2 | 176×56 | |\n| `ops.maven` | Maven | 176×56 | build |\n\n## Auth / Identity (`auth`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `auth.oidc` | OpenID Connect | 176×56 | oidc |\n| `auth.jwt` | JWT | 176×56 | token |\n| `auth.keycloak` | Keycloak | 176×56 | |\n| `auth.auth0` | Auth0 | 176×56 | |\n| `auth.okta` | Okta | 176×56 | |\n| `auth.firebase` | Firebase Auth | 176×56 | firebase |\n| `auth.oauth` | OAuth 2.0 | 176×56 | oauth |\n| `auth.saml` | SAML | 176×56 | |\n| `auth.ldap` | LDAP | 176×56 | |\n\n## Observability (`observability`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `obs.prometheus` | Prometheus | 176×56 | metrics |\n| `obs.grafana` | Grafana | 176×56 | dashboard |\n| `obs.datadog` | Datadog | 176×56 | |\n| `obs.sentry` | Sentry | 176×56 | errors |\n| `obs.elasticsearch` | Elasticsearch | 176×56 | elk |\n| `obs.logstash` | Logstash | 176×56 | elk |\n| `obs.kibana` | Kibana | 176×56 | elk |\n| `obs.jaeger` | Jaeger | 176×56 | tracing |\n| `obs.otel` | OpenTelemetry | 176×56 | otel, tracing |\n| `obs.newrelic` | New Relic | 176×56 | |\n\n## AWS (`aws`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `aws.ec2` | EC2 | 176×56 | aws |\n| `aws.lambda` | Lambda | 176×56 | aws |\n| `aws.s3` | S3 | 176×56 | aws |\n| `aws.ebs` | EBS | 176×56 | aws |\n| `aws.efs` | EFS | 176×56 | aws |\n| `aws.rds` | RDS | 176×56 | aws |\n| `aws.aurora` | Aurora | 176×56 | aws |\n| `aws.dynamodb` | DynamoDB | 176×56 | aws |\n| `aws.elasticache` | ElastiCache | 176×56 | aws |\n| `aws.redshift` | Redshift | 176×56 | aws |\n| `aws.vpc` | VPC | 176×56 | aws |\n| `aws.subnet` | Subnet | 176×56 | aws |\n| `aws.internet-gateway` | Internet Gateway | 176×56 | aws |\n| `aws.nat-gateway` | NAT Gateway | 176×56 | aws |\n| `aws.elb` | ELB | 176×56 | aws |\n| `aws.alb` | ALB | 176×56 | aws |\n| `aws.nlb` | NLB | 176×56 | aws |\n| `aws.api-gateway` | API Gateway | 176×56 | aws |\n| `aws.cloudfront` | CloudFront | 176×56 | aws |\n| `aws.route-53` | Route 53 | 176×56 | aws |\n| `aws.sqs` | SQS | 176×56 | aws |\n| `aws.sns` | SNS | 176×56 | aws |\n| `aws.eventbridge` | EventBridge | 176×56 | aws |\n| `aws.kinesis` | Kinesis | 176×56 | aws |\n| `aws.step-functions` | Step Functions | 176×56 | aws |\n| `aws.ecs` | ECS | 176×56 | aws |\n| `aws.eks` | EKS | 176×56 | aws |\n| `aws.fargate` | Fargate | 176×56 | aws |\n| `aws.ecr` | ECR | 176×56 | aws |\n| `aws.iam` | IAM | 176×56 | aws |\n| `aws.cognito` | Cognito | 176×56 | aws |\n| `aws.secrets-manager` | Secrets Manager | 176×56 | aws |\n| `aws.kms` | KMS | 176×56 | aws |\n| `aws.cloudwatch` | CloudWatch | 176×56 | aws |\n| `aws.cloudtrail` | CloudTrail | 176×56 | aws |\n| `aws.glue` | Glue | 176×56 | aws |\n| `aws.athena` | Athena | 176×56 | aws |\n| `aws.sagemaker` | SageMaker | 176×56 | aws |\n| `aws.appsync` | AppSync | 176×56 | aws |\n| `aws.amplify` | Amplify | 176×56 | aws |\n\n## Azure (`azure`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `azure.virtual-machine` | Virtual Machine | 176×56 | azure |\n| `azure.vm-scale-set` | VM Scale Set | 176×56 | azure |\n| `azure.app-service` | App Service | 176×56 | azure |\n| `azure.functions` | Functions | 176×56 | azure |\n| `azure.container-instances` | Container Instances | 176×56 | azure |\n| `azure.aks` | AKS | 176×56 | azure |\n| `azure.container-registry` | Container Registry | 176×56 | azure |\n| `azure.blob-storage` | Blob Storage | 176×56 | azure |\n| `azure.files` | Files | 176×56 | azure |\n| `azure.disk` | Disk | 176×56 | azure |\n| `azure.sql-database` | SQL Database | 176×56 | azure |\n| `azure.cosmos-db` | Cosmos DB | 176×56 | azure |\n| `azure.cache-for-redis` | Cache for Redis | 176×56 | azure |\n| `azure.synapse` | Synapse | 176×56 | azure |\n| `azure.virtual-network` | Virtual Network | 176×56 | azure |\n| `azure.load-balancer` | Load Balancer | 176×56 | azure |\n| `azure.application-gateway` | Application Gateway | 176×56 | azure |\n| `azure.front-door` | Front Door | 176×56 | azure |\n| `azure.service-bus` | Service Bus | 176×56 | azure |\n| `azure.event-hub` | Event Hub | 176×56 | azure |\n| `azure.event-grid` | Event Grid | 176×56 | azure |\n| `azure.key-vault` | Key Vault | 176×56 | azure |\n| `azure.entra-id` | Entra ID | 176×56 | azure |\n| `azure.monitor` | Monitor | 176×56 | azure |\n| `azure.application-insights` | Application Insights | 176×56 | azure |\n| `azure.logic-apps` | Logic Apps | 176×56 | azure |\n| `azure.api-management` | API Management | 176×56 | azure |\n\n## GCP (`gcp`)\n\n| Type | Label | Default size | Aliases |\n| --- | --- | --- | --- |\n| `gcp.compute-engine` | Compute Engine | 176×56 | gcp, google |\n| `gcp.app-engine` | App Engine | 176×56 | gcp, google |\n| `gcp.cloud-functions` | Cloud Functions | 176×56 | gcp, google |\n| `gcp.cloud-run` | Cloud Run | 176×56 | gcp, google |\n| `gcp.gke` | GKE | 176×56 | gcp, google |\n| `gcp.artifact-registry` | Artifact Registry | 176×56 | gcp, google |\n| `gcp.cloud-storage` | Cloud Storage | 176×56 | gcp, google |\n| `gcp.persistent-disk` | Persistent Disk | 176×56 | gcp, google |\n| `gcp.cloud-sql` | Cloud SQL | 176×56 | gcp, google |\n| `gcp.cloud-spanner` | Cloud Spanner | 176×56 | gcp, google |\n| `gcp.firestore` | Firestore | 176×56 | gcp, google |\n| `gcp.bigtable` | Bigtable | 176×56 | gcp, google |\n| `gcp.bigquery` | BigQuery | 176×56 | gcp, google |\n| `gcp.memorystore` | Memorystore | 176×56 | gcp, google |\n| `gcp.vpc` | VPC | 176×56 | gcp, google |\n| `gcp.cloud-load-balancing` | Cloud Load Balancing | 176×56 | gcp, google |\n| `gcp.cloud-cdn` | Cloud CDN | 176×56 | gcp, google |\n| `gcp.cloud-dns` | Cloud DNS | 176×56 | gcp, google |\n| `gcp.pub-sub` | Pub/Sub | 176×56 | gcp, google |\n| `gcp.dataflow` | Dataflow | 176×56 | gcp, google |\n| `gcp.cloud-tasks` | Cloud Tasks | 176×56 | gcp, google |\n| `gcp.iam` | IAM | 176×56 | gcp, google |\n| `gcp.secret-manager` | Secret Manager | 176×56 | gcp, google |\n| `gcp.cloud-kms` | Cloud KMS | 176×56 | gcp, google |\n| `gcp.cloud-monitoring` | Cloud Monitoring | 176×56 | gcp, google |\n| `gcp.vertex-ai` | Vertex AI | 176×56 | gcp, google |\n",
|
|
@@ -117,6 +117,17 @@ const variableText = (value) => {
|
|
|
117
117
|
return String(value);
|
|
118
118
|
}
|
|
119
119
|
};
|
|
120
|
+
// Collection-level auth (`collection.auth` of the export / pipeline bundle):
|
|
121
|
+
// what requests set to "inherit" send. Absent = none, so an inherited request
|
|
122
|
+
// sends no auth.
|
|
123
|
+
const collectionAuthOf = (record) => {
|
|
124
|
+
const auth = isRecord(record.collection) ? record.collection.auth : undefined;
|
|
125
|
+
return isRecord(auth) && typeof auth.type === "string" && auth.type !== "none" && auth.type !== "inherit"
|
|
126
|
+
? auth
|
|
127
|
+
: undefined;
|
|
128
|
+
};
|
|
129
|
+
// A request's auth with "inherit" replaced by the collection's.
|
|
130
|
+
const effectiveAuth = (auth, collectionAuth) => isRecord(auth) && auth.type === "inherit" ? (collectionAuth ?? { type: "none" }) : auth;
|
|
120
131
|
// Collection variables, enabled ones only — `collection.variables` of the
|
|
121
132
|
// bundle / a Callman export (`{ key, value, enabled }[]`), a top-level
|
|
122
133
|
// `variables`, or Postman's `variable[]` (`disabled`). Same reading as callme.
|
|
@@ -234,6 +245,7 @@ const validateCollection = (input) => {
|
|
|
234
245
|
: fail("collection.name must be a non-empty string");
|
|
235
246
|
if (!Array.isArray(record.requests))
|
|
236
247
|
fail("collection.requests must be an array");
|
|
248
|
+
const collectionAuth = collectionAuthOf(record);
|
|
237
249
|
const requests = record.requests.map((raw, index) => {
|
|
238
250
|
const label = `requests[${index}]`;
|
|
239
251
|
if (!isRecord(raw))
|
|
@@ -243,8 +255,10 @@ const validateCollection = (input) => {
|
|
|
243
255
|
if (typeof request[field] !== "string" || !request[field].trim())
|
|
244
256
|
fail(`${label}.${field} must be a non-empty string`);
|
|
245
257
|
}
|
|
246
|
-
|
|
247
|
-
const
|
|
258
|
+
// "Inherited" requests use the collection's auth (MEI-789).
|
|
259
|
+
const auth = effectiveAuth(request.auth, collectionAuth);
|
|
260
|
+
const headers = applyAuthHeaders(normalizeKeyValues(request.headers, `${label}.headers`), auth);
|
|
261
|
+
const query = applyAuthQuery(normalizeKeyValues(request.query, `${label}.query`), auth);
|
|
248
262
|
const preRequestScript = typeof request.preRequestScript === "string" && request.preRequestScript.trim() ? request.preRequestScript : undefined;
|
|
249
263
|
const postResponseScript = typeof request.postResponseScript === "string" && request.postResponseScript.trim() ? request.postResponseScript : undefined;
|
|
250
264
|
const contracts = Array.isArray(request.contracts) ? request.contracts : Array.isArray(request.contractRules) ? request.contractRules : undefined;
|
|
@@ -261,7 +275,7 @@ const validateCollection = (input) => {
|
|
|
261
275
|
isEnabledInRunner: request.isEnabledInRunner !== false,
|
|
262
276
|
headers: applyDefaultHeaders(headers, request.body),
|
|
263
277
|
query,
|
|
264
|
-
...(isRecord(
|
|
278
|
+
...(isRecord(auth) && auth.type === "oauth2" ? { auth: auth } : {}),
|
|
265
279
|
body: request.body,
|
|
266
280
|
tests: scriptOf(request),
|
|
267
281
|
...(preRequestScript ? { preRequestScript } : {}),
|
|
@@ -24,6 +24,7 @@ exports.TOOL_CATALOG = [
|
|
|
24
24
|
{ name: "update_folder", group: "collections", scopes: ["collections:write"] },
|
|
25
25
|
{ name: "delete_collection", group: "collections", scopes: ["collections:delete"], destructive: true },
|
|
26
26
|
{ name: "delete_folder", group: "collections", scopes: ["collections:delete"], destructive: true },
|
|
27
|
+
{ name: "search_knowledge", group: "collections", scopes: ["collections:read"] },
|
|
27
28
|
{ name: "search_requests", group: "requests", scopes: ["requests:read"] },
|
|
28
29
|
{ name: "get_request", group: "requests", scopes: ["requests:read"] },
|
|
29
30
|
{ name: "create_request", group: "requests", scopes: ["requests:write"] },
|
package/dist-cjs/tools/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const contracts_js_1 = require("./contracts.js");
|
|
|
7
7
|
const diagrams_js_1 = require("./diagrams.js");
|
|
8
8
|
const environments_js_1 = require("./environments.js");
|
|
9
9
|
const import_js_1 = require("./import.js");
|
|
10
|
+
const knowledge_js_1 = require("./knowledge.js");
|
|
10
11
|
const loadTest_js_1 = require("./loadTest.js");
|
|
11
12
|
const meta_js_1 = require("./meta.js");
|
|
12
13
|
const mocks_js_1 = require("./mocks.js");
|
|
@@ -49,6 +50,7 @@ const registerAllTools = (host, ctx) => {
|
|
|
49
50
|
(0, meta_js_1.registerMetaTools)(server, ctx);
|
|
50
51
|
(0, workspaces_js_1.registerWorkspaceTools)(server, ctx);
|
|
51
52
|
(0, collections_js_1.registerCollectionTools)(server, ctx);
|
|
53
|
+
(0, knowledge_js_1.registerKnowledgeTools)(server, ctx);
|
|
52
54
|
(0, requests_js_1.registerRequestTools)(server, ctx);
|
|
53
55
|
(0, contracts_js_1.registerContractTools)(server, ctx);
|
|
54
56
|
(0, import_js_1.registerImportTools)(server, ctx);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerKnowledgeTools = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const shared_js_1 = require("./shared.js");
|
|
6
|
+
// search_knowledge — the organisation's own material an administrator set up
|
|
7
|
+
// in Callman (admin panel → AI Knowledge): API definitions, existing
|
|
8
|
+
// collections and their tests, conventions and known defects, scoped to the
|
|
9
|
+
// token owner's tribe and squad. A model should read it before writing
|
|
10
|
+
// requests, tests or scenarios, so what it writes follows the organisation's
|
|
11
|
+
// conventions and the real API shapes instead of generic guesses.
|
|
12
|
+
const registerKnowledgeTools = (server, ctx) => {
|
|
13
|
+
server.registerTool("search_knowledge", {
|
|
14
|
+
title: "Search the organisation's knowledge",
|
|
15
|
+
description: "Search the reference material your Callman administrator set up for AI work (AI Knowledge): OpenAPI definitions of the organisation's services, existing collections (requests, contract checks, tests), conventions — naming, priorities, review rules, which are BINDING — and known defect patterns. Results are limited to sources for everyone and for your own groups. Call it before writing requests, tests or scenarios, and give `method` + `url` when you work on a specific endpoint to get its definition and existing tests first. Empty when nothing is set up or the AI Knowledge feature is off.",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
query: zod_1.z.string().min(1).max(4_000).describe("What you are about to do or look up, in plain words."),
|
|
18
|
+
method: zod_1.z.string().max(10).optional().describe("HTTP method of the endpoint you work on."),
|
|
19
|
+
url: zod_1.z.string().max(2_000).optional().describe("URL or path of the endpoint you work on."),
|
|
20
|
+
maxChars: zod_1.z.number().int().min(500).max(20_000).default(8_000).describe("Size budget of the result."),
|
|
21
|
+
},
|
|
22
|
+
annotations: shared_js_1.READ,
|
|
23
|
+
}, (0, shared_js_1.guarded)(async ({ query, method, url, maxChars }) => {
|
|
24
|
+
const result = await ctx.api.searchKnowledge({
|
|
25
|
+
feature: "mcp",
|
|
26
|
+
query,
|
|
27
|
+
method: method ?? null,
|
|
28
|
+
url: url ?? null,
|
|
29
|
+
budgetChars: maxChars,
|
|
30
|
+
});
|
|
31
|
+
const items = result.snippets.map((snippet) => ({
|
|
32
|
+
source: snippet.sourceName,
|
|
33
|
+
kind: snippet.kind,
|
|
34
|
+
title: snippet.title,
|
|
35
|
+
text: snippet.text,
|
|
36
|
+
why: snippet.reason === "endpoint" ? "same endpoint" : snippet.reason === "always" ? "always included (binding)" : "relevant",
|
|
37
|
+
}));
|
|
38
|
+
return (0, shared_js_1.ok)({
|
|
39
|
+
sources: result.sources.map((source) => ({ name: source.name, kind: source.kind })),
|
|
40
|
+
items,
|
|
41
|
+
...(items.length === 0
|
|
42
|
+
? { note: "Nothing matched: no organisation knowledge applies to this request (or none is set up)." }
|
|
43
|
+
: { rule: "Conventions are binding; prefer these API definitions and tests over assumptions." }),
|
|
44
|
+
});
|
|
45
|
+
}));
|
|
46
|
+
};
|
|
47
|
+
exports.registerKnowledgeTools = registerKnowledgeTools;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "callman-mcp",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "MCP server for Callman: lets Claude Code, Claude Desktop, Cursor, Codex and Gemini CLI manage collections, requests, environments, test scenarios, UI tests (web, Android, iOS) and system-design diagrams in your Callman workspace — cloud or on-prem.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"callman",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
65
|
-
"callman-core": "^1.
|
|
65
|
+
"callman-core": "^1.42.0",
|
|
66
66
|
"elkjs": "^0.12.0",
|
|
67
67
|
"js-yaml": "^4.1.0",
|
|
68
68
|
"zod": "^3.25.0"
|