@kammcs/buildit-mcp 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/README.md +27 -6
- package/dist/api/generated/operations.js +175 -3
- package/dist/api/generated/schemas.js +259 -4
- package/dist/api/generated/strict.js +292 -4
- package/dist/capabilities.js +236 -0
- package/dist/channel/api.js +32 -1
- package/dist/channel/handoffs.js +190 -0
- package/dist/channel/item-events.js +29 -3
- package/dist/channel/loop.js +262 -4
- package/dist/cli/commands.js +29 -1
- package/dist/config.js +27 -0
- package/dist/errors.js +11 -1
- package/dist/server.js +9 -1
- package/dist/tools/handoff.js +409 -0
- package/dist/tools/items-read.js +1 -0
- package/dist/tools/items-write.js +11 -1
- package/dist/tools/shared.js +14 -0
- package/dist/tools/threads.js +26 -0
- package/dist/tools/whoami.js +36 -0
- package/dist/transports/stdio.js +36 -14
- package/package.json +1 -1
package/dist/transports/stdio.js
CHANGED
|
@@ -11,6 +11,8 @@ import { APPROVAL_HOOK_TOOLS, createApprovalHookTools, READ_ONLY_SAFE_HOOKS, cre
|
|
|
11
11
|
import { createAskTool } from '../tools/ask.js';
|
|
12
12
|
import { createReplyTool, createTurnEndedTool } from '../tools/reply.js';
|
|
13
13
|
import { createListThreadsTool } from '../tools/threads.js';
|
|
14
|
+
import { createHandoffTools } from '../tools/handoff.js';
|
|
15
|
+
import { suggestedCapabilities } from '../capabilities.js';
|
|
14
16
|
import { CATALOG } from '../toolsets/catalog.js';
|
|
15
17
|
import { compareVersions, SERVER_VERSION } from '../version.js';
|
|
16
18
|
/**
|
|
@@ -273,9 +275,21 @@ function channelTools(policy, state, ask, approve) {
|
|
|
273
275
|
createTurnEndedTool(state),
|
|
274
276
|
createApproveTool(state, approve),
|
|
275
277
|
...createApprovalHookTools(state),
|
|
278
|
+
...createHandoffTools(state),
|
|
276
279
|
].filter((tool) => (!policy.readOnly || tool.annotations.readOnlyHint || READ_ONLY_SAFE_HOOKS.has(tool.name)) &&
|
|
277
280
|
!policy.excludeTools.includes(tool.name));
|
|
278
281
|
}
|
|
282
|
+
/**
|
|
283
|
+
* The channel tools this server's API serves: a tool that needs operations
|
|
284
|
+
* the API's /v1/meta leaves out is not listed (when the API doesn't say,
|
|
285
|
+
* every tool is, and an older one says so when called).
|
|
286
|
+
*/
|
|
287
|
+
function servedTools(api, tools) {
|
|
288
|
+
const served = api.served?.operations;
|
|
289
|
+
if (served === undefined)
|
|
290
|
+
return [...tools];
|
|
291
|
+
return tools.filter((t) => (t.requiresOperations ?? []).every((op) => served.has(op)));
|
|
292
|
+
}
|
|
279
293
|
export function startStdio(config, logger, options = {}) {
|
|
280
294
|
if (config.token === undefined)
|
|
281
295
|
throw new Error('stdio mode needs a token');
|
|
@@ -336,11 +350,27 @@ export function startStdio(config, logger, options = {}) {
|
|
|
336
350
|
tools: base.tools.filter((t) => !extraTools.includes(t) || t.runsAfterSessionEnd === true),
|
|
337
351
|
};
|
|
338
352
|
};
|
|
353
|
+
// Read what the API serves at startup: it warns when the API needs a newer server, and
|
|
354
|
+
// channel tools newer than the server (the handoffs) are left out of the listing.
|
|
355
|
+
const metaRead = api
|
|
356
|
+
.getMeta()
|
|
357
|
+
.then((meta) => {
|
|
358
|
+
if (meta.min_mcp_version && compareVersions(SERVER_VERSION, meta.min_mcp_version) < 0) {
|
|
359
|
+
logger.warn('this buildit-mcp is older than the API supports; update it', {
|
|
360
|
+
version: SERVER_VERSION,
|
|
361
|
+
min_version: meta.min_mcp_version,
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
})
|
|
365
|
+
.catch(() => undefined);
|
|
339
366
|
const identity = new StdioIdentity(async () => {
|
|
340
367
|
if (isEnded())
|
|
341
368
|
return frozen();
|
|
342
369
|
const listed = await resolveListedTools(identityFromApi(api), catalog, policy, logger);
|
|
343
|
-
|
|
370
|
+
if (extraTools.length > 0)
|
|
371
|
+
await metaRead;
|
|
372
|
+
const served = servedTools(api, extraTools);
|
|
373
|
+
const shown = served.length > 0 ? { ...listed, tools: [...listed.tools, ...served] } : listed;
|
|
344
374
|
if (shown.identity === 'known')
|
|
345
375
|
lastKnown = shown;
|
|
346
376
|
// The session may have ended while the identity was read.
|
|
@@ -351,18 +381,6 @@ export function startStdio(config, logger, options = {}) {
|
|
|
351
381
|
};
|
|
352
382
|
// Read the identity at startup.
|
|
353
383
|
void identity.refresh();
|
|
354
|
-
// Warn early when the API needs a newer server.
|
|
355
|
-
void api
|
|
356
|
-
.getMeta()
|
|
357
|
-
.then((meta) => {
|
|
358
|
-
if (meta.min_mcp_version && compareVersions(SERVER_VERSION, meta.min_mcp_version) < 0) {
|
|
359
|
-
logger.warn('this buildit-mcp is older than the API supports; update it', {
|
|
360
|
-
version: SERVER_VERSION,
|
|
361
|
-
min_version: meta.min_mcp_version,
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
})
|
|
365
|
-
.catch(() => undefined);
|
|
366
384
|
// Everything the configuration allows is registered; the identity decides what is shown.
|
|
367
385
|
const allowed = listedByPolicy(catalog, policy);
|
|
368
386
|
const wire = options.stdin && options.stdout
|
|
@@ -373,7 +391,9 @@ export function startStdio(config, logger, options = {}) {
|
|
|
373
391
|
const handle = serveStdio(async () => {
|
|
374
392
|
const listed = await identity.refresh();
|
|
375
393
|
const switchable = createSwitchableMcpServer({
|
|
376
|
-
|
|
394
|
+
// What /v1/meta said is known by now (refresh waited for it): the instructions leave out
|
|
395
|
+
// the channel tools this API doesn't serve.
|
|
396
|
+
tools: [...allowed.tools, ...servedTools(api, extraTools)],
|
|
377
397
|
resources: allowed.resources,
|
|
378
398
|
prompts: allowed.prompts,
|
|
379
399
|
api,
|
|
@@ -412,6 +432,8 @@ export function startStdio(config, logger, options = {}) {
|
|
|
412
432
|
logger: logger.child({ component: 'channel' }),
|
|
413
433
|
state,
|
|
414
434
|
notify: (params) => mcp.notification({ method: CHANNEL_NOTIFICATION, params }),
|
|
435
|
+
// What this computer can do, as tag names only (BUILDIT_CAPABILITIES replaces it).
|
|
436
|
+
capabilities: () => suggestedCapabilities(config.channel?.capabilities),
|
|
415
437
|
...(options.channelLock === undefined
|
|
416
438
|
? {}
|
|
417
439
|
: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kammcs/buildit-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "MCP server for buildIt.Social: lets AI agents work with an org's projects, pages and channels through the buildIt.Social agent API, with a personal access token.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Kamm Creative Solutions",
|