@nebutra/mcp 0.1.4 → 2.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 +11 -0
- package/bin/nebutra-mcp.js +28 -0
- package/bin/nebutra-tool-protocol.js +27 -0
- package/dist/{chunk-25TNKUCR.js → chunk-7A2G4AGA.js} +0 -81
- package/dist/chunk-EMIF5K3P.js +83 -0
- 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,16 @@
|
|
|
1
1
|
# @nebutra/mcp
|
|
2
2
|
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies []:
|
|
8
|
+
- @nebutra/ui@2.0.0
|
|
9
|
+
- @nebutra/capability-kit@2.0.0
|
|
10
|
+
- @nebutra/errors@2.0.0
|
|
11
|
+
- @nebutra/event-log@2.0.0
|
|
12
|
+
- @nebutra/trace-store@2.0.0
|
|
13
|
+
|
|
3
14
|
## 0.1.3
|
|
4
15
|
|
|
5
16
|
### 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);
|
|
@@ -541,83 +541,6 @@ 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
545
|
import {
|
|
623
546
|
loadAgentComponentContract,
|
|
@@ -856,10 +779,6 @@ export {
|
|
|
856
779
|
McpHost,
|
|
857
780
|
toolConsentStore,
|
|
858
781
|
mcpHost,
|
|
859
|
-
createRateLimitMiddleware,
|
|
860
|
-
createAuditMiddleware,
|
|
861
|
-
createAccessControlMiddleware,
|
|
862
|
-
composeMCPMiddleware,
|
|
863
782
|
INTERNAL_SERVERS,
|
|
864
783
|
registerInternalServers,
|
|
865
784
|
getInternalServerIds,
|
|
@@ -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
|
+
};
|
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-7A2G4AGA.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": "2.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": "2.0.0",
|
|
46
|
+
"@nebutra/errors": "2.0.0",
|
|
47
|
+
"@nebutra/event-log": "2.0.0",
|
|
48
|
+
"@nebutra/trace-store": "2.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": "2.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",
|