@nebutra/mcp 0.1.4 → 3.0.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 +22 -0
- package/bin/nebutra-mcp.js +28 -0
- package/bin/nebutra-tool-protocol.js +27 -0
- package/dist/chunk-EMIF5K3P.js +83 -0
- package/dist/{chunk-25TNKUCR.js → chunk-ZTLLKBBG.js} +14 -89
- package/dist/cli.js +2 -1
- package/dist/index-BD_aLZKz.d.ts +158 -0
- package/dist/index.d.ts +4 -157
- package/dist/index.js +7 -5
- package/dist/middleware/index.d.ts +2 -0
- package/dist/middleware/index.js +12 -0
- package/dist/server/contextServer.js +0 -0
- package/package.json +22 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @nebutra/mcp
|
|
2
2
|
|
|
3
|
+
## 3.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @nebutra/capability-kit@3.0.0
|
|
9
|
+
- @nebutra/errors@3.0.0
|
|
10
|
+
- @nebutra/event-log@3.0.0
|
|
11
|
+
- @nebutra/trace-store@3.0.0
|
|
12
|
+
- @nebutra/ui@3.0.0
|
|
13
|
+
|
|
14
|
+
## 2.0.0
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies []:
|
|
19
|
+
- @nebutra/ui@2.0.0
|
|
20
|
+
- @nebutra/capability-kit@2.0.0
|
|
21
|
+
- @nebutra/errors@2.0.0
|
|
22
|
+
- @nebutra/event-log@2.0.0
|
|
23
|
+
- @nebutra/trace-store@2.0.0
|
|
24
|
+
|
|
3
25
|
## 0.1.3
|
|
4
26
|
|
|
5
27
|
### Patch Changes
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Committed bin entry for `nebutra-mcp` (the stdio context server).
|
|
3
|
+
//
|
|
4
|
+
// pnpm links bins before any lifecycle script or build runs, so package.json#bin
|
|
5
|
+
// must point at a file that exists in a fresh checkout — dist/ does not. This
|
|
6
|
+
// file exists at link time and hands off to the tsup output once it is built.
|
|
7
|
+
// Guarded by tests/architecture/workspace-bin-stubs.test.ts.
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { dirname, resolve } from "node:path";
|
|
10
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
|
+
|
|
12
|
+
const entry = resolve(dirname(fileURLToPath(import.meta.url)), "../dist/server/contextServer.js");
|
|
13
|
+
|
|
14
|
+
if (!existsSync(entry)) {
|
|
15
|
+
process.stderr.write(
|
|
16
|
+
[
|
|
17
|
+
`nebutra-mcp: built entry not found at ${entry}`,
|
|
18
|
+
"The package has not been built yet. Run `pnpm --filter @nebutra/mcp build` and retry.",
|
|
19
|
+
"",
|
|
20
|
+
].join("\n"),
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// contextServer.js starts the server only when process.argv[1] ends with
|
|
26
|
+
// "contextServer.js", so make argv identical to a direct `node dist/server/… `.
|
|
27
|
+
process.argv[1] = entry;
|
|
28
|
+
await import(pathToFileURL(entry).href);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Committed bin entry for `nebutra-tool-protocol`.
|
|
3
|
+
//
|
|
4
|
+
// pnpm links bins before any lifecycle script or build runs, so package.json#bin
|
|
5
|
+
// must point at a file that exists in a fresh checkout — dist/ does not. This
|
|
6
|
+
// file exists at link time and hands off to the tsup output once it is built.
|
|
7
|
+
// Guarded by tests/architecture/workspace-bin-stubs.test.ts.
|
|
8
|
+
import { existsSync } from "node:fs";
|
|
9
|
+
import { dirname, resolve } from "node:path";
|
|
10
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
11
|
+
|
|
12
|
+
const entry = resolve(dirname(fileURLToPath(import.meta.url)), "../dist/cli.js");
|
|
13
|
+
|
|
14
|
+
if (!existsSync(entry)) {
|
|
15
|
+
process.stderr.write(
|
|
16
|
+
[
|
|
17
|
+
`nebutra-tool-protocol: built entry not found at ${entry}`,
|
|
18
|
+
"The package has not been built yet. Run `pnpm --filter @nebutra/mcp build` and retry.",
|
|
19
|
+
"",
|
|
20
|
+
].join("\n"),
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Keep argv identical to a direct `node dist/cli.js …` invocation.
|
|
26
|
+
process.argv[1] = entry;
|
|
27
|
+
await import(pathToFileURL(entry).href);
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// src/middleware/mcpMiddleware.ts
|
|
2
|
+
function createRateLimitMiddleware(options) {
|
|
3
|
+
const requests = /* @__PURE__ */ new Map();
|
|
4
|
+
return async (ctx, next) => {
|
|
5
|
+
const key = `${ctx.tenantId || "anon"}:${ctx.userId || "anon"}`;
|
|
6
|
+
const now = Date.now();
|
|
7
|
+
let record = requests.get(key);
|
|
8
|
+
if (!record || now > record.resetAt) {
|
|
9
|
+
record = { count: 0, resetAt: now + options.windowMs };
|
|
10
|
+
requests.set(key, record);
|
|
11
|
+
}
|
|
12
|
+
record.count++;
|
|
13
|
+
if (record.count > options.maxRequests) {
|
|
14
|
+
return {
|
|
15
|
+
success: false,
|
|
16
|
+
error: `MCP rate limit exceeded. Max ${options.maxRequests} requests per ${options.windowMs / 1e3}s`,
|
|
17
|
+
duration: 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
return next();
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function createAuditMiddleware(options) {
|
|
24
|
+
return async (ctx, next) => {
|
|
25
|
+
const result = await next();
|
|
26
|
+
const entry = {
|
|
27
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
28
|
+
requestId: ctx.requestId,
|
|
29
|
+
toolName: ctx.toolName,
|
|
30
|
+
arguments: ctx.arguments,
|
|
31
|
+
success: result.success,
|
|
32
|
+
duration: result.duration
|
|
33
|
+
};
|
|
34
|
+
if (ctx.tenantId) entry.tenantId = ctx.tenantId;
|
|
35
|
+
if (ctx.userId) entry.userId = ctx.userId;
|
|
36
|
+
if (result.error) entry.error = result.error;
|
|
37
|
+
Promise.resolve(options.onLog(entry)).catch(console.error);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function createAccessControlMiddleware(options) {
|
|
42
|
+
return async (ctx, next) => {
|
|
43
|
+
if (options.blockedTools?.includes(ctx.toolName)) {
|
|
44
|
+
return {
|
|
45
|
+
success: false,
|
|
46
|
+
error: `Tool ${ctx.toolName} is blocked`,
|
|
47
|
+
duration: 0
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (options.allowedTools && options.allowedTools.length > 0 && !options.allowedTools.includes(ctx.toolName)) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: `Tool ${ctx.toolName} is not in allowed list`,
|
|
54
|
+
duration: 0
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return next();
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function composeMCPMiddleware(middlewares) {
|
|
61
|
+
return async (ctx, finalNext) => {
|
|
62
|
+
let index = -1;
|
|
63
|
+
const dispatch = async (i) => {
|
|
64
|
+
if (i <= index) {
|
|
65
|
+
throw new Error("next() called multiple times");
|
|
66
|
+
}
|
|
67
|
+
index = i;
|
|
68
|
+
const middleware = middlewares[i];
|
|
69
|
+
if (!middleware) {
|
|
70
|
+
return finalNext();
|
|
71
|
+
}
|
|
72
|
+
return middleware(ctx, () => dispatch(i + 1));
|
|
73
|
+
};
|
|
74
|
+
return dispatch(0);
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export {
|
|
79
|
+
createRateLimitMiddleware,
|
|
80
|
+
createAuditMiddleware,
|
|
81
|
+
createAccessControlMiddleware,
|
|
82
|
+
composeMCPMiddleware
|
|
83
|
+
};
|
|
@@ -541,90 +541,12 @@ var McpHost = class {
|
|
|
541
541
|
var toolConsentStore = new InMemoryToolConsentStore();
|
|
542
542
|
var mcpHost = new McpHost({ consent: toolConsentStore });
|
|
543
543
|
|
|
544
|
-
// src/middleware/mcpMiddleware.ts
|
|
545
|
-
function createRateLimitMiddleware(options) {
|
|
546
|
-
const requests = /* @__PURE__ */ new Map();
|
|
547
|
-
return async (ctx, next) => {
|
|
548
|
-
const key = `${ctx.tenantId || "anon"}:${ctx.userId || "anon"}`;
|
|
549
|
-
const now = Date.now();
|
|
550
|
-
let record = requests.get(key);
|
|
551
|
-
if (!record || now > record.resetAt) {
|
|
552
|
-
record = { count: 0, resetAt: now + options.windowMs };
|
|
553
|
-
requests.set(key, record);
|
|
554
|
-
}
|
|
555
|
-
record.count++;
|
|
556
|
-
if (record.count > options.maxRequests) {
|
|
557
|
-
return {
|
|
558
|
-
success: false,
|
|
559
|
-
error: `MCP rate limit exceeded. Max ${options.maxRequests} requests per ${options.windowMs / 1e3}s`,
|
|
560
|
-
duration: 0
|
|
561
|
-
};
|
|
562
|
-
}
|
|
563
|
-
return next();
|
|
564
|
-
};
|
|
565
|
-
}
|
|
566
|
-
function createAuditMiddleware(options) {
|
|
567
|
-
return async (ctx, next) => {
|
|
568
|
-
const result = await next();
|
|
569
|
-
const entry = {
|
|
570
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
571
|
-
requestId: ctx.requestId,
|
|
572
|
-
toolName: ctx.toolName,
|
|
573
|
-
arguments: ctx.arguments,
|
|
574
|
-
success: result.success,
|
|
575
|
-
duration: result.duration
|
|
576
|
-
};
|
|
577
|
-
if (ctx.tenantId) entry.tenantId = ctx.tenantId;
|
|
578
|
-
if (ctx.userId) entry.userId = ctx.userId;
|
|
579
|
-
if (result.error) entry.error = result.error;
|
|
580
|
-
Promise.resolve(options.onLog(entry)).catch(console.error);
|
|
581
|
-
return result;
|
|
582
|
-
};
|
|
583
|
-
}
|
|
584
|
-
function createAccessControlMiddleware(options) {
|
|
585
|
-
return async (ctx, next) => {
|
|
586
|
-
if (options.blockedTools?.includes(ctx.toolName)) {
|
|
587
|
-
return {
|
|
588
|
-
success: false,
|
|
589
|
-
error: `Tool ${ctx.toolName} is blocked`,
|
|
590
|
-
duration: 0
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
if (options.allowedTools && options.allowedTools.length > 0 && !options.allowedTools.includes(ctx.toolName)) {
|
|
594
|
-
return {
|
|
595
|
-
success: false,
|
|
596
|
-
error: `Tool ${ctx.toolName} is not in allowed list`,
|
|
597
|
-
duration: 0
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
return next();
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
function composeMCPMiddleware(middlewares) {
|
|
604
|
-
return async (ctx, finalNext) => {
|
|
605
|
-
let index = -1;
|
|
606
|
-
const dispatch = async (i) => {
|
|
607
|
-
if (i <= index) {
|
|
608
|
-
throw new Error("next() called multiple times");
|
|
609
|
-
}
|
|
610
|
-
index = i;
|
|
611
|
-
const middleware = middlewares[i];
|
|
612
|
-
if (!middleware) {
|
|
613
|
-
return finalNext();
|
|
614
|
-
}
|
|
615
|
-
return middleware(ctx, () => dispatch(i + 1));
|
|
616
|
-
};
|
|
617
|
-
return dispatch(0);
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
|
|
621
544
|
// src/server/uiAgentServer.ts
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
} from "@nebutra/ui/agent";
|
|
545
|
+
var uiAgentModule;
|
|
546
|
+
function loadUiAgent() {
|
|
547
|
+
uiAgentModule ??= import("@nebutra/ui/agent");
|
|
548
|
+
return uiAgentModule;
|
|
549
|
+
}
|
|
628
550
|
function readContractOptions(args) {
|
|
629
551
|
const options = {
|
|
630
552
|
root: typeof args.root === "string" ? args.root : process.cwd()
|
|
@@ -641,7 +563,8 @@ function readName(args) {
|
|
|
641
563
|
}
|
|
642
564
|
return name;
|
|
643
565
|
}
|
|
644
|
-
function validateAll(args) {
|
|
566
|
+
async function validateAll(args) {
|
|
567
|
+
const { loadAgentComponentContract, loadAgentManifest, validateAgentComponent } = await loadUiAgent();
|
|
645
568
|
const options = readContractOptions(args);
|
|
646
569
|
const manifest = loadAgentManifest(options);
|
|
647
570
|
const results = manifest.components.map(
|
|
@@ -729,6 +652,7 @@ function createUiAgentMcpServer() {
|
|
|
729
652
|
],
|
|
730
653
|
handlers: {
|
|
731
654
|
nebutra_ui_search_components: async (args) => {
|
|
655
|
+
const { loadAgentManifest, searchAgentComponents } = await loadUiAgent();
|
|
732
656
|
const manifest = loadAgentManifest(readContractOptions(args));
|
|
733
657
|
const searchOptions = {
|
|
734
658
|
limit: typeof args.limit === "number" ? args.limit : 20,
|
|
@@ -745,8 +669,12 @@ function createUiAgentMcpServer() {
|
|
|
745
669
|
searchOptions
|
|
746
670
|
);
|
|
747
671
|
},
|
|
748
|
-
nebutra_ui_get_component: async (args) =>
|
|
672
|
+
nebutra_ui_get_component: async (args) => {
|
|
673
|
+
const { loadAgentComponentContract } = await loadUiAgent();
|
|
674
|
+
return loadAgentComponentContract(readName(args), readContractOptions(args));
|
|
675
|
+
},
|
|
749
676
|
nebutra_ui_validate_component: async (args) => {
|
|
677
|
+
const { loadAgentComponentContract, validateAgentComponent } = await loadUiAgent();
|
|
750
678
|
if (typeof args.name === "string" && args.name.trim().length > 0) {
|
|
751
679
|
return validateAgentComponent(
|
|
752
680
|
loadAgentComponentContract(args.name, readContractOptions(args))
|
|
@@ -755,6 +683,7 @@ function createUiAgentMcpServer() {
|
|
|
755
683
|
return validateAll(args);
|
|
756
684
|
},
|
|
757
685
|
nebutra_ui_get_migration_hints: async (args) => {
|
|
686
|
+
const { loadAgentComponentContract } = await loadUiAgent();
|
|
758
687
|
const contract = loadAgentComponentContract(readName(args), readContractOptions(args));
|
|
759
688
|
return {
|
|
760
689
|
component: contract.name,
|
|
@@ -856,10 +785,6 @@ export {
|
|
|
856
785
|
McpHost,
|
|
857
786
|
toolConsentStore,
|
|
858
787
|
mcpHost,
|
|
859
|
-
createRateLimitMiddleware,
|
|
860
|
-
createAuditMiddleware,
|
|
861
|
-
createAccessControlMiddleware,
|
|
862
|
-
composeMCPMiddleware,
|
|
863
788
|
INTERNAL_SERVERS,
|
|
864
789
|
registerInternalServers,
|
|
865
790
|
getInternalServerIds,
|
package/dist/cli.js
CHANGED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const ToolParameterSchema: z.ZodObject<{
|
|
4
|
+
type: z.ZodEnum<{
|
|
5
|
+
string: "string";
|
|
6
|
+
number: "number";
|
|
7
|
+
boolean: "boolean";
|
|
8
|
+
object: "object";
|
|
9
|
+
array: "array";
|
|
10
|
+
}>;
|
|
11
|
+
description: z.ZodOptional<z.ZodString>;
|
|
12
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
default: z.ZodOptional<z.ZodAny>;
|
|
14
|
+
}, z.core.$strip>;
|
|
15
|
+
declare const ToolDefinitionSchema: z.ZodObject<{
|
|
16
|
+
name: z.ZodString;
|
|
17
|
+
description: z.ZodString;
|
|
18
|
+
parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
19
|
+
type: z.ZodEnum<{
|
|
20
|
+
string: "string";
|
|
21
|
+
number: "number";
|
|
22
|
+
boolean: "boolean";
|
|
23
|
+
object: "object";
|
|
24
|
+
array: "array";
|
|
25
|
+
}>;
|
|
26
|
+
description: z.ZodOptional<z.ZodString>;
|
|
27
|
+
required: z.ZodOptional<z.ZodBoolean>;
|
|
28
|
+
default: z.ZodOptional<z.ZodAny>;
|
|
29
|
+
}, z.core.$strip>>>;
|
|
30
|
+
returns: z.ZodOptional<z.ZodString>;
|
|
31
|
+
allowedPlans: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
allowedTenants: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
requiredPermissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
+
}, z.core.$strip>;
|
|
35
|
+
type ToolParameter = z.infer<typeof ToolParameterSchema>;
|
|
36
|
+
type ToolDefinition = z.infer<typeof ToolDefinitionSchema>;
|
|
37
|
+
interface MCPRequest {
|
|
38
|
+
id: string;
|
|
39
|
+
method: string;
|
|
40
|
+
params?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
interface MCPResponse {
|
|
43
|
+
id: string;
|
|
44
|
+
result?: unknown;
|
|
45
|
+
error?: MCPError;
|
|
46
|
+
}
|
|
47
|
+
interface MCPError {
|
|
48
|
+
code: number;
|
|
49
|
+
message: string;
|
|
50
|
+
data?: unknown;
|
|
51
|
+
}
|
|
52
|
+
interface MCPContext {
|
|
53
|
+
requestId: string;
|
|
54
|
+
tenantId?: string;
|
|
55
|
+
userId?: string;
|
|
56
|
+
plan?: string;
|
|
57
|
+
permissions?: string[];
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
interface ToolExecutionRequest {
|
|
61
|
+
tool: string;
|
|
62
|
+
arguments: Record<string, unknown>;
|
|
63
|
+
context: MCPContext;
|
|
64
|
+
}
|
|
65
|
+
interface ToolExecutionResult {
|
|
66
|
+
success: boolean;
|
|
67
|
+
result?: unknown;
|
|
68
|
+
error?: string;
|
|
69
|
+
duration: number;
|
|
70
|
+
tokensUsed?: number;
|
|
71
|
+
}
|
|
72
|
+
interface MCPServerManifest {
|
|
73
|
+
name: string;
|
|
74
|
+
version: string;
|
|
75
|
+
scopes: string[];
|
|
76
|
+
homepage?: string;
|
|
77
|
+
}
|
|
78
|
+
interface MCPServerConfig {
|
|
79
|
+
id: string;
|
|
80
|
+
name: string;
|
|
81
|
+
description: string;
|
|
82
|
+
endpoint: string;
|
|
83
|
+
transport: "http" | "websocket" | "stdio" | "local";
|
|
84
|
+
manifest?: MCPServerManifest;
|
|
85
|
+
tools: ToolDefinition[];
|
|
86
|
+
handlers?: Record<string, MCPToolHandler>;
|
|
87
|
+
authentication?: {
|
|
88
|
+
type: "bearer" | "api-key" | "none";
|
|
89
|
+
headerName?: string;
|
|
90
|
+
};
|
|
91
|
+
rateLimit?: {
|
|
92
|
+
maxRequests: number;
|
|
93
|
+
windowMs: number;
|
|
94
|
+
};
|
|
95
|
+
allowedPlans?: string[];
|
|
96
|
+
allowedTenants?: string[];
|
|
97
|
+
}
|
|
98
|
+
type MCPToolHandler = (args: Record<string, unknown>, context: MCPContext) => unknown | Promise<unknown>;
|
|
99
|
+
interface SmitheryServerInfo {
|
|
100
|
+
qualifiedName: string;
|
|
101
|
+
displayName: string;
|
|
102
|
+
description: string;
|
|
103
|
+
homepage?: string;
|
|
104
|
+
useCount?: number;
|
|
105
|
+
isDeployed?: boolean;
|
|
106
|
+
}
|
|
107
|
+
interface SmitheryConfig {
|
|
108
|
+
apiKey?: string;
|
|
109
|
+
baseUrl: string;
|
|
110
|
+
defaultServers?: string[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* MCP Middleware for rate limiting, audit logging, and access control
|
|
115
|
+
*/
|
|
116
|
+
interface MCPMiddlewareContext extends MCPContext {
|
|
117
|
+
toolName: string;
|
|
118
|
+
arguments: Record<string, unknown>;
|
|
119
|
+
}
|
|
120
|
+
type MCPMiddlewareNext = () => Promise<ToolExecutionResult>;
|
|
121
|
+
type MCPMiddleware = (ctx: MCPMiddlewareContext, next: MCPMiddlewareNext) => Promise<ToolExecutionResult>;
|
|
122
|
+
/**
|
|
123
|
+
* Rate limiting middleware for MCP calls
|
|
124
|
+
*/
|
|
125
|
+
declare function createRateLimitMiddleware(options: {
|
|
126
|
+
maxRequests: number;
|
|
127
|
+
windowMs: number;
|
|
128
|
+
}): MCPMiddleware;
|
|
129
|
+
/**
|
|
130
|
+
* Audit logging middleware
|
|
131
|
+
*/
|
|
132
|
+
declare function createAuditMiddleware(options: {
|
|
133
|
+
onLog: (entry: AuditLogEntry) => void | Promise<void>;
|
|
134
|
+
}): MCPMiddleware;
|
|
135
|
+
interface AuditLogEntry {
|
|
136
|
+
timestamp: string;
|
|
137
|
+
requestId: string;
|
|
138
|
+
tenantId?: string;
|
|
139
|
+
userId?: string;
|
|
140
|
+
toolName: string;
|
|
141
|
+
arguments: Record<string, unknown>;
|
|
142
|
+
success: boolean;
|
|
143
|
+
duration: number;
|
|
144
|
+
error?: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Tool access control middleware
|
|
148
|
+
*/
|
|
149
|
+
declare function createAccessControlMiddleware(options: {
|
|
150
|
+
blockedTools?: string[];
|
|
151
|
+
allowedTools?: string[];
|
|
152
|
+
}): MCPMiddleware;
|
|
153
|
+
/**
|
|
154
|
+
* Compose multiple middlewares
|
|
155
|
+
*/
|
|
156
|
+
declare function composeMCPMiddleware(middlewares: MCPMiddleware[]): MCPMiddleware;
|
|
157
|
+
|
|
158
|
+
export { type AuditLogEntry as A, type MCPServerConfig as M, type SmitheryConfig as S, type ToolDefinition as T, type MCPContext as a, type ToolExecutionResult as b, type MCPServerManifest as c, type MCPToolHandler as d, type MCPError as e, type MCPMiddleware as f, type MCPMiddlewareContext as g, type MCPRequest as h, type MCPResponse as i, type SmitheryServerInfo as j, ToolDefinitionSchema as k, type ToolExecutionRequest as l, type ToolParameter as m, ToolParameterSchema as n, composeMCPMiddleware as o, createAccessControlMiddleware as p, createAuditMiddleware as q, createRateLimitMiddleware as r, type MCPMiddlewareNext as s };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,116 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { M as MCPServerConfig, T as ToolDefinition, a as MCPContext, b as ToolExecutionResult, c as MCPServerManifest, d as MCPToolHandler } from './index-BD_aLZKz.js';
|
|
2
|
+
export { A as AuditLogEntry, e as MCPError, f as MCPMiddleware, g as MCPMiddlewareContext, h as MCPRequest, i as MCPResponse, S as SmitheryConfig, j as SmitheryServerInfo, k as ToolDefinitionSchema, l as ToolExecutionRequest, m as ToolParameter, n as ToolParameterSchema, o as composeMCPMiddleware, p as createAccessControlMiddleware, q as createAuditMiddleware, r as createRateLimitMiddleware } from './index-BD_aLZKz.js';
|
|
2
3
|
import { EventLog } from '@nebutra/event-log';
|
|
3
4
|
import { TraceStore } from '@nebutra/trace-store';
|
|
4
|
-
|
|
5
|
-
declare const ToolParameterSchema: z.ZodObject<{
|
|
6
|
-
type: z.ZodEnum<{
|
|
7
|
-
string: "string";
|
|
8
|
-
number: "number";
|
|
9
|
-
boolean: "boolean";
|
|
10
|
-
object: "object";
|
|
11
|
-
array: "array";
|
|
12
|
-
}>;
|
|
13
|
-
description: z.ZodOptional<z.ZodString>;
|
|
14
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
15
|
-
default: z.ZodOptional<z.ZodAny>;
|
|
16
|
-
}, z.core.$strip>;
|
|
17
|
-
declare const ToolDefinitionSchema: z.ZodObject<{
|
|
18
|
-
name: z.ZodString;
|
|
19
|
-
description: z.ZodString;
|
|
20
|
-
parameters: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
21
|
-
type: z.ZodEnum<{
|
|
22
|
-
string: "string";
|
|
23
|
-
number: "number";
|
|
24
|
-
boolean: "boolean";
|
|
25
|
-
object: "object";
|
|
26
|
-
array: "array";
|
|
27
|
-
}>;
|
|
28
|
-
description: z.ZodOptional<z.ZodString>;
|
|
29
|
-
required: z.ZodOptional<z.ZodBoolean>;
|
|
30
|
-
default: z.ZodOptional<z.ZodAny>;
|
|
31
|
-
}, z.core.$strip>>>;
|
|
32
|
-
returns: z.ZodOptional<z.ZodString>;
|
|
33
|
-
allowedPlans: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
34
|
-
allowedTenants: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
35
|
-
requiredPermissions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
36
|
-
}, z.core.$strip>;
|
|
37
|
-
type ToolParameter = z.infer<typeof ToolParameterSchema>;
|
|
38
|
-
type ToolDefinition = z.infer<typeof ToolDefinitionSchema>;
|
|
39
|
-
interface MCPRequest {
|
|
40
|
-
id: string;
|
|
41
|
-
method: string;
|
|
42
|
-
params?: Record<string, unknown>;
|
|
43
|
-
}
|
|
44
|
-
interface MCPResponse {
|
|
45
|
-
id: string;
|
|
46
|
-
result?: unknown;
|
|
47
|
-
error?: MCPError;
|
|
48
|
-
}
|
|
49
|
-
interface MCPError {
|
|
50
|
-
code: number;
|
|
51
|
-
message: string;
|
|
52
|
-
data?: unknown;
|
|
53
|
-
}
|
|
54
|
-
interface MCPContext {
|
|
55
|
-
requestId: string;
|
|
56
|
-
tenantId?: string;
|
|
57
|
-
userId?: string;
|
|
58
|
-
plan?: string;
|
|
59
|
-
permissions?: string[];
|
|
60
|
-
metadata?: Record<string, unknown>;
|
|
61
|
-
}
|
|
62
|
-
interface ToolExecutionRequest {
|
|
63
|
-
tool: string;
|
|
64
|
-
arguments: Record<string, unknown>;
|
|
65
|
-
context: MCPContext;
|
|
66
|
-
}
|
|
67
|
-
interface ToolExecutionResult {
|
|
68
|
-
success: boolean;
|
|
69
|
-
result?: unknown;
|
|
70
|
-
error?: string;
|
|
71
|
-
duration: number;
|
|
72
|
-
tokensUsed?: number;
|
|
73
|
-
}
|
|
74
|
-
interface MCPServerManifest {
|
|
75
|
-
name: string;
|
|
76
|
-
version: string;
|
|
77
|
-
scopes: string[];
|
|
78
|
-
homepage?: string;
|
|
79
|
-
}
|
|
80
|
-
interface MCPServerConfig {
|
|
81
|
-
id: string;
|
|
82
|
-
name: string;
|
|
83
|
-
description: string;
|
|
84
|
-
endpoint: string;
|
|
85
|
-
transport: "http" | "websocket" | "stdio" | "local";
|
|
86
|
-
manifest?: MCPServerManifest;
|
|
87
|
-
tools: ToolDefinition[];
|
|
88
|
-
handlers?: Record<string, MCPToolHandler>;
|
|
89
|
-
authentication?: {
|
|
90
|
-
type: "bearer" | "api-key" | "none";
|
|
91
|
-
headerName?: string;
|
|
92
|
-
};
|
|
93
|
-
rateLimit?: {
|
|
94
|
-
maxRequests: number;
|
|
95
|
-
windowMs: number;
|
|
96
|
-
};
|
|
97
|
-
allowedPlans?: string[];
|
|
98
|
-
allowedTenants?: string[];
|
|
99
|
-
}
|
|
100
|
-
type MCPToolHandler = (args: Record<string, unknown>, context: MCPContext) => unknown | Promise<unknown>;
|
|
101
|
-
interface SmitheryServerInfo {
|
|
102
|
-
qualifiedName: string;
|
|
103
|
-
displayName: string;
|
|
104
|
-
description: string;
|
|
105
|
-
homepage?: string;
|
|
106
|
-
useCount?: number;
|
|
107
|
-
isDeployed?: boolean;
|
|
108
|
-
}
|
|
109
|
-
interface SmitheryConfig {
|
|
110
|
-
apiKey?: string;
|
|
111
|
-
baseUrl: string;
|
|
112
|
-
defaultServers?: string[];
|
|
113
|
-
}
|
|
5
|
+
import 'zod';
|
|
114
6
|
|
|
115
7
|
/**
|
|
116
8
|
* Registry for MCP servers and their tools
|
|
@@ -329,51 +221,6 @@ declare class McpHost {
|
|
|
329
221
|
declare const toolConsentStore: InMemoryToolConsentStore;
|
|
330
222
|
declare const mcpHost: McpHost;
|
|
331
223
|
|
|
332
|
-
/**
|
|
333
|
-
* MCP Middleware for rate limiting, audit logging, and access control
|
|
334
|
-
*/
|
|
335
|
-
interface MCPMiddlewareContext extends MCPContext {
|
|
336
|
-
toolName: string;
|
|
337
|
-
arguments: Record<string, unknown>;
|
|
338
|
-
}
|
|
339
|
-
type MCPMiddlewareNext = () => Promise<ToolExecutionResult>;
|
|
340
|
-
type MCPMiddleware = (ctx: MCPMiddlewareContext, next: MCPMiddlewareNext) => Promise<ToolExecutionResult>;
|
|
341
|
-
/**
|
|
342
|
-
* Rate limiting middleware for MCP calls
|
|
343
|
-
*/
|
|
344
|
-
declare function createRateLimitMiddleware(options: {
|
|
345
|
-
maxRequests: number;
|
|
346
|
-
windowMs: number;
|
|
347
|
-
}): MCPMiddleware;
|
|
348
|
-
/**
|
|
349
|
-
* Audit logging middleware
|
|
350
|
-
*/
|
|
351
|
-
declare function createAuditMiddleware(options: {
|
|
352
|
-
onLog: (entry: AuditLogEntry) => void | Promise<void>;
|
|
353
|
-
}): MCPMiddleware;
|
|
354
|
-
interface AuditLogEntry {
|
|
355
|
-
timestamp: string;
|
|
356
|
-
requestId: string;
|
|
357
|
-
tenantId?: string;
|
|
358
|
-
userId?: string;
|
|
359
|
-
toolName: string;
|
|
360
|
-
arguments: Record<string, unknown>;
|
|
361
|
-
success: boolean;
|
|
362
|
-
duration: number;
|
|
363
|
-
error?: string;
|
|
364
|
-
}
|
|
365
|
-
/**
|
|
366
|
-
* Tool access control middleware
|
|
367
|
-
*/
|
|
368
|
-
declare function createAccessControlMiddleware(options: {
|
|
369
|
-
blockedTools?: string[];
|
|
370
|
-
allowedTools?: string[];
|
|
371
|
-
}): MCPMiddleware;
|
|
372
|
-
/**
|
|
373
|
-
* Compose multiple middlewares
|
|
374
|
-
*/
|
|
375
|
-
declare function composeMCPMiddleware(middlewares: MCPMiddleware[]): MCPMiddleware;
|
|
376
|
-
|
|
377
224
|
/**
|
|
378
225
|
* Register internal Nebutra services as MCP servers
|
|
379
226
|
* These wrap our existing microservices with MCP-compatible interfaces
|
|
@@ -388,4 +235,4 @@ declare function registerInternalServers(): void;
|
|
|
388
235
|
*/
|
|
389
236
|
declare function getInternalServerIds(): string[];
|
|
390
237
|
|
|
391
|
-
export {
|
|
238
|
+
export { INTERNAL_SERVERS, InMemoryToolConsentStore, MCPClient, MCPContext, MCPServerConfig, MCPServerManifest, MCPServerRegistry, MCPToolHandler, McpHost, type ToolConsentGrant, type ToolConsentStore, type ToolDebugEntry, ToolDefinition, ToolExecutionResult, appendToolDebug, getInternalServerIds, mcpClient, mcpHost, readToolDebug, registerInternalServers, serverRegistry, toolConsentStore, toolDebugPath };
|
package/dist/index.js
CHANGED
|
@@ -7,10 +7,6 @@ import {
|
|
|
7
7
|
ToolDefinitionSchema,
|
|
8
8
|
ToolParameterSchema,
|
|
9
9
|
appendToolDebug,
|
|
10
|
-
composeMCPMiddleware,
|
|
11
|
-
createAccessControlMiddleware,
|
|
12
|
-
createAuditMiddleware,
|
|
13
|
-
createRateLimitMiddleware,
|
|
14
10
|
getInternalServerIds,
|
|
15
11
|
mcpClient,
|
|
16
12
|
mcpHost,
|
|
@@ -19,7 +15,13 @@ import {
|
|
|
19
15
|
serverRegistry,
|
|
20
16
|
toolConsentStore,
|
|
21
17
|
toolDebugPath
|
|
22
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-ZTLLKBBG.js";
|
|
19
|
+
import {
|
|
20
|
+
composeMCPMiddleware,
|
|
21
|
+
createAccessControlMiddleware,
|
|
22
|
+
createAuditMiddleware,
|
|
23
|
+
createRateLimitMiddleware
|
|
24
|
+
} from "./chunk-EMIF5K3P.js";
|
|
23
25
|
export {
|
|
24
26
|
INTERNAL_SERVERS,
|
|
25
27
|
InMemoryToolConsentStore,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import {
|
|
2
|
+
composeMCPMiddleware,
|
|
3
|
+
createAccessControlMiddleware,
|
|
4
|
+
createAuditMiddleware,
|
|
5
|
+
createRateLimitMiddleware
|
|
6
|
+
} from "../chunk-EMIF5K3P.js";
|
|
7
|
+
export {
|
|
8
|
+
composeMCPMiddleware,
|
|
9
|
+
createAccessControlMiddleware,
|
|
10
|
+
createAuditMiddleware,
|
|
11
|
+
createRateLimitMiddleware
|
|
12
|
+
};
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebutra/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"nebutra": {
|
|
8
|
+
"graph": "runtime",
|
|
8
9
|
"status": "wip",
|
|
9
10
|
"productionReady": false,
|
|
10
11
|
"requires": [
|
|
@@ -27,20 +28,24 @@
|
|
|
27
28
|
"types": "./dist/index.d.ts",
|
|
28
29
|
"import": "./dist/index.js",
|
|
29
30
|
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./middleware": {
|
|
33
|
+
"types": "./dist/middleware/index.d.ts",
|
|
34
|
+
"import": "./dist/middleware/index.js",
|
|
35
|
+
"default": "./dist/middleware/index.js"
|
|
30
36
|
}
|
|
31
37
|
},
|
|
32
38
|
"bin": {
|
|
33
|
-
"nebutra-mcp": "./
|
|
34
|
-
"nebutra-tool-protocol": "./
|
|
39
|
+
"nebutra-mcp": "./bin/nebutra-mcp.js",
|
|
40
|
+
"nebutra-tool-protocol": "./bin/nebutra-tool-protocol.js"
|
|
35
41
|
},
|
|
36
42
|
"dependencies": {
|
|
37
43
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
38
44
|
"zod": "^4.3.6",
|
|
39
|
-
"@nebutra/capability-kit": "0.
|
|
40
|
-
"@nebutra/errors": "0.
|
|
41
|
-
"@nebutra/event-log": "0.
|
|
42
|
-
"@nebutra/trace-store": "0.
|
|
43
|
-
"@nebutra/ui": "0.2.2"
|
|
45
|
+
"@nebutra/capability-kit": "3.0.0",
|
|
46
|
+
"@nebutra/errors": "3.0.0",
|
|
47
|
+
"@nebutra/event-log": "3.0.0",
|
|
48
|
+
"@nebutra/trace-store": "3.0.0"
|
|
44
49
|
},
|
|
45
50
|
"devDependencies": {
|
|
46
51
|
"tsup": "^8.5.1",
|
|
@@ -60,11 +65,20 @@
|
|
|
60
65
|
"access": "public"
|
|
61
66
|
},
|
|
62
67
|
"files": [
|
|
68
|
+
"bin",
|
|
63
69
|
"dist",
|
|
64
70
|
"README.md",
|
|
65
71
|
"LICENSE",
|
|
66
72
|
"CHANGELOG.md"
|
|
67
73
|
],
|
|
74
|
+
"peerDependencies": {
|
|
75
|
+
"@nebutra/ui": "3.0.0"
|
|
76
|
+
},
|
|
77
|
+
"peerDependenciesMeta": {
|
|
78
|
+
"@nebutra/ui": {
|
|
79
|
+
"optional": true
|
|
80
|
+
}
|
|
81
|
+
},
|
|
68
82
|
"scripts": {
|
|
69
83
|
"build": "tsup",
|
|
70
84
|
"dev": "tsup --watch",
|