@arpproject/vibearp-mcp 1.2.0 → 1.3.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 +3 -1
- package/lib/dashboard/static/dashboard.js +5 -5
- package/lib/dashboard/static/index.html +3 -3
- package/lib/server.js +80 -104
- package/lib/server.js.map +4 -4
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# VibeARP MCP Server
|
|
2
2
|
|
|
3
|
-
`@arpproject/
|
|
3
|
+
`@arpproject/vibarp-mcp` is an [MCP server](https://www.dreamfactory.com/use-cases/mcp-server/) for [RO-Crate](https://www.researchobject.org/ro-crate/) editing, validation, and profile-aware constraints following the best practices of the ARP project (https://researchdata.hu/). It is designed for MCP-compatible AI assistants such as Codex and Claude Code. It can use metadata profiles and remote CEDAR templates offered by the ARP profile repository (https://cedar.schema.researchdata.hu/).
|
|
4
4
|
|
|
5
5
|
[Quick start](#quick-start) · [Első lépések](#első-lépések)
|
|
6
6
|
|
|
@@ -150,6 +150,8 @@ engedélyezett hozzáféréssel rendelkezik.
|
|
|
150
150
|
This package is maintained by SZTAKI, Department of Distributed Systems
|
|
151
151
|
(<https://dsd.sztaki.hu>).
|
|
152
152
|
|
|
153
|
+
Contact: [rockit@dsd.sztaki.hu](mailto:rockit@dsd.sztaki.hu).
|
|
154
|
+
|
|
153
155
|
Individual contributors are listed in `package.json`.
|
|
154
156
|
|
|
155
157
|
## License
|
|
@@ -99,9 +99,9 @@ const huTranslations = {
|
|
|
99
99
|
'Cancel': 'Mégse',
|
|
100
100
|
'Name': 'Név',
|
|
101
101
|
'Reload': 'Újratöltés',
|
|
102
|
-
'
|
|
102
|
+
'Metadata Profiles': 'Metadataprofilok',
|
|
103
103
|
'Browse remote CEDAR repositories and manage locally converted recrate profiles.': 'Távoli CEDAR-tárolók böngészése és a helyben átalakított ReCrate-profilok kezelése.',
|
|
104
|
-
'Browse Remote': 'Távoli
|
|
104
|
+
'Browse Remote': 'Távoli profilok böngészése',
|
|
105
105
|
'Storage': 'Tárolási hely',
|
|
106
106
|
'Version': 'Verzió',
|
|
107
107
|
'Source': 'Forrás',
|
|
@@ -110,11 +110,11 @@ const huTranslations = {
|
|
|
110
110
|
'Import URL': 'Importálás URL-ről',
|
|
111
111
|
'Select Remote Provider': 'Távoli szolgáltató kiválasztása',
|
|
112
112
|
'Choose Repository': 'Tároló kiválasztása',
|
|
113
|
-
'Select a remote provider to browse
|
|
113
|
+
'Select a remote provider to browse profiles.': 'Válasszon távoli szolgáltatót a profilok böngészéséhez.',
|
|
114
114
|
'Manage Providers...': 'Szolgáltatók kezelése…',
|
|
115
115
|
'Manage Remote Providers': 'Távoli szolgáltatók kezelése',
|
|
116
116
|
'Configured Providers': 'Beállított szolgáltatók',
|
|
117
|
-
'Manage connections to remote
|
|
117
|
+
'Manage connections to remote profile providers.': 'Távoli profil-szolgáltatók kapcsolatainak kezelése.',
|
|
118
118
|
'Add Provider': 'Szolgáltató hozzáadása',
|
|
119
119
|
'Dataverse proxy (read-only)': 'Dataverse proxy (csak olvasható)',
|
|
120
120
|
'CEDAR API key': 'CEDAR API-kulcs',
|
|
@@ -125,7 +125,7 @@ const huTranslations = {
|
|
|
125
125
|
'Collapse All': 'Összes összecsukása',
|
|
126
126
|
'Locate in Tree': 'Megkeresés a fában',
|
|
127
127
|
'Deselect': 'Kijelölés megszüntetése',
|
|
128
|
-
'Select a template to import...': 'Válasszon importálandó
|
|
128
|
+
'Select a template to import...': 'Válasszon importálandó sablont…',
|
|
129
129
|
'Add': 'Hozzáadás',
|
|
130
130
|
'Previous page': 'Előző oldal',
|
|
131
131
|
'Next page': 'Következő oldal',
|
|
@@ -382,7 +382,7 @@
|
|
|
382
382
|
<div class="profiles-modal-body">
|
|
383
383
|
<div class="profiles-toolbar">
|
|
384
384
|
<div>
|
|
385
|
-
<h3>
|
|
385
|
+
<h3>Metadata Profiles</h3>
|
|
386
386
|
<p class="setting-description">Browse remote CEDAR repositories and manage locally converted recrate profiles.</p>
|
|
387
387
|
</div>
|
|
388
388
|
<div class="profiles-toolbar-actions">
|
|
@@ -455,7 +455,7 @@
|
|
|
455
455
|
<div class="provider-dialog-icon provider-server-icon"></div>
|
|
456
456
|
<div>
|
|
457
457
|
<h3>Choose Repository</h3>
|
|
458
|
-
<p class="setting-description">Select a remote provider to browse
|
|
458
|
+
<p class="setting-description">Select a remote provider to browse profiles.</p>
|
|
459
459
|
</div>
|
|
460
460
|
</div>
|
|
461
461
|
<div id="remoteProviderSelectList" class="provider-select-list">
|
|
@@ -484,7 +484,7 @@
|
|
|
484
484
|
<div class="provider-dialog-icon provider-sliders-icon"><span></span><span></span><span></span></div>
|
|
485
485
|
<div>
|
|
486
486
|
<h3>Configured Providers</h3>
|
|
487
|
-
<p class="setting-description">Manage connections to remote
|
|
487
|
+
<p class="setting-description">Manage connections to remote profile providers.</p>
|
|
488
488
|
</div>
|
|
489
489
|
</div>
|
|
490
490
|
<button type="button" class="btn btn-primary" id="addRemoteProviderBtn">
|
package/lib/server.js
CHANGED
|
@@ -29,9 +29,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
mod
|
|
30
30
|
));
|
|
31
31
|
|
|
32
|
-
//
|
|
32
|
+
// ../../node_modules/mime-types/node_modules/mime-db/db.json
|
|
33
33
|
var require_db = __commonJS({
|
|
34
|
-
"
|
|
34
|
+
"../../node_modules/mime-types/node_modules/mime-db/db.json"(exports2, module2) {
|
|
35
35
|
module2.exports = {
|
|
36
36
|
"application/1d-interleaved-parityfec": {
|
|
37
37
|
source: "iana"
|
|
@@ -8554,16 +8554,16 @@ var require_db = __commonJS({
|
|
|
8554
8554
|
}
|
|
8555
8555
|
});
|
|
8556
8556
|
|
|
8557
|
-
//
|
|
8557
|
+
// ../../node_modules/mime-types/node_modules/mime-db/index.js
|
|
8558
8558
|
var require_mime_db = __commonJS({
|
|
8559
|
-
"
|
|
8559
|
+
"../../node_modules/mime-types/node_modules/mime-db/index.js"(exports2, module2) {
|
|
8560
8560
|
module2.exports = require_db();
|
|
8561
8561
|
}
|
|
8562
8562
|
});
|
|
8563
8563
|
|
|
8564
|
-
//
|
|
8564
|
+
// ../../node_modules/mime-types/index.js
|
|
8565
8565
|
var require_mime_types = __commonJS({
|
|
8566
|
-
"
|
|
8566
|
+
"../../node_modules/mime-types/index.js"(exports2) {
|
|
8567
8567
|
"use strict";
|
|
8568
8568
|
var db = require_mime_db();
|
|
8569
8569
|
var extname2 = require("path").extname;
|
|
@@ -36638,15 +36638,15 @@ var require_lib2 = __commonJS({
|
|
|
36638
36638
|
"../metadata-profile-core/lib/index.js"(exports2) {
|
|
36639
36639
|
"use strict";
|
|
36640
36640
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
36641
|
-
exports2.deriveDataverseProxyBaseUrl = exports2.isCedarLikeUrl = exports2.deriveConformsToFromId = exports2.deleteCedarProvider = exports2.saveCedarProvider = exports2.loadCedarProviders = exports2.defaultCedarProviders = exports2.defaultCedarProvider = exports2.deleteMetadataProfile = exports2.
|
|
36641
|
+
exports2.deriveDataverseProxyBaseUrl = exports2.isCedarLikeUrl = exports2.deriveConformsToFromId = exports2.deleteCedarProvider = exports2.saveCedarProvider = exports2.loadCedarProviders = exports2.defaultCedarProviders = exports2.defaultCedarProvider = exports2.deleteMetadataProfile = exports2.importRemoteTemplate = exports2.listCedarFolder = exports2.getCedarPublicFolderId = exports2.listRemoteTemplates = exports2.resolveMissingConformsToUrls = exports2.importCedarTemplateFromUrl = exports2.importCedarTemplateContent = exports2.listLocalProfiles = exports2.rebuildConformsToIndex = exports2.saveProfileIndex = exports2.loadProfileIndex = exports2.ensureProfileStorage = exports2.resolveProfileStorage = exports2.resolveProfileRootPath = void 0;
|
|
36642
36642
|
var crypto2 = require("node:crypto");
|
|
36643
36643
|
var fs14 = require("node:fs");
|
|
36644
36644
|
var os3 = require("node:os");
|
|
36645
36645
|
var path13 = require("node:path");
|
|
36646
36646
|
var schema_url_resolution_1 = require_schema_url_resolution();
|
|
36647
|
-
var DEFAULT_INDEX_FILENAME = "metadata-
|
|
36648
|
-
var DEFAULT_REMOTE_PROVIDER_CONFIG_FILENAME = "remote-
|
|
36649
|
-
var DEFAULT_REMOTE_PROVIDER_KEYTAR_SERVICE = "RocKIT.
|
|
36647
|
+
var DEFAULT_INDEX_FILENAME = "metadata-profile-index.json";
|
|
36648
|
+
var DEFAULT_REMOTE_PROVIDER_CONFIG_FILENAME = "remote-profile-providers.json";
|
|
36649
|
+
var DEFAULT_REMOTE_PROVIDER_KEYTAR_SERVICE = "RocKIT.RemoteProfileProvider";
|
|
36650
36650
|
var DEFAULT_ARP_PROD_PREFIX = "https://repo.schema.researchdata.hu/templates/";
|
|
36651
36651
|
var DEFAULT_ARP_DEV_PREFIX = "https://repo.cedardev.dsd.sztaki.hu/templates/";
|
|
36652
36652
|
var DEFAULT_ARP_W3ID_PROD = "https://w3id.org/arp/schema/";
|
|
@@ -36662,7 +36662,7 @@ var require_lib2 = __commonJS({
|
|
|
36662
36662
|
return void 0;
|
|
36663
36663
|
}
|
|
36664
36664
|
function resolveProfileRootPath6(rootPath) {
|
|
36665
|
-
const configured = rootPath?.trim() || readConfiguredEnv("ROCKIT_ROOT_PATH"
|
|
36665
|
+
const configured = rootPath?.trim() || readConfiguredEnv("ROCKIT_ROOT_PATH");
|
|
36666
36666
|
if (configured && configured.trim() !== "") {
|
|
36667
36667
|
return path13.resolve(configured);
|
|
36668
36668
|
}
|
|
@@ -36671,12 +36671,12 @@ var require_lib2 = __commonJS({
|
|
|
36671
36671
|
exports2.resolveProfileRootPath = resolveProfileRootPath6;
|
|
36672
36672
|
function resolveProfileStorage3(rootPath) {
|
|
36673
36673
|
const root = resolveProfileRootPath6(rootPath);
|
|
36674
|
-
const indexFile = readConfiguredEnv("
|
|
36674
|
+
const indexFile = readConfiguredEnv("ROCKIT_METADATA_PROFILE_INDEX_FILE");
|
|
36675
36675
|
const indexPath = indexFile && indexFile.trim() !== "" ? path13.isAbsolute(indexFile) ? indexFile : path13.join(root, indexFile) : path13.join(root, DEFAULT_INDEX_FILENAME);
|
|
36676
36676
|
return {
|
|
36677
36677
|
rootPath: root,
|
|
36678
|
-
cedarDir: path13.join(root, "metadata-
|
|
36679
|
-
roCrateDir: path13.join(root, "metadata-
|
|
36678
|
+
cedarDir: path13.join(root, "metadata-profiles", "cedar"),
|
|
36679
|
+
roCrateDir: path13.join(root, "metadata-profiles", "ro-crate"),
|
|
36680
36680
|
indexPath
|
|
36681
36681
|
};
|
|
36682
36682
|
}
|
|
@@ -36770,9 +36770,9 @@ var require_lib2 = __commonJS({
|
|
|
36770
36770
|
const hash = createShortHash(`${schemaId}:${source}`);
|
|
36771
36771
|
const safeName = schemaName.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
36772
36772
|
const fileName = `${safeName || "cedar_schema"}_v${schemaVersion}_${source}_${hash}.json`;
|
|
36773
|
-
const sourcePath = `metadata-
|
|
36774
|
-
const convertedPath = `metadata-
|
|
36775
|
-
const hungarianConvertedPath = `metadata-
|
|
36773
|
+
const sourcePath = `metadata-profiles/cedar/${fileName}`;
|
|
36774
|
+
const convertedPath = `metadata-profiles/ro-crate/${fileName}`;
|
|
36775
|
+
const hungarianConvertedPath = `metadata-profiles/ro-crate/hu/${fileName}`;
|
|
36776
36776
|
const absoluteSourcePath = path13.join(storage.rootPath, sourcePath);
|
|
36777
36777
|
const absoluteConvertedPath = path13.join(storage.rootPath, convertedPath);
|
|
36778
36778
|
const absoluteHungarianConvertedPath = path13.join(storage.rootPath, hungarianConvertedPath);
|
|
@@ -36859,7 +36859,7 @@ var require_lib2 = __commonJS({
|
|
|
36859
36859
|
return { storage, imported, unresolvedUrls, warnings };
|
|
36860
36860
|
}
|
|
36861
36861
|
exports2.resolveMissingConformsToUrls = resolveMissingConformsToUrls2;
|
|
36862
|
-
async function
|
|
36862
|
+
async function listRemoteTemplates3(provider = defaultCedarProvider3(), query, rootPath) {
|
|
36863
36863
|
const normalizedProvider = normalizeProvider(provider);
|
|
36864
36864
|
const folderId = normalizedProvider.registryFolderId ?? DEFAULT_REGISTRY_FOLDER;
|
|
36865
36865
|
const url = `${resourceBaseUrl(normalizedProvider)}/folders/${encodeURIComponent(folderId)}/contents?limit=100&offset=0&publication_status=all&resource_types=template,folder&sort=name&version=all`;
|
|
@@ -36867,7 +36867,7 @@ var require_lib2 = __commonJS({
|
|
|
36867
36867
|
const resources = Array.isArray(fetched.resources) ? fetched.resources : [];
|
|
36868
36868
|
const local = listLocalProfiles3(rootPath);
|
|
36869
36869
|
const needle = query?.trim().toLowerCase();
|
|
36870
|
-
const
|
|
36870
|
+
const templates = resources.filter((item) => {
|
|
36871
36871
|
return Boolean(item) && typeof item === "object" && !Array.isArray(item);
|
|
36872
36872
|
}).filter((item) => item.resourceType === "template" || readString(item["@type"])?.includes("Template")).map((item) => remoteSchemaSummary(item, normalizedProvider, local.profiles)).filter((item) => {
|
|
36873
36873
|
if (!needle) {
|
|
@@ -36875,9 +36875,13 @@ var require_lib2 = __commonJS({
|
|
|
36875
36875
|
}
|
|
36876
36876
|
return item.name.toLowerCase().includes(needle) || item.templateUrl.toLowerCase().includes(needle) || item.conformsTo.toLowerCase().includes(needle);
|
|
36877
36877
|
});
|
|
36878
|
-
return {
|
|
36878
|
+
return {
|
|
36879
|
+
provider: normalizedProvider,
|
|
36880
|
+
templates,
|
|
36881
|
+
storage: local.storage
|
|
36882
|
+
};
|
|
36879
36883
|
}
|
|
36880
|
-
exports2.
|
|
36884
|
+
exports2.listRemoteTemplates = listRemoteTemplates3;
|
|
36881
36885
|
async function getCedarPublicFolderId(provider = defaultCedarProvider3()) {
|
|
36882
36886
|
const normalizedProvider = normalizeProvider(provider);
|
|
36883
36887
|
const url = `${resourceBaseUrl(normalizedProvider)}/search?sharing=shared-with-everybody&publication_status=all&q=public&resource_types=folder&version=all`;
|
|
@@ -36910,7 +36914,7 @@ var require_lib2 = __commonJS({
|
|
|
36910
36914
|
};
|
|
36911
36915
|
}
|
|
36912
36916
|
exports2.listCedarFolder = listCedarFolder3;
|
|
36913
|
-
async function
|
|
36917
|
+
async function importRemoteTemplate3(args) {
|
|
36914
36918
|
const provider = normalizeProvider(args.provider ?? defaultCedarProvider3());
|
|
36915
36919
|
return importCedarTemplateFromUrl3({
|
|
36916
36920
|
url: args.templateIdOrUrl,
|
|
@@ -36919,7 +36923,7 @@ var require_lib2 = __commonJS({
|
|
|
36919
36923
|
conformsTo: args.conformsTo
|
|
36920
36924
|
});
|
|
36921
36925
|
}
|
|
36922
|
-
exports2.
|
|
36926
|
+
exports2.importRemoteTemplate = importRemoteTemplate3;
|
|
36923
36927
|
async function deleteMetadataProfile3(args) {
|
|
36924
36928
|
const storage = ensureProfileStorage2(args.rootPath);
|
|
36925
36929
|
const index = loadProfileIndex(args.rootPath);
|
|
@@ -36965,8 +36969,8 @@ var require_lib2 = __commonJS({
|
|
|
36965
36969
|
exports2.defaultCedarProviders = defaultCedarProviders2;
|
|
36966
36970
|
async function loadCedarProviders3(rootPath) {
|
|
36967
36971
|
const storage = ensureProfileStorage2(rootPath);
|
|
36968
|
-
const configFileName = readConfiguredEnv("
|
|
36969
|
-
const keytarService = readConfiguredEnv("
|
|
36972
|
+
const configFileName = readConfiguredEnv("ROCKIT_REMOTE_PROFILE_PROVIDER_CONFIG_FILE") || DEFAULT_REMOTE_PROVIDER_CONFIG_FILENAME;
|
|
36973
|
+
const keytarService = readConfiguredEnv("ROCKIT_REMOTE_PROFILE_PROVIDER_KEYTAR_SERVICE") || DEFAULT_REMOTE_PROVIDER_KEYTAR_SERVICE;
|
|
36970
36974
|
const configPath = path13.isAbsolute(configFileName) ? configFileName : path13.join(storage.rootPath, configFileName);
|
|
36971
36975
|
const warnings = [];
|
|
36972
36976
|
let configuredProviders = [];
|
|
@@ -37068,10 +37072,6 @@ var require_lib2 = __commonJS({
|
|
|
37068
37072
|
const attempted = /* @__PURE__ */ new Set();
|
|
37069
37073
|
const queue = [];
|
|
37070
37074
|
enqueueSchemaFetchCandidates(queue, attempted, inputUrl, rankSchemaResolveProviders(inputUrl, configuredProviders, provider ? normalizeProvider(provider) : void 0));
|
|
37071
|
-
logSchemaResolve("start", {
|
|
37072
|
-
inputUrl,
|
|
37073
|
-
providers: rankSchemaResolveProviders(inputUrl, configuredProviders, provider ? normalizeProvider(provider) : void 0).map((candidateProvider) => schemaResolveProviderLabel(candidateProvider))
|
|
37074
|
-
});
|
|
37075
37075
|
let lastError;
|
|
37076
37076
|
while (queue.length > 0) {
|
|
37077
37077
|
const entry = queue.shift();
|
|
@@ -37080,32 +37080,18 @@ var require_lib2 = __commonJS({
|
|
|
37080
37080
|
continue;
|
|
37081
37081
|
}
|
|
37082
37082
|
attempted.add(attemptKey);
|
|
37083
|
-
logSchemaResolve("attempt", describeSchemaResolveEntry(entry));
|
|
37084
37083
|
try {
|
|
37085
37084
|
const response = await fetchWithOptionalAuth(entry.candidate, entry.provider);
|
|
37086
37085
|
const content = await response.text();
|
|
37087
37086
|
try {
|
|
37088
37087
|
JSON.parse(content);
|
|
37089
|
-
logSchemaResolve("success", {
|
|
37090
|
-
...describeSchemaResolveEntry(entry),
|
|
37091
|
-
finalUrl: response.url
|
|
37092
|
-
});
|
|
37093
37088
|
return { content, finalUrl: response.url };
|
|
37094
37089
|
} catch {
|
|
37095
37090
|
lastError = new Error(`The URL ${entry.candidate} resolved to non-JSON content at ${response.url}.`);
|
|
37096
37091
|
const redirectProviders = rankSchemaResolveProviders(response.url, configuredProviders, entry.provider);
|
|
37097
37092
|
enqueueRedirectCandidates(queue, attempted, response.url, redirectProviders);
|
|
37098
|
-
logSchemaResolve("non-json", {
|
|
37099
|
-
...describeSchemaResolveEntry(entry),
|
|
37100
|
-
finalUrl: response.url,
|
|
37101
|
-
nextProviders: redirectProviders.map((candidateProvider) => schemaResolveProviderLabel(candidateProvider))
|
|
37102
|
-
});
|
|
37103
37093
|
}
|
|
37104
37094
|
} catch (error2) {
|
|
37105
|
-
logSchemaResolve("error", {
|
|
37106
|
-
...describeSchemaResolveEntry(entry),
|
|
37107
|
-
error: error2 instanceof Error ? error2.message : String(error2)
|
|
37108
|
-
});
|
|
37109
37095
|
lastError = error2;
|
|
37110
37096
|
}
|
|
37111
37097
|
}
|
|
@@ -37170,23 +37156,6 @@ var require_lib2 = __commonJS({
|
|
|
37170
37156
|
function schemaResolveProviderKey(provider) {
|
|
37171
37157
|
return provider.id || provider.domainBase || provider.baseUrl || provider.resourceBaseUrl || "provider";
|
|
37172
37158
|
}
|
|
37173
|
-
function schemaResolveProviderLabel(provider) {
|
|
37174
|
-
return provider.title || provider.id || provider.domainBase || provider.baseUrl || "provider";
|
|
37175
|
-
}
|
|
37176
|
-
function describeSchemaResolveEntry(entry) {
|
|
37177
|
-
return {
|
|
37178
|
-
candidate: entry.candidate,
|
|
37179
|
-
provider: schemaResolveProviderLabel(entry.provider),
|
|
37180
|
-
proxyUrl: effectiveProviderAccessMode(entry.provider) === "dataverseProxy" ? effectiveCedarFetchUrl(entry.candidate, entry.provider) : ""
|
|
37181
|
-
};
|
|
37182
|
-
}
|
|
37183
|
-
function logSchemaResolve(message, details) {
|
|
37184
|
-
if (details === void 0) {
|
|
37185
|
-
console.info("[SchemaResolve]", message);
|
|
37186
|
-
return;
|
|
37187
|
-
}
|
|
37188
|
-
console.info("[SchemaResolve]", message, details);
|
|
37189
|
-
}
|
|
37190
37159
|
async function fetchJsonWithAuthFallback(url, provider) {
|
|
37191
37160
|
const response = await fetchWithOptionalAuth(url, provider);
|
|
37192
37161
|
return response.json();
|
|
@@ -37306,7 +37275,7 @@ var require_lib2 = __commonJS({
|
|
|
37306
37275
|
writeJsonAtomic2(configPath, safeProviders, 4);
|
|
37307
37276
|
}
|
|
37308
37277
|
function ensureDefaultCedarProviderConfig(rootPath) {
|
|
37309
|
-
const configFileName = readConfiguredEnv("
|
|
37278
|
+
const configFileName = readConfiguredEnv("ROCKIT_REMOTE_PROFILE_PROVIDER_CONFIG_FILE") || DEFAULT_REMOTE_PROVIDER_CONFIG_FILENAME;
|
|
37310
37279
|
const configPath = path13.isAbsolute(configFileName) ? configFileName : path13.join(rootPath, configFileName);
|
|
37311
37280
|
if (!fs14.existsSync(configPath)) {
|
|
37312
37281
|
writeConfiguredCedarProvidersSync(defaultCedarProviders2(), configPath);
|
|
@@ -47404,7 +47373,7 @@ var DashboardApiHandlers = class {
|
|
|
47404
47373
|
try {
|
|
47405
47374
|
const query = parseQuery(req.url || "");
|
|
47406
47375
|
const provider = await this.resolveMetadataProfileProvider(query.providerId);
|
|
47407
|
-
const result = await (0, import_metadata_profile_core2.
|
|
47376
|
+
const result = await (0, import_metadata_profile_core2.listRemoteTemplates)(
|
|
47408
47377
|
provider,
|
|
47409
47378
|
query.query,
|
|
47410
47379
|
(0, import_metadata_profile_core2.resolveProfileRootPath)()
|
|
@@ -47412,8 +47381,8 @@ var DashboardApiHandlers = class {
|
|
|
47412
47381
|
sendJson(res, {
|
|
47413
47382
|
provider: redactMetadataProfileProvider(result.provider),
|
|
47414
47383
|
storage: result.storage,
|
|
47415
|
-
count: result.
|
|
47416
|
-
schemas: result.
|
|
47384
|
+
count: result.templates.length,
|
|
47385
|
+
schemas: result.templates
|
|
47417
47386
|
});
|
|
47418
47387
|
} catch (error2) {
|
|
47419
47388
|
const message = error2 instanceof Error ? error2.message : String(error2);
|
|
@@ -47473,7 +47442,7 @@ var DashboardApiHandlers = class {
|
|
|
47473
47442
|
if (templateIdOrUrl === "") {
|
|
47474
47443
|
throw new Error("templateIdOrUrl is required.");
|
|
47475
47444
|
}
|
|
47476
|
-
const result = await (0, import_metadata_profile_core2.
|
|
47445
|
+
const result = await (0, import_metadata_profile_core2.importRemoteTemplate)({
|
|
47477
47446
|
templateIdOrUrl,
|
|
47478
47447
|
rootPath: (0, import_metadata_profile_core2.resolveProfileRootPath)(),
|
|
47479
47448
|
provider: parseMetadataProfileProvider(body.provider) ?? await this.resolveMetadataProfileProvider(readProviderId(body.providerId)),
|
|
@@ -49863,12 +49832,12 @@ function createMetadataProfileHandlers(deps) {
|
|
|
49863
49832
|
async function listWellKnownSchemas2(params) {
|
|
49864
49833
|
const provider = await resolveProvider(params);
|
|
49865
49834
|
const query = typeof params.query === "string" ? params.query : void 0;
|
|
49866
|
-
const result = await (0, import_metadata_profile_core3.
|
|
49835
|
+
const result = await (0, import_metadata_profile_core3.listRemoteTemplates)(provider, query, parseRootPath(params));
|
|
49867
49836
|
return {
|
|
49868
49837
|
provider: result.provider,
|
|
49869
49838
|
storage: result.storage,
|
|
49870
|
-
count: result.
|
|
49871
|
-
schemas: result.
|
|
49839
|
+
count: result.templates.length,
|
|
49840
|
+
schemas: result.templates
|
|
49872
49841
|
};
|
|
49873
49842
|
}
|
|
49874
49843
|
async function listRemoteSchemaTree2(params) {
|
|
@@ -49959,7 +49928,7 @@ function createMetadataProfileHandlers(deps) {
|
|
|
49959
49928
|
skippedImported,
|
|
49960
49929
|
count: visited,
|
|
49961
49930
|
tree: tree.nodes,
|
|
49962
|
-
note: "Only unimported template leaves are listed. Import a selected template by calling
|
|
49931
|
+
note: "Only unimported template leaves are listed. Import a selected template by calling import_remote_template with templateIdOrUrl=<templateId>, then associate profile.conformsTo with update_profile_conforms_to(write=true)."
|
|
49963
49932
|
};
|
|
49964
49933
|
}
|
|
49965
49934
|
async function importWellKnownSchema2(params) {
|
|
@@ -49968,16 +49937,16 @@ function createMetadataProfileHandlers(deps) {
|
|
|
49968
49937
|
if (templateIdOrUrl === "" && typeof params.name === "string") {
|
|
49969
49938
|
const query = params.name.trim();
|
|
49970
49939
|
if (query !== "") {
|
|
49971
|
-
const remote = await (0, import_metadata_profile_core3.
|
|
49940
|
+
const remote = await (0, import_metadata_profile_core3.listRemoteTemplates)(provider, query, parseRootPath(params));
|
|
49972
49941
|
const lower = query.toLowerCase();
|
|
49973
|
-
const match = remote.
|
|
49942
|
+
const match = remote.templates.find((template) => template.name.toLowerCase() === lower) ?? remote.templates[0];
|
|
49974
49943
|
templateIdOrUrl = match?.templateUrl ?? "";
|
|
49975
49944
|
}
|
|
49976
49945
|
}
|
|
49977
49946
|
if (templateIdOrUrl === "") {
|
|
49978
|
-
throw new Error("
|
|
49947
|
+
throw new Error("import_remote_template requires name, templateIdOrUrl, url, or conformsTo.");
|
|
49979
49948
|
}
|
|
49980
|
-
const result = await (0, import_metadata_profile_core3.
|
|
49949
|
+
const result = await (0, import_metadata_profile_core3.importRemoteTemplate)({
|
|
49981
49950
|
provider,
|
|
49982
49951
|
templateIdOrUrl,
|
|
49983
49952
|
rootPath: parseRootPath(params),
|
|
@@ -50444,7 +50413,7 @@ function createProfileResolutionHelpers(deps) {
|
|
|
50444
50413
|
index: { profiles: [], conformsToIndex: {} },
|
|
50445
50414
|
indexPath,
|
|
50446
50415
|
rootPath,
|
|
50447
|
-
warning: `
|
|
50416
|
+
warning: `Profile index file not found: ${indexPath}`
|
|
50448
50417
|
};
|
|
50449
50418
|
}
|
|
50450
50419
|
try {
|
|
@@ -50461,7 +50430,7 @@ function createProfileResolutionHelpers(deps) {
|
|
|
50461
50430
|
index: { profiles: [], conformsToIndex: {} },
|
|
50462
50431
|
indexPath,
|
|
50463
50432
|
rootPath,
|
|
50464
|
-
warning: `Failed to parse
|
|
50433
|
+
warning: `Failed to parse profile index: ${message}`
|
|
50465
50434
|
};
|
|
50466
50435
|
}
|
|
50467
50436
|
}
|
|
@@ -50479,7 +50448,7 @@ function createProfileResolutionHelpers(deps) {
|
|
|
50479
50448
|
loaded: false
|
|
50480
50449
|
};
|
|
50481
50450
|
if (!absoluteConvertedPath) {
|
|
50482
|
-
resolved.loadError = "Missing files.convertedPath in
|
|
50451
|
+
resolved.loadError = "Missing files.convertedPath in profile index entry.";
|
|
50483
50452
|
return resolved;
|
|
50484
50453
|
}
|
|
50485
50454
|
if (!fs10.existsSync(absoluteConvertedPath)) {
|
|
@@ -50515,7 +50484,7 @@ function createProfileResolutionHelpers(deps) {
|
|
|
50515
50484
|
unresolvedUrls: profileUrls,
|
|
50516
50485
|
profiles: [],
|
|
50517
50486
|
warnings: profileUrls.length > 0 ? [
|
|
50518
|
-
"Remote mode profile resolution requires caller-supplied
|
|
50487
|
+
"Remote mode profile resolution requires caller-supplied profile index/profile content."
|
|
50519
50488
|
] : []
|
|
50520
50489
|
};
|
|
50521
50490
|
}
|
|
@@ -51378,7 +51347,7 @@ function createProfileValidationHelpers(deps) {
|
|
|
51378
51347
|
continue;
|
|
51379
51348
|
}
|
|
51380
51349
|
warnings.push(
|
|
51381
|
-
`Entity ${entityId} contains custom property outside active profile
|
|
51350
|
+
`Entity ${entityId} contains custom property outside active profile rules: ${key}. Keep it if the user wants this metadata; do not remove it automatically.`
|
|
51382
51351
|
);
|
|
51383
51352
|
}
|
|
51384
51353
|
const valueSetsByProperty = /* @__PURE__ */ new Map();
|
|
@@ -52155,8 +52124,8 @@ var tools = [
|
|
|
52155
52124
|
}
|
|
52156
52125
|
},
|
|
52157
52126
|
{
|
|
52158
|
-
name: "
|
|
52159
|
-
description: "Browse/search configured
|
|
52127
|
+
name: "list_remote_templates",
|
|
52128
|
+
description: "Browse/search configured profile providers for well-known Dataverse metadata profiles.",
|
|
52160
52129
|
inputSchema: {
|
|
52161
52130
|
type: "object",
|
|
52162
52131
|
properties: {
|
|
@@ -52170,7 +52139,7 @@ var tools = [
|
|
|
52170
52139
|
}
|
|
52171
52140
|
},
|
|
52172
52141
|
{
|
|
52173
|
-
name: "
|
|
52142
|
+
name: "list_remote_template_tree",
|
|
52174
52143
|
description: "Browse configured CEDAR providers as a folder tree and list only unimported template leaves for profile selection.",
|
|
52175
52144
|
inputSchema: {
|
|
52176
52145
|
type: "object",
|
|
@@ -52196,8 +52165,8 @@ var tools = [
|
|
|
52196
52165
|
}
|
|
52197
52166
|
},
|
|
52198
52167
|
{
|
|
52199
|
-
name: "
|
|
52200
|
-
description: "Import a well-known
|
|
52168
|
+
name: "import_remote_template",
|
|
52169
|
+
description: "Import a well-known metadata profile by name/template URL/conformsTo into the shared metadata profile store.",
|
|
52201
52170
|
inputSchema: {
|
|
52202
52171
|
type: "object",
|
|
52203
52172
|
properties: {
|
|
@@ -52215,7 +52184,7 @@ var tools = [
|
|
|
52215
52184
|
},
|
|
52216
52185
|
{
|
|
52217
52186
|
name: "list_metadata_profiles",
|
|
52218
|
-
description: "List persisted CEDAR/recrate metadata profiles from the shared metadata-
|
|
52187
|
+
description: "List persisted CEDAR/recrate metadata profiles from the shared metadata-profile-index.json store.",
|
|
52219
52188
|
inputSchema: {
|
|
52220
52189
|
type: "object",
|
|
52221
52190
|
properties: {
|
|
@@ -52689,7 +52658,7 @@ var tools = [
|
|
|
52689
52658
|
}
|
|
52690
52659
|
},
|
|
52691
52660
|
{
|
|
52692
|
-
name: "
|
|
52661
|
+
name: "resolve_metadata_profile",
|
|
52693
52662
|
description: "Resolve profile URL to profile records and converted profile file paths via metadata-schema-index.",
|
|
52694
52663
|
inputSchema: {
|
|
52695
52664
|
type: "object",
|
|
@@ -52783,6 +52752,11 @@ You are editing an RO-Crate as a data steward.
|
|
|
52783
52752
|
|
|
52784
52753
|
## Mandatory Startup
|
|
52785
52754
|
|
|
52755
|
+
The configured RO-Crate MCP server's call names are "RO-Crate MCP" and
|
|
52756
|
+
"VibeARP". When a user says either name, use the configured server's tools even
|
|
52757
|
+
if the harness displays a different server label (commonly \`rocrate\` or
|
|
52758
|
+
\`rocrate-mcp-server\`).
|
|
52759
|
+
|
|
52786
52760
|
Before advising on or editing RO-Crate metadata, read this top-level workflow doc
|
|
52787
52761
|
with \`read_agent_workflow_doc\`. Then read the step-specific workflow doc before
|
|
52788
52762
|
each step.
|
|
@@ -52857,7 +52831,7 @@ When generating the review URL:
|
|
|
52857
52831
|
|
|
52858
52832
|
1. Try to solve the user's task in one coherent pass.
|
|
52859
52833
|
2. If you need a decision from the user, provide a short menu they can choose from.
|
|
52860
|
-
3. For RO-Crate metadata authoring, always check and offer
|
|
52834
|
+
3. For RO-Crate metadata authoring, always check and offer metadata profiles
|
|
52861
52835
|
because they guide FAIR metadata creation for both users and agents.
|
|
52862
52836
|
4. If the crate already contains active \`conformsTo\` profile URLs, resolve and
|
|
52863
52837
|
download those profiles before proceeding with planning or edits. In local
|
|
@@ -52867,9 +52841,9 @@ When generating the review URL:
|
|
|
52867
52841
|
metadata work until it is addressed.
|
|
52868
52842
|
5. When no active \`conformsTo\` profile exists, offer available local metadata
|
|
52869
52843
|
profiles first, then browse configured remote CEDAR providers with
|
|
52870
|
-
\`
|
|
52844
|
+
\`list_remote_template_tree\` and offer unimported leaf templates in a simplified
|
|
52871
52845
|
folder tree. After the user selects a remote template, import it with
|
|
52872
|
-
\`
|
|
52846
|
+
\`import_remote_template\` using \`templateIdOrUrl=<selected templateId>\`,
|
|
52873
52847
|
then associate the returned \`profile.conformsTo\` with the crate using
|
|
52874
52848
|
\`update_profile_conforms_to(write=true)\`.
|
|
52875
52849
|
`,
|
|
@@ -52924,7 +52898,7 @@ These rules are mandatory for RO-Crate metadata quality.
|
|
|
52924
52898
|
1. Profile conformance is a hard constraint for required fields, value sets, and entity types on profiled \`Dataset\`/\`File\` entities.
|
|
52925
52899
|
2. Prefer properties explicitly allowed by active profile rules for curated metadata.
|
|
52926
52900
|
3. Start setting values for required fields first, then recommended optional fields, then any remaining allowed fields.
|
|
52927
|
-
4. Custom properties outside the active profile
|
|
52901
|
+
4. Custom properties outside the active profile are allowed when they have JSON-LD context mappings.
|
|
52928
52902
|
- Treat validation messages about custom properties as advisory notes.
|
|
52929
52903
|
- Do not delete, rename, or migrate custom properties unless the user explicitly asks.
|
|
52930
52904
|
- If useful, mention an allowed alternative field or profile update, but keep the user's custom metadata intact.
|
|
@@ -52945,7 +52919,7 @@ Always follow this sequence when curating RO-Crate metadata:
|
|
|
52945
52919
|
1. Call \`get_rocrate_context\` before any edit.
|
|
52946
52920
|
In local mode this must be treated as a profile-resolution step as well as a context read.
|
|
52947
52921
|
If the crate already contains \`conformsTo\` URLs, do not proceed until the corresponding
|
|
52948
|
-
|
|
52922
|
+
profiles have been downloaded into the local profile store or the resolution failure
|
|
52949
52923
|
has been reported clearly to the user.
|
|
52950
52924
|
2. Identify whether the crate already has active \`conformsTo\` profile URLs.
|
|
52951
52925
|
If active \`conformsTo\` URLs are present, the user has already selected the
|
|
@@ -52953,35 +52927,35 @@ Always follow this sequence when curating RO-Crate metadata:
|
|
|
52953
52927
|
profile choices unless the user asks to change them.
|
|
52954
52928
|
If \`get_rocrate_context\`, \`validate_crate\`, or another profile-aware MCP call reports
|
|
52955
52929
|
unresolved profile URLs, stop normal metadata work and resolve/download those profiles first.
|
|
52956
|
-
3. For RO-Crate metadata authoring, always check and offer
|
|
52930
|
+
3. For RO-Crate metadata authoring, always check and offer metadata profiles because they guide FAIR metadata creation for both users and agents.
|
|
52957
52931
|
4. If no active profile is present:
|
|
52958
52932
|
- call \`list_metadata_profiles\` to show locally available metadata profiles,
|
|
52959
|
-
- call \`
|
|
52933
|
+
- call \`list_remote_template_tree\` to browse configured remote CEDAR providers
|
|
52960
52934
|
when local profiles are empty, insufficient, or the user may want a remote
|
|
52961
52935
|
profile,
|
|
52962
52936
|
- present every available local profile returned by \`list_metadata_profiles\` by name, version, and \`conformsTo\` URL,
|
|
52963
|
-
- present remote CEDAR
|
|
52937
|
+
- present remote CEDAR templates separately as a simplified folder tree with
|
|
52964
52938
|
only selectable leaf templates; do not list templates already imported
|
|
52965
52939
|
locally,
|
|
52966
52940
|
- do not collapse the list to only the profile you recommend,
|
|
52967
52941
|
- if one profile seems best, mark it as recommended while still listing the other available profiles,
|
|
52968
|
-
- offer a numbered menu in this order: all listed profiles
|
|
52942
|
+
- offer a numbered menu in this order: all listed local profiles and remote templates first, then "provide another metadata profile URL", then "continue without a profile",
|
|
52969
52943
|
- stop and wait for the user's choice before planning fields, searching the web, or writing metadata,
|
|
52970
52944
|
- for an already-downloaded local profile, call \`update_profile_conforms_to\`
|
|
52971
52945
|
with its \`conformsTo\` URL after the user chooses it,
|
|
52972
|
-
- for a remote CEDAR leaf template, call \`
|
|
52946
|
+
- for a remote CEDAR leaf template, call \`import_remote_template\` with
|
|
52973
52947
|
\`templateIdOrUrl=<selected templateId>\`, then call
|
|
52974
52948
|
\`update_profile_conforms_to(write=true)\` with the returned
|
|
52975
52949
|
\`profile.conformsTo\`,
|
|
52976
|
-
- if no profiles
|
|
52950
|
+
- if no profiles or templates can be listed because of an error, report the error and still offer the user a chance to provide a metadata profile URL.
|
|
52977
52951
|
5. Do not silently continue without a profile after listing available profiles. Continuing without a profile requires the user's explicit choice.
|
|
52978
52952
|
6. Read active profile constraints from \`profileRules.allowedPropertiesByClass\`.
|
|
52979
|
-
7. If constraints are missing or unclear, call \`
|
|
52953
|
+
7. If constraints are missing or unclear, call \`resolve_metadata_profile\`.
|
|
52980
52954
|
Do not continue to field planning or metadata edits while active \`conformsTo\` URLs remain unresolved.
|
|
52981
52955
|
8. Build a short plan:
|
|
52982
52956
|
- required fields still missing
|
|
52983
52957
|
- recommended optional fields
|
|
52984
|
-
- custom fields outside the active profile
|
|
52958
|
+
- custom fields outside the active profile, if relevant
|
|
52985
52959
|
9. Only after planning, run web \`search\` if needed for missing values.
|
|
52986
52960
|
10. Only then start metadata writes with \`apply_changes\` (default persists in local mode).
|
|
52987
52961
|
- Use \`dryRun=true\` when you want preview-only execution.
|
|
@@ -53325,21 +53299,21 @@ function createToolDispatcher(deps) {
|
|
|
53325
53299
|
}
|
|
53326
53300
|
return textResult2(result);
|
|
53327
53301
|
}
|
|
53328
|
-
if (toolName === "
|
|
53302
|
+
if (toolName === "list_remote_templates") {
|
|
53329
53303
|
const result = await runInTelemetryContext(async () => listWellKnownSchemas2(params));
|
|
53330
53304
|
if (collector && telemetryId) {
|
|
53331
53305
|
collector.completeToolCallSuccess(telemetryId, result);
|
|
53332
53306
|
}
|
|
53333
53307
|
return textResult2(result);
|
|
53334
53308
|
}
|
|
53335
|
-
if (toolName === "
|
|
53309
|
+
if (toolName === "list_remote_template_tree") {
|
|
53336
53310
|
const result = await runInTelemetryContext(async () => listRemoteSchemaTree2(params));
|
|
53337
53311
|
if (collector && telemetryId) {
|
|
53338
53312
|
collector.completeToolCallSuccess(telemetryId, result);
|
|
53339
53313
|
}
|
|
53340
53314
|
return textResult2(result);
|
|
53341
53315
|
}
|
|
53342
|
-
if (toolName === "
|
|
53316
|
+
if (toolName === "import_remote_template") {
|
|
53343
53317
|
const result = await runInTelemetryContext(async () => importWellKnownSchema2(params));
|
|
53344
53318
|
if (collector && telemetryId) {
|
|
53345
53319
|
collector.completeToolCallSuccess(telemetryId, result);
|
|
@@ -53887,10 +53861,10 @@ function createToolDispatcher(deps) {
|
|
|
53887
53861
|
}
|
|
53888
53862
|
return textResult2(payload);
|
|
53889
53863
|
}
|
|
53890
|
-
if (toolName === "
|
|
53864
|
+
if (toolName === "resolve_metadata_profile") {
|
|
53891
53865
|
const profileUrl = typeof params.profileUrl === "string" ? params.profileUrl.trim() : "";
|
|
53892
53866
|
if (profileUrl === "") {
|
|
53893
|
-
throw new Error("
|
|
53867
|
+
throw new Error("resolve_metadata_profile requires profileUrl.");
|
|
53894
53868
|
}
|
|
53895
53869
|
const mode = parseAccessMode2(params);
|
|
53896
53870
|
const includeProfileContent = params.includeProfileContent === true;
|
|
@@ -69273,8 +69247,9 @@ async function startServerWithTransports(options) {
|
|
|
69273
69247
|
const mcpServer = new McpServer(
|
|
69274
69248
|
{
|
|
69275
69249
|
name: "rocrate-mcp-server",
|
|
69250
|
+
title: "RO-Crate MCP / VibeARP",
|
|
69276
69251
|
version: getBuildInfo().version,
|
|
69277
|
-
description: "RO-Crate metadata tools. The canonical way to open a local RO-Crate dataset in AROMA is open_aroma_for_local_file."
|
|
69252
|
+
description: "RO-Crate metadata tools, also known as RO-Crate MCP or VibeARP. These names refer to this same server. The canonical way to open a local RO-Crate dataset in AROMA is open_aroma_for_local_file."
|
|
69278
69253
|
},
|
|
69279
69254
|
{
|
|
69280
69255
|
capabilities: {
|
|
@@ -70014,6 +69989,7 @@ function getDashboardUrl() {
|
|
|
70014
69989
|
}
|
|
70015
69990
|
function getMcpServerInstructions() {
|
|
70016
69991
|
return `RO-CRATE TOOL ROUTING
|
|
69992
|
+
This MCP server is known by the call names "RO-Crate MCP" and "VibeARP". When a user mentions either name, use this configured RO-Crate MCP server's tools, regardless of the server label shown by the harness (commonly "rocrate" or "rocrate-mcp-server"). Do not search for or select a different MCP server based on these names.
|
|
70017
69993
|
The canonical way to open a local RO-Crate dataset in AROMA is open_aroma_for_local_file.
|
|
70018
69994
|
For a direct request to open, view, show, inspect, or launch a dataset in AROMA\u2014including the exact request "open dataset in AROMA"\u2014call open_aroma_for_local_file immediately as the first tool. Treat "dataset" as the RO-Crate in the current working directory and pass "ro-crate-metadata.json"; otherwise pass the dataset's ro-crate-metadata.json path.
|
|
70019
69995
|
Before RO-Crate editing/advice, call read_agent_workflow_doc with name "rocrate_workflow.md" and follow it.
|