@nextclaw/mcp 0.1.1 → 0.1.3
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/dist/index.d.ts +105 -2
- package/dist/index.js +271 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { McpServerDefinition, McpTransport,
|
|
1
|
+
import { McpServerDefinition, McpTransport, McpServerScope, McpServerMetadata, Config } from '@nextclaw/core';
|
|
2
2
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
3
3
|
import { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
4
4
|
|
|
@@ -45,6 +45,56 @@ type McpLifecycleState = {
|
|
|
45
45
|
lastReadyAt?: string;
|
|
46
46
|
lastError?: string;
|
|
47
47
|
};
|
|
48
|
+
type McpMarketplaceTransportType = McpTransport["type"];
|
|
49
|
+
type McpMarketplaceInputField = {
|
|
50
|
+
id: string;
|
|
51
|
+
label: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
required?: boolean;
|
|
54
|
+
secret?: boolean;
|
|
55
|
+
defaultValue?: string;
|
|
56
|
+
};
|
|
57
|
+
type McpMarketplaceInstallTemplate = {
|
|
58
|
+
kind: "template";
|
|
59
|
+
spec: string;
|
|
60
|
+
command: string;
|
|
61
|
+
defaultName: string;
|
|
62
|
+
transportTypes: McpMarketplaceTransportType[];
|
|
63
|
+
template: McpServerDefinition;
|
|
64
|
+
inputs: McpMarketplaceInputField[];
|
|
65
|
+
};
|
|
66
|
+
type McpInstalledRecord = {
|
|
67
|
+
name: string;
|
|
68
|
+
enabled: boolean;
|
|
69
|
+
transport: McpTransport["type"];
|
|
70
|
+
scope: McpServerScope;
|
|
71
|
+
source: "manual" | "marketplace";
|
|
72
|
+
catalogSlug?: string;
|
|
73
|
+
displayName?: string;
|
|
74
|
+
vendor?: string;
|
|
75
|
+
docsUrl?: string;
|
|
76
|
+
homepage?: string;
|
|
77
|
+
trustLevel?: "official" | "verified" | "community";
|
|
78
|
+
installedAt?: string;
|
|
79
|
+
toolCount?: number;
|
|
80
|
+
accessible?: boolean;
|
|
81
|
+
lastReadyAt?: string;
|
|
82
|
+
lastError?: string;
|
|
83
|
+
};
|
|
84
|
+
type McpMutationResult = {
|
|
85
|
+
changed: boolean;
|
|
86
|
+
name: string;
|
|
87
|
+
message: string;
|
|
88
|
+
definition?: McpServerDefinition;
|
|
89
|
+
};
|
|
90
|
+
type McpMaterializeInstallParams = {
|
|
91
|
+
template: McpMarketplaceInstallTemplate;
|
|
92
|
+
name?: string;
|
|
93
|
+
enabled?: boolean;
|
|
94
|
+
scope?: Partial<McpServerScope>;
|
|
95
|
+
inputs?: Record<string, string | undefined>;
|
|
96
|
+
metadata?: Partial<McpServerMetadata>;
|
|
97
|
+
};
|
|
48
98
|
declare function normalizeMcpServerName(name: string): string;
|
|
49
99
|
declare function readDefaultAgentId(config: Config): string;
|
|
50
100
|
declare function isServerAccessibleToAgent(params: {
|
|
@@ -79,6 +129,7 @@ declare class McpServerLifecycleManager {
|
|
|
79
129
|
});
|
|
80
130
|
warmServer(record: McpServerRecord): Promise<McpLifecycleState>;
|
|
81
131
|
getCachedCatalog(serverName: string): McpToolCatalogEntry[];
|
|
132
|
+
getCachedState(serverName: string): McpLifecycleState | undefined;
|
|
82
133
|
callTool(record: McpServerRecord, toolName: string, args: Record<string, unknown>): Promise<unknown>;
|
|
83
134
|
closeAll(): Promise<void>;
|
|
84
135
|
closeServer(serverName: string): Promise<void>;
|
|
@@ -104,6 +155,7 @@ declare class McpRegistryService {
|
|
|
104
155
|
nextConfig: Config;
|
|
105
156
|
}): Promise<McpConfigReconcileResult>;
|
|
106
157
|
listAccessibleTools(filter?: McpCatalogFilter): McpToolCatalogEntry[];
|
|
158
|
+
getCachedState(serverName: string): McpLifecycleState | undefined;
|
|
107
159
|
callTool(params: {
|
|
108
160
|
serverName: string;
|
|
109
161
|
toolName: string;
|
|
@@ -122,4 +174,55 @@ declare class McpDoctorService {
|
|
|
122
174
|
inspect(name?: string): Promise<McpDoctorReport[]>;
|
|
123
175
|
}
|
|
124
176
|
|
|
125
|
-
|
|
177
|
+
declare class McpDoctorFacade {
|
|
178
|
+
private readonly options;
|
|
179
|
+
private readonly doctorService;
|
|
180
|
+
constructor(options: {
|
|
181
|
+
getConfig: () => Config;
|
|
182
|
+
registryService?: McpRegistryService;
|
|
183
|
+
});
|
|
184
|
+
inspect(name?: string): Promise<McpDoctorReport[]>;
|
|
185
|
+
inspectOne(name: string): Promise<McpDoctorReport | null>;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
declare class McpInstallTemplateMaterializer {
|
|
189
|
+
materialize(params: McpMaterializeInstallParams): {
|
|
190
|
+
name: string;
|
|
191
|
+
definition: McpServerDefinition;
|
|
192
|
+
};
|
|
193
|
+
private applyInputs;
|
|
194
|
+
private mergeScope;
|
|
195
|
+
private mergeMetadata;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
declare class McpMutationService {
|
|
199
|
+
private readonly options;
|
|
200
|
+
private readonly materializer;
|
|
201
|
+
constructor(options: {
|
|
202
|
+
getConfig: () => Config;
|
|
203
|
+
saveConfig: (config: Config) => void;
|
|
204
|
+
materializer?: McpInstallTemplateMaterializer;
|
|
205
|
+
});
|
|
206
|
+
listServerNames(): string[];
|
|
207
|
+
addServer(name: string, definition: McpServerDefinition): McpMutationResult;
|
|
208
|
+
updateServer(name: string, definition: McpServerDefinition): McpMutationResult;
|
|
209
|
+
removeServer(name: string): McpMutationResult;
|
|
210
|
+
toggleEnabled(name: string, enabled: boolean): McpMutationResult;
|
|
211
|
+
installFromTemplate(params: Omit<McpMaterializeInstallParams, "template"> & {
|
|
212
|
+
template: McpMarketplaceInstallTemplate;
|
|
213
|
+
}): McpMutationResult;
|
|
214
|
+
duplicateServer(sourceName: string, targetName: string): McpMutationResult;
|
|
215
|
+
renameServer(sourceName: string, targetName: string): McpMutationResult;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
declare class McpInstalledViewService {
|
|
219
|
+
private readonly options;
|
|
220
|
+
private readonly registryService;
|
|
221
|
+
constructor(options: {
|
|
222
|
+
getConfig: () => Config;
|
|
223
|
+
registryService?: McpRegistryService;
|
|
224
|
+
});
|
|
225
|
+
listInstalled(): McpInstalledRecord[];
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export { type McpCatalogFilter, McpClientFactory, type McpConfigReconcileResult, McpDoctorFacade, type McpDoctorReport, McpDoctorService, McpInstallTemplateMaterializer, type McpInstalledRecord, McpInstalledViewService, type McpLifecycleState, type McpMarketplaceInputField, type McpMarketplaceInstallTemplate, type McpMarketplaceTransportType, type McpMaterializeInstallParams, type McpMutationResult, McpMutationService, McpRegistryService, McpServerLifecycleManager, type McpServerRecord, type McpServerWarmResult, type McpToolCatalogEntry, buildQualifiedMcpToolName, getMcpServer, isServerAccessibleToAgent, listMcpServers, normalizeMcpServerName, readDefaultAgentId, sanitizeMcpSegment };
|
package/dist/index.js
CHANGED
|
@@ -151,6 +151,13 @@ var McpServerLifecycleManager = class {
|
|
|
151
151
|
getCachedCatalog(serverName) {
|
|
152
152
|
return this.readyConnections.get(serverName)?.tools ?? [];
|
|
153
153
|
}
|
|
154
|
+
getCachedState(serverName) {
|
|
155
|
+
const ready = this.readyConnections.get(serverName);
|
|
156
|
+
if (!ready) {
|
|
157
|
+
return void 0;
|
|
158
|
+
}
|
|
159
|
+
return this.stripConnection(ready);
|
|
160
|
+
}
|
|
154
161
|
async callTool(record, toolName, args) {
|
|
155
162
|
const connection = await this.ensureConnection(record);
|
|
156
163
|
const result = await connection.client.callTool({
|
|
@@ -376,6 +383,9 @@ var McpRegistryService = class {
|
|
|
376
383
|
})
|
|
377
384
|
).flatMap((record) => this.lifecycleManager.getCachedCatalog(record.name)).sort((left, right) => left.qualifiedName.localeCompare(right.qualifiedName));
|
|
378
385
|
}
|
|
386
|
+
getCachedState(serverName) {
|
|
387
|
+
return this.lifecycleManager.getCachedState(serverName);
|
|
388
|
+
}
|
|
379
389
|
async callTool(params) {
|
|
380
390
|
const server = this.getServer(params.serverName);
|
|
381
391
|
if (!server) {
|
|
@@ -437,9 +447,270 @@ var McpDoctorService = class {
|
|
|
437
447
|
);
|
|
438
448
|
}
|
|
439
449
|
};
|
|
450
|
+
|
|
451
|
+
// src/doctor/mcp-doctor-facade.ts
|
|
452
|
+
var McpDoctorFacade = class {
|
|
453
|
+
constructor(options) {
|
|
454
|
+
this.options = options;
|
|
455
|
+
this.doctorService = new McpDoctorService({
|
|
456
|
+
getConfig: this.options.getConfig,
|
|
457
|
+
registryService: this.options.registryService
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
doctorService;
|
|
461
|
+
async inspect(name) {
|
|
462
|
+
return await this.doctorService.inspect(name);
|
|
463
|
+
}
|
|
464
|
+
async inspectOne(name) {
|
|
465
|
+
const reports = await this.inspect(name);
|
|
466
|
+
return reports[0] ?? null;
|
|
467
|
+
}
|
|
468
|
+
};
|
|
469
|
+
|
|
470
|
+
// src/install/mcp-install-template-materializer.ts
|
|
471
|
+
var McpInstallTemplateMaterializer = class {
|
|
472
|
+
materialize(params) {
|
|
473
|
+
const name = normalizeMcpServerName(params.name?.trim() || params.template.defaultName);
|
|
474
|
+
const inputs = params.inputs ?? {};
|
|
475
|
+
const definition = this.applyInputs(params.template.template, inputs);
|
|
476
|
+
definition.enabled = params.enabled ?? definition.enabled;
|
|
477
|
+
definition.scope = this.mergeScope(definition.scope, params.scope);
|
|
478
|
+
definition.metadata = this.mergeMetadata(definition.metadata, params.template, params.metadata);
|
|
479
|
+
return { name, definition };
|
|
480
|
+
}
|
|
481
|
+
applyInputs(definition, inputs) {
|
|
482
|
+
const replacer = (value) => value.replace(/\{\{\s*([A-Za-z0-9._-]+)\s*\}\}/g, (_, key) => inputs[key]?.trim() ?? "");
|
|
483
|
+
const transform = (value) => {
|
|
484
|
+
if (typeof value === "string") {
|
|
485
|
+
return replacer(value);
|
|
486
|
+
}
|
|
487
|
+
if (Array.isArray(value)) {
|
|
488
|
+
return value.map((entry) => transform(entry));
|
|
489
|
+
}
|
|
490
|
+
if (!value || typeof value !== "object") {
|
|
491
|
+
return value;
|
|
492
|
+
}
|
|
493
|
+
return Object.fromEntries(
|
|
494
|
+
Object.entries(value).map(([key, entry]) => [key, transform(entry)])
|
|
495
|
+
);
|
|
496
|
+
};
|
|
497
|
+
return transform(structuredClone(definition));
|
|
498
|
+
}
|
|
499
|
+
mergeScope(current, override) {
|
|
500
|
+
if (!override) {
|
|
501
|
+
return current;
|
|
502
|
+
}
|
|
503
|
+
const agents = Array.from(new Set((override.agents ?? current.agents ?? []).map((entry) => entry.trim()).filter(Boolean)));
|
|
504
|
+
const allAgents = override.allAgents ?? current.allAgents ?? agents.length === 0;
|
|
505
|
+
return {
|
|
506
|
+
allAgents,
|
|
507
|
+
agents: allAgents ? [] : agents
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
mergeMetadata(current, template, override) {
|
|
511
|
+
return {
|
|
512
|
+
...current,
|
|
513
|
+
source: "marketplace",
|
|
514
|
+
catalogSlug: template.spec,
|
|
515
|
+
displayName: override?.displayName ?? current?.displayName,
|
|
516
|
+
vendor: override?.vendor ?? current?.vendor,
|
|
517
|
+
docsUrl: override?.docsUrl ?? current?.docsUrl,
|
|
518
|
+
homepage: override?.homepage ?? current?.homepage,
|
|
519
|
+
trustLevel: override?.trustLevel ?? current?.trustLevel ?? "official",
|
|
520
|
+
installedAt: override?.installedAt ?? current?.installedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
|
|
521
|
+
...override ?? {}
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
|
|
526
|
+
// src/manage/mcp-mutation-service.ts
|
|
527
|
+
var McpMutationService = class {
|
|
528
|
+
constructor(options) {
|
|
529
|
+
this.options = options;
|
|
530
|
+
this.materializer = this.options.materializer ?? new McpInstallTemplateMaterializer();
|
|
531
|
+
}
|
|
532
|
+
materializer;
|
|
533
|
+
listServerNames() {
|
|
534
|
+
return listMcpServers(this.options.getConfig()).map((record) => record.name);
|
|
535
|
+
}
|
|
536
|
+
addServer(name, definition) {
|
|
537
|
+
const normalizedName = normalizeMcpServerName(name);
|
|
538
|
+
const config = this.options.getConfig();
|
|
539
|
+
if (config.mcp.servers[normalizedName]) {
|
|
540
|
+
return {
|
|
541
|
+
changed: false,
|
|
542
|
+
name: normalizedName,
|
|
543
|
+
message: `MCP server already exists: ${normalizedName}. Use 'mcp list' or remove it first.`,
|
|
544
|
+
definition: config.mcp.servers[normalizedName]
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
config.mcp.servers[normalizedName] = definition;
|
|
548
|
+
this.options.saveConfig(config);
|
|
549
|
+
return {
|
|
550
|
+
changed: true,
|
|
551
|
+
name: normalizedName,
|
|
552
|
+
message: `Added MCP server ${normalizedName}.`,
|
|
553
|
+
definition
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
updateServer(name, definition) {
|
|
557
|
+
const normalizedName = normalizeMcpServerName(name);
|
|
558
|
+
const config = this.options.getConfig();
|
|
559
|
+
if (!config.mcp.servers[normalizedName]) {
|
|
560
|
+
return {
|
|
561
|
+
changed: false,
|
|
562
|
+
name: normalizedName,
|
|
563
|
+
message: `Unknown MCP server: ${normalizedName}`
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
config.mcp.servers[normalizedName] = definition;
|
|
567
|
+
this.options.saveConfig(config);
|
|
568
|
+
return {
|
|
569
|
+
changed: true,
|
|
570
|
+
name: normalizedName,
|
|
571
|
+
message: `Updated MCP server ${normalizedName}.`,
|
|
572
|
+
definition
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
removeServer(name) {
|
|
576
|
+
const normalizedName = normalizeMcpServerName(name);
|
|
577
|
+
const config = this.options.getConfig();
|
|
578
|
+
if (!config.mcp.servers[normalizedName]) {
|
|
579
|
+
return {
|
|
580
|
+
changed: false,
|
|
581
|
+
name: normalizedName,
|
|
582
|
+
message: `Unknown MCP server: ${normalizedName}`
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
delete config.mcp.servers[normalizedName];
|
|
586
|
+
this.options.saveConfig(config);
|
|
587
|
+
return {
|
|
588
|
+
changed: true,
|
|
589
|
+
name: normalizedName,
|
|
590
|
+
message: `Removed MCP server ${normalizedName}.`
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
toggleEnabled(name, enabled) {
|
|
594
|
+
const normalizedName = normalizeMcpServerName(name);
|
|
595
|
+
const config = this.options.getConfig();
|
|
596
|
+
const current = config.mcp.servers[normalizedName];
|
|
597
|
+
if (!current) {
|
|
598
|
+
return {
|
|
599
|
+
changed: false,
|
|
600
|
+
name: normalizedName,
|
|
601
|
+
message: `Unknown MCP server: ${normalizedName}`
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
current.enabled = enabled;
|
|
605
|
+
this.options.saveConfig(config);
|
|
606
|
+
return {
|
|
607
|
+
changed: true,
|
|
608
|
+
name: normalizedName,
|
|
609
|
+
message: `${enabled ? "Enabled" : "Disabled"} MCP server ${normalizedName}.`,
|
|
610
|
+
definition: current
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
installFromTemplate(params) {
|
|
614
|
+
const materialized = this.materializer.materialize(params);
|
|
615
|
+
return this.addServer(materialized.name, materialized.definition);
|
|
616
|
+
}
|
|
617
|
+
duplicateServer(sourceName, targetName) {
|
|
618
|
+
const source = getMcpServer(this.options.getConfig(), sourceName);
|
|
619
|
+
if (!source) {
|
|
620
|
+
return {
|
|
621
|
+
changed: false,
|
|
622
|
+
name: normalizeMcpServerName(sourceName),
|
|
623
|
+
message: `Unknown MCP server: ${normalizeMcpServerName(sourceName)}`
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
const definition = structuredClone(source.definition);
|
|
627
|
+
if (definition.metadata) {
|
|
628
|
+
definition.metadata = {
|
|
629
|
+
...definition.metadata,
|
|
630
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
return this.addServer(targetName, definition);
|
|
634
|
+
}
|
|
635
|
+
renameServer(sourceName, targetName) {
|
|
636
|
+
const source = getMcpServer(this.options.getConfig(), sourceName);
|
|
637
|
+
if (!source) {
|
|
638
|
+
return {
|
|
639
|
+
changed: false,
|
|
640
|
+
name: normalizeMcpServerName(sourceName),
|
|
641
|
+
message: `Unknown MCP server: ${normalizeMcpServerName(sourceName)}`
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
const nextName = normalizeMcpServerName(targetName);
|
|
645
|
+
const config = this.options.getConfig();
|
|
646
|
+
if (source.name === nextName) {
|
|
647
|
+
return {
|
|
648
|
+
changed: false,
|
|
649
|
+
name: nextName,
|
|
650
|
+
message: `MCP server already named ${nextName}.`,
|
|
651
|
+
definition: source.definition
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
if (config.mcp.servers[nextName]) {
|
|
655
|
+
return {
|
|
656
|
+
changed: false,
|
|
657
|
+
name: nextName,
|
|
658
|
+
message: `MCP server already exists: ${nextName}. Use another name.`
|
|
659
|
+
};
|
|
660
|
+
}
|
|
661
|
+
delete config.mcp.servers[source.name];
|
|
662
|
+
config.mcp.servers[nextName] = source.definition;
|
|
663
|
+
this.options.saveConfig(config);
|
|
664
|
+
return {
|
|
665
|
+
changed: true,
|
|
666
|
+
name: nextName,
|
|
667
|
+
message: `Renamed MCP server ${source.name} -> ${nextName}.`,
|
|
668
|
+
definition: source.definition
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
// src/view/mcp-installed-view-service.ts
|
|
674
|
+
var McpInstalledViewService = class {
|
|
675
|
+
constructor(options) {
|
|
676
|
+
this.options = options;
|
|
677
|
+
this.registryService = this.options.registryService ?? new McpRegistryService({
|
|
678
|
+
getConfig: this.options.getConfig
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
registryService;
|
|
682
|
+
listInstalled() {
|
|
683
|
+
return this.registryService.listServers().map((server) => {
|
|
684
|
+
const metadata = server.definition.metadata;
|
|
685
|
+
const cached = this.registryService.getCachedState(server.name);
|
|
686
|
+
return {
|
|
687
|
+
name: server.name,
|
|
688
|
+
enabled: server.definition.enabled,
|
|
689
|
+
transport: server.definition.transport.type,
|
|
690
|
+
scope: server.definition.scope,
|
|
691
|
+
source: metadata?.source === "marketplace" ? "marketplace" : "manual",
|
|
692
|
+
catalogSlug: metadata?.catalogSlug,
|
|
693
|
+
displayName: metadata?.displayName,
|
|
694
|
+
vendor: metadata?.vendor,
|
|
695
|
+
docsUrl: metadata?.docsUrl,
|
|
696
|
+
homepage: metadata?.homepage,
|
|
697
|
+
trustLevel: metadata?.trustLevel,
|
|
698
|
+
installedAt: metadata?.installedAt,
|
|
699
|
+
accessible: cached?.clientReady,
|
|
700
|
+
toolCount: cached?.tools.length,
|
|
701
|
+
lastReadyAt: cached?.lastReadyAt,
|
|
702
|
+
lastError: cached?.lastError
|
|
703
|
+
};
|
|
704
|
+
});
|
|
705
|
+
}
|
|
706
|
+
};
|
|
440
707
|
export {
|
|
441
708
|
McpClientFactory,
|
|
709
|
+
McpDoctorFacade,
|
|
442
710
|
McpDoctorService,
|
|
711
|
+
McpInstallTemplateMaterializer,
|
|
712
|
+
McpInstalledViewService,
|
|
713
|
+
McpMutationService,
|
|
443
714
|
McpRegistryService,
|
|
444
715
|
McpServerLifecycleManager,
|
|
445
716
|
buildQualifiedMcpToolName,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Platform-level MCP registry, lifecycle, and diagnostics for NextClaw.",
|
|
6
6
|
"type": "module",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
19
19
|
"undici": "^6.21.0",
|
|
20
|
-
"@nextclaw/core": "0.9.
|
|
20
|
+
"@nextclaw/core": "0.9.4"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/node": "^20.17.6",
|