@contentrain/mcp 1.9.0 → 1.10.1
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 +10 -3
- package/dist/{annotations-DSzewhL4.mjs → annotations-D3tlsF38.mjs} +39 -4
- package/dist/annotations-D3tlsF38.mjs.map +1 -0
- package/dist/{apply-manager-BnPbPXFG.mjs → apply-manager-UXUTYFZn.mjs} +3 -3
- package/dist/{apply-manager-BnPbPXFG.mjs.map → apply-manager-UXUTYFZn.mjs.map} +1 -1
- package/dist/{availability-Bj9zOfEn.mjs → availability-sWWRz2W0.mjs} +8 -2
- package/dist/availability-sWWRz2W0.mjs.map +1 -0
- package/dist/branch-lifecycle-AwBJIheA.d.mts.map +1 -1
- package/dist/{branch-lifecycle-D7tXOE4f.mjs → branch-lifecycle-Dd84lx37.mjs} +61 -3
- package/dist/branch-lifecycle-Dd84lx37.mjs.map +1 -0
- package/dist/{content-manager-BExZy6Eu.d.mts → content-manager-DcmNwvmq.d.mts} +2 -2
- package/dist/{content-manager-BExZy6Eu.d.mts.map → content-manager-DcmNwvmq.d.mts.map} +1 -1
- package/dist/core/apply-manager.mjs +3 -3
- package/dist/core/config.d.mts +1 -1
- package/dist/core/content-manager.d.mts +1 -1
- package/dist/core/context.d.mts +1 -1
- package/dist/core/contracts/index.d.mts +2 -2
- package/dist/core/doctor.mjs +2 -2
- package/dist/core/model-manager.d.mts +1 -1
- package/dist/core/ops/index.d.mts +2 -2
- package/dist/core/overlay-reader.d.mts +1 -1
- package/dist/core/validator/index.d.mts +1 -1
- package/dist/{doctor-BTToHt0y.mjs → doctor-BwSJW1sS.mjs} +2 -2
- package/dist/{doctor-BTToHt0y.mjs.map → doctor-BwSJW1sS.mjs.map} +1 -1
- package/dist/git/branch-lifecycle.mjs +1 -1
- package/dist/git/transaction.d.mts.map +1 -1
- package/dist/git/transaction.mjs +2 -2
- package/dist/index-DDX-qYNw.d.mts +2 -0
- package/dist/index.mjs +7 -7
- package/dist/{local-BZEUWBoC.mjs → local-BIE23GuI.mjs} +3 -3
- package/dist/{local-BZEUWBoC.mjs.map → local-BIE23GuI.mjs.map} +1 -1
- package/dist/providers/github/index.d.mts +1 -1
- package/dist/providers/gitlab/index.d.mts +1 -1
- package/dist/providers/local/index.d.mts +1 -1
- package/dist/providers/local/index.mjs +3 -3
- package/dist/server/http/index.d.mts +1 -1
- package/dist/server/http/index.mjs +7 -7
- package/dist/{server-B6_fzRmK.mjs → server-BkDuFvVt.mjs} +139 -9
- package/dist/server-BkDuFvVt.mjs.map +1 -0
- package/dist/{server-B1KfvywF.d.mts → server-vA1tM7DA.d.mts} +2 -2
- package/dist/{server-B1KfvywF.d.mts.map → server-vA1tM7DA.d.mts.map} +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.mjs +7 -7
- package/dist/tools/annotations.d.mts +3 -3
- package/dist/tools/annotations.d.mts.map +1 -1
- package/dist/tools/annotations.mjs +1 -1
- package/dist/tools/availability.d.mts +3 -0
- package/dist/tools/availability.d.mts.map +1 -1
- package/dist/tools/availability.mjs +1 -1
- package/dist/{transaction-qliKvBRL.mjs → transaction-DhVoGigz.mjs} +4 -22
- package/dist/transaction-DhVoGigz.mjs.map +1 -0
- package/package.json +4 -4
- package/dist/annotations-DSzewhL4.mjs.map +0 -1
- package/dist/availability-Bj9zOfEn.mjs.map +0 -1
- package/dist/branch-lifecycle-D7tXOE4f.mjs.map +0 -1
- package/dist/index-6yasXNLQ.d.mts +0 -2
- package/dist/server-B6_fzRmK.mjs.map +0 -1
- package/dist/transaction-qliKvBRL.mjs.map +0 -1
|
@@ -5,19 +5,19 @@ import { n as readVocabulary, t as readConfig } from "./config-DlFcTxFG.mjs";
|
|
|
5
5
|
import { S as writeContent, _ as resolveMdFilePath, a as fieldDefZodSchema, c as validateModelDefinition, d as listContent, g as resolveLocaleStrategy, h as resolveJsonFilePath, l as writeModel, m as resolveContentDir, n as checkReferences, o as listModels, r as countEntries, s as readModel, u as deleteContent } from "./model-manager-BhLsUgaB.mjs";
|
|
6
6
|
import { n as readMeta, r as writeMeta } from "./meta-manager-C900rEyG.mjs";
|
|
7
7
|
import { n as readContext } from "./context-CYN__o3Q.mjs";
|
|
8
|
-
import { a as deleteRemoteBranch, c as pruneMergedRemoteBranches, i as cleanupMergedBranches, n as checkBranchHealth, s as listRemoteCrBranches } from "./branch-lifecycle-
|
|
9
|
-
import { i as mergeBranch, n as createTransaction, r as ensureContentBranch, t as buildBranchName } from "./transaction-
|
|
10
|
-
import { n as isMerged, t as LocalProvider } from "./local-
|
|
11
|
-
import { n as isToolAvailable, t as TOOL_REQUIREMENTS } from "./availability-
|
|
8
|
+
import { a as deleteRemoteBranch, c as pruneMergedRemoteBranches, i as cleanupMergedBranches, n as checkBranchHealth, s as listRemoteCrBranches } from "./branch-lifecycle-Dd84lx37.mjs";
|
|
9
|
+
import { i as mergeBranch, n as createTransaction, r as ensureContentBranch, t as buildBranchName } from "./transaction-DhVoGigz.mjs";
|
|
10
|
+
import { n as isMerged, t as LocalProvider } from "./local-BIE23GuI.mjs";
|
|
11
|
+
import { n as isToolAvailable, t as TOOL_REQUIREMENTS } from "./availability-sWWRz2W0.mjs";
|
|
12
12
|
import { t as detectStack } from "./detect-wVSI9VuY.mjs";
|
|
13
|
-
import { t as TOOL_ANNOTATIONS } from "./annotations-
|
|
13
|
+
import { t as TOOL_ANNOTATIONS } from "./annotations-D3tlsF38.mjs";
|
|
14
14
|
import { n as listTemplates, t as getTemplate } from "./templates-D6EllixQ.mjs";
|
|
15
15
|
import { t as validateProject } from "./validator-8vaPxSba.mjs";
|
|
16
16
|
import { t as OverlayReader } from "./overlay-reader-BOb105gS.mjs";
|
|
17
17
|
import { t as buildGraph } from "./graph-builder-CRUX_8mA.mjs";
|
|
18
18
|
import { n as scanSummary, t as scanCandidates } from "./scanner-VOwrKLGC.mjs";
|
|
19
|
-
import { n as applyExtract, r as applyReuse } from "./apply-manager-
|
|
20
|
-
import { t as runDoctor } from "./doctor-
|
|
19
|
+
import { n as applyExtract, r as applyReuse } from "./apply-manager-UXUTYFZn.mjs";
|
|
20
|
+
import { t as runDoctor } from "./doctor-BwSJW1sS.mjs";
|
|
21
21
|
import { join } from "node:path";
|
|
22
22
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
23
23
|
import { CONTENTRAIN_BRANCH } from "@contentrain/types";
|
|
@@ -2368,8 +2368,137 @@ function registerDoctorTools(server, _provider, projectRoot) {
|
|
|
2368
2368
|
});
|
|
2369
2369
|
}
|
|
2370
2370
|
//#endregion
|
|
2371
|
+
//#region src/tools/media.ts
|
|
2372
|
+
/**
|
|
2373
|
+
* Media tools — a deterministic passthrough to the provider's optional
|
|
2374
|
+
* media facet (`RepoProvider.media`). Registration is capability-aware:
|
|
2375
|
+
* `createServer` skips all five tools when the provider has no media
|
|
2376
|
+
* stack, so the guard below is defense in depth only.
|
|
2377
|
+
*
|
|
2378
|
+
* The facet closes the discovery loop for external agents: list assets →
|
|
2379
|
+
* pick a `media/...` path → reference it via `contentrain_content_save`
|
|
2380
|
+
* (which normalizes it to an absolute delivery URL when `mediaBaseUrl`
|
|
2381
|
+
* is set). Ingest is URL-based — MCP has no binary channel — and the
|
|
2382
|
+
* provider implementation owns SSRF/MIME/size policy for the fetch.
|
|
2383
|
+
*/
|
|
2384
|
+
function mediaUnavailable(tool) {
|
|
2385
|
+
return {
|
|
2386
|
+
content: [{
|
|
2387
|
+
type: "text",
|
|
2388
|
+
text: JSON.stringify({
|
|
2389
|
+
error: `${tool} requires a provider with a media stack.`,
|
|
2390
|
+
capability_required: "media",
|
|
2391
|
+
hint: "Media tools are available when MCP is driven by a media-capable provider (e.g. Studio MCP Cloud). Local and plain git providers do not expose one."
|
|
2392
|
+
})
|
|
2393
|
+
}],
|
|
2394
|
+
isError: true
|
|
2395
|
+
};
|
|
2396
|
+
}
|
|
2397
|
+
function mediaError(error, stage) {
|
|
2398
|
+
return {
|
|
2399
|
+
content: [{
|
|
2400
|
+
type: "text",
|
|
2401
|
+
text: JSON.stringify({ ...normalizeOperationError(error, stage) })
|
|
2402
|
+
}],
|
|
2403
|
+
isError: true
|
|
2404
|
+
};
|
|
2405
|
+
}
|
|
2406
|
+
function ok(payload) {
|
|
2407
|
+
return { content: [{
|
|
2408
|
+
type: "text",
|
|
2409
|
+
text: JSON.stringify(payload)
|
|
2410
|
+
}] };
|
|
2411
|
+
}
|
|
2412
|
+
function registerMediaTools(server, provider, _projectRoot) {
|
|
2413
|
+
server.tool("contentrain_media_list", "List media assets from the provider media stack. Returns storage paths (media/...) usable in media/image/file fields via contentrain_content_save, plus delivery URLs when available. Supports search, tag filter, and cursor pagination.", {
|
|
2414
|
+
search: z.string().optional().describe("Substring match on filename/path/alt"),
|
|
2415
|
+
tag: z.string().optional().describe("Only assets carrying this tag"),
|
|
2416
|
+
limit: z.number().int().min(1).max(100).optional().describe("Page size. Default: provider-defined"),
|
|
2417
|
+
cursor: z.string().optional().describe("Opaque cursor from a previous response")
|
|
2418
|
+
}, TOOL_ANNOTATIONS["contentrain_media_list"], async (input) => {
|
|
2419
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_list");
|
|
2420
|
+
try {
|
|
2421
|
+
const result = await provider.media.list(input);
|
|
2422
|
+
return ok({
|
|
2423
|
+
assets: result.assets,
|
|
2424
|
+
next_cursor: result.nextCursor,
|
|
2425
|
+
total: result.total
|
|
2426
|
+
});
|
|
2427
|
+
} catch (error) {
|
|
2428
|
+
return mediaError(error, "media_list");
|
|
2429
|
+
}
|
|
2430
|
+
});
|
|
2431
|
+
server.tool("contentrain_media_get", "Get a single media asset by id, including its storage path, delivery URL, and metadata.", { id: z.string().describe("Asset id (from contentrain_media_list)") }, TOOL_ANNOTATIONS["contentrain_media_get"], async (input) => {
|
|
2432
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_get");
|
|
2433
|
+
try {
|
|
2434
|
+
const asset = await provider.media.get(input.id);
|
|
2435
|
+
if (!asset) return {
|
|
2436
|
+
content: [{
|
|
2437
|
+
type: "text",
|
|
2438
|
+
text: JSON.stringify({
|
|
2439
|
+
error: `Media asset not found: ${input.id}`,
|
|
2440
|
+
hint: "Use contentrain_media_list to discover asset ids."
|
|
2441
|
+
})
|
|
2442
|
+
}],
|
|
2443
|
+
isError: true
|
|
2444
|
+
};
|
|
2445
|
+
return ok({ asset });
|
|
2446
|
+
} catch (error) {
|
|
2447
|
+
return mediaError(error, "media_get");
|
|
2448
|
+
}
|
|
2449
|
+
});
|
|
2450
|
+
server.tool("contentrain_media_ingest", "Ingest a media asset from a source URL. The provider fetches the URL server-side under its own SSRF/MIME/size policy and stores the asset in the media stack. Returns the stored asset with its media/... path.", {
|
|
2451
|
+
url: z.string().url().describe("Source URL to fetch server-side"),
|
|
2452
|
+
filename: z.string().optional().describe("Target filename override"),
|
|
2453
|
+
alt: z.string().optional().describe("Alt text for the asset"),
|
|
2454
|
+
tags: z.array(z.string()).max(20).optional().describe("Tags to attach")
|
|
2455
|
+
}, TOOL_ANNOTATIONS["contentrain_media_ingest"], async (input) => {
|
|
2456
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_ingest");
|
|
2457
|
+
try {
|
|
2458
|
+
return ok({
|
|
2459
|
+
status: "ingested",
|
|
2460
|
+
asset: await provider.media.ingest(input)
|
|
2461
|
+
});
|
|
2462
|
+
} catch (error) {
|
|
2463
|
+
return mediaError(error, "media_ingest");
|
|
2464
|
+
}
|
|
2465
|
+
});
|
|
2466
|
+
server.tool("contentrain_media_update", "Update metadata (alt text, tags, filename) of an existing media asset. Does not touch the binary.", {
|
|
2467
|
+
id: z.string().describe("Asset id to update"),
|
|
2468
|
+
alt: z.string().optional().describe("New alt text"),
|
|
2469
|
+
tags: z.array(z.string()).max(20).optional().describe("Replacement tag list"),
|
|
2470
|
+
filename: z.string().optional().describe("New filename")
|
|
2471
|
+
}, TOOL_ANNOTATIONS["contentrain_media_update"], async (input) => {
|
|
2472
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_update");
|
|
2473
|
+
try {
|
|
2474
|
+
const { id, ...patch } = input;
|
|
2475
|
+
return ok({
|
|
2476
|
+
status: "updated",
|
|
2477
|
+
asset: await provider.media.update(id, patch)
|
|
2478
|
+
});
|
|
2479
|
+
} catch (error) {
|
|
2480
|
+
return mediaError(error, "media_update");
|
|
2481
|
+
}
|
|
2482
|
+
});
|
|
2483
|
+
server.tool("contentrain_media_delete", "Delete a media asset from the media stack. Content entries referencing its path are NOT rewritten — check references before deleting.", {
|
|
2484
|
+
id: z.string().describe("Asset id to delete"),
|
|
2485
|
+
confirm: z.literal(true).describe("Must be true to confirm deletion")
|
|
2486
|
+
}, TOOL_ANNOTATIONS["contentrain_media_delete"], async (input) => {
|
|
2487
|
+
if (!provider.media) return mediaUnavailable("contentrain_media_delete");
|
|
2488
|
+
try {
|
|
2489
|
+
await provider.media.delete(input.id);
|
|
2490
|
+
return ok({
|
|
2491
|
+
status: "deleted",
|
|
2492
|
+
id: input.id
|
|
2493
|
+
});
|
|
2494
|
+
} catch (error) {
|
|
2495
|
+
return mediaError(error, "media_delete");
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2498
|
+
}
|
|
2499
|
+
//#endregion
|
|
2371
2500
|
//#region package.json
|
|
2372
|
-
var version = "1.
|
|
2501
|
+
var version = "1.10.1";
|
|
2373
2502
|
//#endregion
|
|
2374
2503
|
//#region src/server.ts
|
|
2375
2504
|
/**
|
|
@@ -2410,6 +2539,7 @@ function createServer(input) {
|
|
|
2410
2539
|
registerNormalizeTools(server, provider, projectRoot);
|
|
2411
2540
|
registerBulkTools(server, provider, projectRoot);
|
|
2412
2541
|
registerDoctorTools(server, provider, projectRoot);
|
|
2542
|
+
registerMediaTools(server, provider, projectRoot);
|
|
2413
2543
|
return server;
|
|
2414
2544
|
}
|
|
2415
2545
|
function resolveServerContext(input) {
|
|
@@ -2438,4 +2568,4 @@ function resolveServerContext(input) {
|
|
|
2438
2568
|
//#endregion
|
|
2439
2569
|
export { createServer as n, DEFAULT_INSTRUCTIONS as t };
|
|
2440
2570
|
|
|
2441
|
-
//# sourceMappingURL=server-
|
|
2571
|
+
//# sourceMappingURL=server-BkDuFvVt.mjs.map
|