@bighub/bighub-mcp 0.1.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/README.md +59 -0
- package/dist/httpClient.js +174 -0
- package/dist/index.js +48 -0
- package/dist/registerTools.js +548 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @bighub/bighub-mcp
|
|
2
|
+
|
|
3
|
+
Official MCP server for BIGHUB governance APIs.
|
|
4
|
+
|
|
5
|
+
This package exposes MCP tools that call `https://api.bighub.io` for governance operations:
|
|
6
|
+
actions, rules, approvals, kill switch, events, API keys, webhooks, and auth.
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @bighub/bighub-mcp
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Local development
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install
|
|
18
|
+
npm run test
|
|
19
|
+
npm run check
|
|
20
|
+
npm run build
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Run in stdio mode:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm run start
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Environment variables
|
|
30
|
+
|
|
31
|
+
- `BIGHUB_API_KEY` - preferred auth method (`X-API-Key`)
|
|
32
|
+
- `BIGHUB_BEARER_TOKEN` - optional auth method (`Authorization: Bearer ...`)
|
|
33
|
+
- `BIGHUB_BASE_URL` - defaults to `https://api.bighub.io`
|
|
34
|
+
- `BIGHUB_TIMEOUT_MS` - HTTP timeout (default: `15000`)
|
|
35
|
+
- `BIGHUB_MAX_RETRIES` - retry count on transient failures (default: `2`)
|
|
36
|
+
- `BIGHUB_ALLOW_INSECURE_HTTP` - only for localhost/private host testing
|
|
37
|
+
|
|
38
|
+
## Tool coverage
|
|
39
|
+
|
|
40
|
+
- **Actions:** submit, submit_v2, dry_run, status, verify, stats, dashboard summary
|
|
41
|
+
- **Future Memory:** ingest, context, refresh aggregates, recommendations
|
|
42
|
+
- **Rules:** create/list/get/update/delete/pause/resume/validate/dry-run/versions/domains/apply_patch/purge_idempotency
|
|
43
|
+
- **Approvals:** list, resolve
|
|
44
|
+
- **Kill switch:** status, activate, deactivate
|
|
45
|
+
- **Events:** list, stats
|
|
46
|
+
- **API keys:** create, list, delete, rotate, validate, scopes
|
|
47
|
+
- **Webhooks:** create, list, get, update, delete, deliveries, test, list_events, verify_signature, replay
|
|
48
|
+
- **Auth:** signup, login, refresh, logout
|
|
49
|
+
- **Fallback:** generic `bighub_http_request` tool for endpoints not yet wrapped
|
|
50
|
+
|
|
51
|
+
## Notes
|
|
52
|
+
|
|
53
|
+
- Tools are one-to-one wrappers over BIGHUB HTTP endpoints.
|
|
54
|
+
- Retries use exponential backoff with jitter for transient errors.
|
|
55
|
+
- Errors preserve structured metadata when returned by the API.
|
|
56
|
+
|
|
57
|
+
## Links
|
|
58
|
+
|
|
59
|
+
- [Main README](../../README.md)
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
export class BighubHttpError extends Error {
|
|
2
|
+
statusCode;
|
|
3
|
+
requestId;
|
|
4
|
+
code;
|
|
5
|
+
responseBody;
|
|
6
|
+
constructor(message, options) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "BighubHttpError";
|
|
9
|
+
this.statusCode = options?.statusCode;
|
|
10
|
+
this.requestId = options?.requestId;
|
|
11
|
+
this.code = options?.code;
|
|
12
|
+
this.responseBody = options?.responseBody;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const RETRYABLE_STATUS_CODES = new Set([408, 409, 425, 429, 500, 502, 503, 504]);
|
|
16
|
+
function sleep(ms) {
|
|
17
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
18
|
+
}
|
|
19
|
+
function shouldRetry(statusCode, err) {
|
|
20
|
+
if (err !== undefined) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return statusCode !== undefined && RETRYABLE_STATUS_CODES.has(statusCode);
|
|
24
|
+
}
|
|
25
|
+
function buildRetryDelayMs(attempt) {
|
|
26
|
+
const base = 250;
|
|
27
|
+
const cap = 2500;
|
|
28
|
+
const delay = Math.min(cap, base * 2 ** Math.max(0, attempt - 1));
|
|
29
|
+
const jitter = Math.random() * Math.min(250, delay / 2);
|
|
30
|
+
return delay + jitter;
|
|
31
|
+
}
|
|
32
|
+
function ensureSecureBaseUrl(baseUrl) {
|
|
33
|
+
const url = new URL(baseUrl);
|
|
34
|
+
const scheme = url.protocol.replace(":", "").toLowerCase();
|
|
35
|
+
const host = (url.hostname || "").toLowerCase();
|
|
36
|
+
const allowInsecure = new Set(["1", "true", "yes", "on"]).has((process.env.BIGHUB_ALLOW_INSECURE_HTTP || "").trim().toLowerCase());
|
|
37
|
+
const localhost = host === "localhost" || host === "127.0.0.1";
|
|
38
|
+
const privateHost = host.endsWith(".local");
|
|
39
|
+
if (scheme !== "https" && !(localhost || (allowInsecure && privateHost))) {
|
|
40
|
+
throw new Error("Insecure base_url is not allowed. Use https:// or set BIGHUB_ALLOW_INSECURE_HTTP=true only for localhost/private hosts.");
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function buildUrl(baseUrl, path, query) {
|
|
44
|
+
const url = new URL(`${baseUrl.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`);
|
|
45
|
+
if (query) {
|
|
46
|
+
for (const [key, value] of Object.entries(query)) {
|
|
47
|
+
if (value === undefined || value === null) {
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(value)) {
|
|
51
|
+
for (const item of value) {
|
|
52
|
+
if (item !== undefined && item !== null) {
|
|
53
|
+
url.searchParams.append(key, String(item));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
url.searchParams.set(key, String(value));
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return url.toString();
|
|
63
|
+
}
|
|
64
|
+
function extractErrorMetadata(body) {
|
|
65
|
+
if (!body || typeof body !== "object") {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
const value = body;
|
|
69
|
+
const detail = value.detail;
|
|
70
|
+
const requestId = (typeof value.request_id === "string" ? value.request_id : undefined) ||
|
|
71
|
+
(typeof value.validation_id === "string" ? value.validation_id : undefined) ||
|
|
72
|
+
(value.error && typeof value.error === "object" && typeof value.error.request_id === "string"
|
|
73
|
+
? value.error.request_id
|
|
74
|
+
: undefined);
|
|
75
|
+
const code = detail && typeof detail === "object" && typeof detail.code === "string"
|
|
76
|
+
? detail.code
|
|
77
|
+
: undefined;
|
|
78
|
+
return { requestId, code, detail };
|
|
79
|
+
}
|
|
80
|
+
async function parseResponseBody(response) {
|
|
81
|
+
const contentType = response.headers.get("content-type") || "";
|
|
82
|
+
if (contentType.includes("application/json")) {
|
|
83
|
+
try {
|
|
84
|
+
return await response.json();
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const text = await response.text();
|
|
91
|
+
return text ? { text } : {};
|
|
92
|
+
}
|
|
93
|
+
export class BighubHttpClient {
|
|
94
|
+
config;
|
|
95
|
+
constructor(config) {
|
|
96
|
+
ensureSecureBaseUrl(config.baseUrl);
|
|
97
|
+
this.config = config;
|
|
98
|
+
}
|
|
99
|
+
async request(options) {
|
|
100
|
+
const url = buildUrl(this.config.baseUrl, options.path, options.query);
|
|
101
|
+
const headers = {
|
|
102
|
+
Accept: "application/json",
|
|
103
|
+
"User-Agent": this.config.userAgent,
|
|
104
|
+
...(options.headers || {}),
|
|
105
|
+
};
|
|
106
|
+
if (this.config.apiKey) {
|
|
107
|
+
headers["X-API-Key"] = this.config.apiKey;
|
|
108
|
+
}
|
|
109
|
+
else if (this.config.bearerToken) {
|
|
110
|
+
headers.Authorization = `Bearer ${this.config.bearerToken}`;
|
|
111
|
+
}
|
|
112
|
+
if (options.idempotencyKey) {
|
|
113
|
+
headers["Idempotency-Key"] = options.idempotencyKey;
|
|
114
|
+
}
|
|
115
|
+
if (options.body !== undefined) {
|
|
116
|
+
headers["Content-Type"] = "application/json";
|
|
117
|
+
}
|
|
118
|
+
let lastError;
|
|
119
|
+
for (let attempt = 1; attempt <= this.config.maxRetries + 1; attempt += 1) {
|
|
120
|
+
const controller = new AbortController();
|
|
121
|
+
const timeoutId = setTimeout(() => controller.abort(), this.config.timeoutMs);
|
|
122
|
+
try {
|
|
123
|
+
const response = await fetch(url, {
|
|
124
|
+
method: options.method,
|
|
125
|
+
headers,
|
|
126
|
+
body: options.body !== undefined ? JSON.stringify(options.body) : undefined,
|
|
127
|
+
signal: controller.signal,
|
|
128
|
+
});
|
|
129
|
+
clearTimeout(timeoutId);
|
|
130
|
+
if (shouldRetry(response.status) && attempt <= this.config.maxRetries) {
|
|
131
|
+
await sleep(buildRetryDelayMs(attempt));
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
const body = await parseResponseBody(response);
|
|
135
|
+
if (response.ok) {
|
|
136
|
+
return body;
|
|
137
|
+
}
|
|
138
|
+
const { requestId, code, detail } = extractErrorMetadata(body);
|
|
139
|
+
const message = typeof detail === "string" ? detail : response.statusText || "API error";
|
|
140
|
+
throw new BighubHttpError(message, {
|
|
141
|
+
statusCode: response.status,
|
|
142
|
+
requestId,
|
|
143
|
+
code,
|
|
144
|
+
responseBody: body,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
clearTimeout(timeoutId);
|
|
149
|
+
lastError = error;
|
|
150
|
+
const isAbort = error instanceof DOMException && error.name === "AbortError";
|
|
151
|
+
const retryable = shouldRetry(undefined, error);
|
|
152
|
+
if (isAbort) {
|
|
153
|
+
if (attempt <= this.config.maxRetries) {
|
|
154
|
+
await sleep(buildRetryDelayMs(attempt));
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
throw new BighubHttpError(`Request timed out: ${options.method} ${options.path}`);
|
|
158
|
+
}
|
|
159
|
+
if (retryable && attempt <= this.config.maxRetries) {
|
|
160
|
+
await sleep(buildRetryDelayMs(attempt));
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (error instanceof BighubHttpError) {
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
throw new BighubHttpError(`Network error: ${options.method} ${options.path}`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
if (lastError instanceof BighubHttpError) {
|
|
170
|
+
throw lastError;
|
|
171
|
+
}
|
|
172
|
+
throw new BighubHttpError(`Request failed after retries: ${options.method} ${options.path}`);
|
|
173
|
+
}
|
|
174
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { BighubHttpClient } from "./httpClient.js";
|
|
5
|
+
import { registerBighubTools } from "./registerTools.js";
|
|
6
|
+
function parseNumberEnv(name, fallback) {
|
|
7
|
+
const raw = process.env[name];
|
|
8
|
+
if (!raw) {
|
|
9
|
+
return fallback;
|
|
10
|
+
}
|
|
11
|
+
const parsed = Number(raw);
|
|
12
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
13
|
+
}
|
|
14
|
+
async function main() {
|
|
15
|
+
const baseUrl = process.env.BIGHUB_BASE_URL || "https://api.bighub.io";
|
|
16
|
+
const apiKey = process.env.BIGHUB_API_KEY;
|
|
17
|
+
const bearerToken = process.env.BIGHUB_BEARER_TOKEN;
|
|
18
|
+
if (!apiKey && !bearerToken) {
|
|
19
|
+
console.error("BIGHUB_API_KEY or BIGHUB_BEARER_TOKEN must be set. " +
|
|
20
|
+
"Most tools require authentication against api.bighub.io.");
|
|
21
|
+
}
|
|
22
|
+
const client = new BighubHttpClient({
|
|
23
|
+
baseUrl,
|
|
24
|
+
apiKey,
|
|
25
|
+
bearerToken,
|
|
26
|
+
timeoutMs: parseNumberEnv("BIGHUB_TIMEOUT_MS", 15000),
|
|
27
|
+
maxRetries: parseNumberEnv("BIGHUB_MAX_RETRIES", 2),
|
|
28
|
+
userAgent: "bighub-mcp/0.1.0",
|
|
29
|
+
});
|
|
30
|
+
const server = new McpServer({
|
|
31
|
+
name: "bighub-mcp",
|
|
32
|
+
version: "0.1.0",
|
|
33
|
+
});
|
|
34
|
+
registerBighubTools(server, client);
|
|
35
|
+
const transport = new StdioServerTransport();
|
|
36
|
+
await server.connect(transport);
|
|
37
|
+
console.error("bighub-mcp server running on stdio");
|
|
38
|
+
const shutdown = async () => {
|
|
39
|
+
await server.close();
|
|
40
|
+
process.exit(0);
|
|
41
|
+
};
|
|
42
|
+
process.on("SIGINT", shutdown);
|
|
43
|
+
process.on("SIGTERM", shutdown);
|
|
44
|
+
}
|
|
45
|
+
main().catch((error) => {
|
|
46
|
+
console.error("bighub-mcp startup error:", error);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const JsonObjectSchema = z.record(z.string(), z.unknown());
|
|
3
|
+
const JsonPatchSchema = z.union([
|
|
4
|
+
z.array(JsonObjectSchema),
|
|
5
|
+
z.object({
|
|
6
|
+
ops: z.array(JsonObjectSchema),
|
|
7
|
+
format: z.string().optional(),
|
|
8
|
+
}),
|
|
9
|
+
]);
|
|
10
|
+
const AnyOutputSchema = z.object({}).passthrough();
|
|
11
|
+
function toResult(data) {
|
|
12
|
+
return {
|
|
13
|
+
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function cleanObject(input) {
|
|
17
|
+
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== undefined));
|
|
18
|
+
}
|
|
19
|
+
export function registerBighubTools(server, client) {
|
|
20
|
+
server.registerTool("bighub_http_request", {
|
|
21
|
+
description: "Low-level passthrough for any BIGHUB API endpoint.",
|
|
22
|
+
outputSchema: AnyOutputSchema,
|
|
23
|
+
inputSchema: {
|
|
24
|
+
method: z.enum(["GET", "POST", "PATCH", "DELETE"]),
|
|
25
|
+
path: z.string().regex(/^\/.*/, "Path must start with '/'"),
|
|
26
|
+
query: JsonObjectSchema.optional(),
|
|
27
|
+
body: z.union([JsonObjectSchema, z.array(JsonObjectSchema)]).optional(),
|
|
28
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
29
|
+
idempotency_key: z.string().optional(),
|
|
30
|
+
},
|
|
31
|
+
}, async ({ method, path, query, body, headers, idempotency_key }) => toResult(await client.request({
|
|
32
|
+
method,
|
|
33
|
+
path,
|
|
34
|
+
query,
|
|
35
|
+
body,
|
|
36
|
+
headers,
|
|
37
|
+
idempotencyKey: idempotency_key,
|
|
38
|
+
})));
|
|
39
|
+
server.registerTool("bighub_actions_submit", {
|
|
40
|
+
description: "Validate an action via /actions/submit.",
|
|
41
|
+
outputSchema: AnyOutputSchema,
|
|
42
|
+
inputSchema: {
|
|
43
|
+
action: z.string(),
|
|
44
|
+
actor: z.string().default("AI_AGENT"),
|
|
45
|
+
value: z.number().optional(),
|
|
46
|
+
target: z.string().optional(),
|
|
47
|
+
domain: z.string().optional(),
|
|
48
|
+
metadata: JsonObjectSchema.optional(),
|
|
49
|
+
idempotency_key: z.string().optional(),
|
|
50
|
+
},
|
|
51
|
+
}, async ({ action, actor, value, target, domain, metadata, idempotency_key }) => toResult(await client.request({
|
|
52
|
+
method: "POST",
|
|
53
|
+
path: "/actions/submit",
|
|
54
|
+
body: cleanObject({ action, actor, value, target, domain, metadata }),
|
|
55
|
+
idempotencyKey: idempotency_key,
|
|
56
|
+
})));
|
|
57
|
+
server.registerTool("bighub_actions_submit_v2", {
|
|
58
|
+
description: "Validate an action with pro decision intelligence via /actions/submit/v2.",
|
|
59
|
+
outputSchema: AnyOutputSchema,
|
|
60
|
+
inputSchema: {
|
|
61
|
+
payload: JsonObjectSchema,
|
|
62
|
+
idempotency_key: z.string().optional(),
|
|
63
|
+
},
|
|
64
|
+
}, async ({ payload, idempotency_key }) => toResult(await client.request({
|
|
65
|
+
method: "POST",
|
|
66
|
+
path: "/actions/submit/v2",
|
|
67
|
+
body: payload,
|
|
68
|
+
idempotencyKey: idempotency_key,
|
|
69
|
+
})));
|
|
70
|
+
server.registerTool("bighub_actions_dry_run", {
|
|
71
|
+
description: "Run a non-persistent action validation via /actions/submit/dry-run.",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
payload: JsonObjectSchema,
|
|
74
|
+
idempotency_key: z.string().optional(),
|
|
75
|
+
},
|
|
76
|
+
}, async ({ payload, idempotency_key }) => toResult(await client.request({
|
|
77
|
+
method: "POST",
|
|
78
|
+
path: "/actions/submit/dry-run",
|
|
79
|
+
body: payload,
|
|
80
|
+
idempotencyKey: idempotency_key,
|
|
81
|
+
})));
|
|
82
|
+
server.registerTool("bighub_actions_verify_validation", {
|
|
83
|
+
description: "Verify a previous validation by validation_id.",
|
|
84
|
+
inputSchema: { validation_id: z.string() },
|
|
85
|
+
}, async ({ validation_id }) => toResult(await client.request({
|
|
86
|
+
method: "GET",
|
|
87
|
+
path: `/actions/validations/${validation_id}/verify`,
|
|
88
|
+
})));
|
|
89
|
+
server.registerTool("bighub_actions_observer_stats", {
|
|
90
|
+
description: "Get action observer stats.",
|
|
91
|
+
inputSchema: {},
|
|
92
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/actions/observer/stats" })));
|
|
93
|
+
server.registerTool("bighub_actions_dashboard_summary", {
|
|
94
|
+
description: "Get action dashboard summary.",
|
|
95
|
+
inputSchema: {},
|
|
96
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/actions/dashboard/summary" })));
|
|
97
|
+
server.registerTool("bighub_actions_status", {
|
|
98
|
+
description: "Get action system status.",
|
|
99
|
+
inputSchema: {},
|
|
100
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/actions/status" })));
|
|
101
|
+
server.registerTool("bighub_actions_memory_ingest", {
|
|
102
|
+
description: "Ingest governed execution events into Future Memory.",
|
|
103
|
+
inputSchema: {
|
|
104
|
+
events: z.array(JsonObjectSchema),
|
|
105
|
+
source: z.string().default("adapter"),
|
|
106
|
+
source_version: z.string().optional(),
|
|
107
|
+
actor: z.string().optional(),
|
|
108
|
+
domain: z.string().optional(),
|
|
109
|
+
model: z.string().optional(),
|
|
110
|
+
trace_id: z.string().optional(),
|
|
111
|
+
redact: z.boolean().default(true),
|
|
112
|
+
redaction_policy: z.string().default("default"),
|
|
113
|
+
},
|
|
114
|
+
}, async ({ events, source, source_version, actor, domain, model, trace_id, redact, redaction_policy }) => toResult(await client.request({
|
|
115
|
+
method: "POST",
|
|
116
|
+
path: "/actions/memory/ingest",
|
|
117
|
+
body: cleanObject({
|
|
118
|
+
source,
|
|
119
|
+
events,
|
|
120
|
+
source_version,
|
|
121
|
+
actor,
|
|
122
|
+
domain,
|
|
123
|
+
model,
|
|
124
|
+
trace_id,
|
|
125
|
+
redact,
|
|
126
|
+
redaction_policy,
|
|
127
|
+
}),
|
|
128
|
+
})));
|
|
129
|
+
server.registerTool("bighub_actions_memory_context", {
|
|
130
|
+
description: "Read Future Memory context window and rates.",
|
|
131
|
+
inputSchema: {
|
|
132
|
+
window_hours: z.number().int().default(24),
|
|
133
|
+
tool: z.string().optional(),
|
|
134
|
+
domain: z.string().optional(),
|
|
135
|
+
actor: z.string().optional(),
|
|
136
|
+
source: z.string().optional(),
|
|
137
|
+
limit_recent: z.number().int().default(25),
|
|
138
|
+
},
|
|
139
|
+
}, async ({ window_hours, tool, domain, actor, source, limit_recent }) => toResult(await client.request({
|
|
140
|
+
method: "GET",
|
|
141
|
+
path: "/actions/memory/context",
|
|
142
|
+
query: cleanObject({ window_hours, tool, domain, actor, source, limit_recent }),
|
|
143
|
+
})));
|
|
144
|
+
server.registerTool("bighub_actions_memory_refresh_aggregates", {
|
|
145
|
+
description: "Refresh Future Memory aggregates.",
|
|
146
|
+
inputSchema: {
|
|
147
|
+
concurrent: z.boolean().default(false),
|
|
148
|
+
window_hours: z.number().int().default(24),
|
|
149
|
+
},
|
|
150
|
+
}, async ({ concurrent, window_hours }) => toResult(await client.request({
|
|
151
|
+
method: "POST",
|
|
152
|
+
path: "/actions/memory/refresh-aggregates",
|
|
153
|
+
query: { concurrent, window_hours },
|
|
154
|
+
})));
|
|
155
|
+
server.registerTool("bighub_actions_memory_recommendations", {
|
|
156
|
+
description: "Compute Future Memory policy recommendations.",
|
|
157
|
+
outputSchema: AnyOutputSchema,
|
|
158
|
+
inputSchema: {
|
|
159
|
+
window_hours: z.number().int().default(24),
|
|
160
|
+
scope: JsonObjectSchema.optional(),
|
|
161
|
+
tool: z.string().optional(),
|
|
162
|
+
domain: z.string().optional(),
|
|
163
|
+
actor: z.string().optional(),
|
|
164
|
+
source: z.string().optional(),
|
|
165
|
+
min_events: z.number().int().default(20),
|
|
166
|
+
min_blocked_rate: z.number().default(0.15),
|
|
167
|
+
min_approval_rate: z.number().default(0.1),
|
|
168
|
+
min_tool_error_rate: z.number().default(0.05),
|
|
169
|
+
limit_recommendations: z.number().int().default(10),
|
|
170
|
+
include_examples: z.boolean().default(true),
|
|
171
|
+
auto_apply: z.boolean().default(false),
|
|
172
|
+
},
|
|
173
|
+
}, async (args) => toResult(await client.request({
|
|
174
|
+
method: "POST",
|
|
175
|
+
path: "/actions/memory/recommendations",
|
|
176
|
+
body: cleanObject(args),
|
|
177
|
+
})));
|
|
178
|
+
server.registerTool("bighub_rules_create", {
|
|
179
|
+
description: "Create a governance rule.",
|
|
180
|
+
outputSchema: AnyOutputSchema,
|
|
181
|
+
inputSchema: {
|
|
182
|
+
payload: JsonObjectSchema,
|
|
183
|
+
idempotency_key: z.string().optional(),
|
|
184
|
+
},
|
|
185
|
+
}, async ({ payload, idempotency_key }) => toResult(await client.request({
|
|
186
|
+
method: "POST",
|
|
187
|
+
path: "/rules",
|
|
188
|
+
body: payload,
|
|
189
|
+
idempotencyKey: idempotency_key,
|
|
190
|
+
})));
|
|
191
|
+
server.registerTool("bighub_rules_list", {
|
|
192
|
+
description: "List governance rules.",
|
|
193
|
+
outputSchema: AnyOutputSchema,
|
|
194
|
+
inputSchema: {
|
|
195
|
+
status: z.string().optional(),
|
|
196
|
+
domain: z.string().optional(),
|
|
197
|
+
limit: z.number().int().optional(),
|
|
198
|
+
offset: z.number().int().optional(),
|
|
199
|
+
},
|
|
200
|
+
}, async ({ status, domain, limit, offset }) => toResult(await client.request({
|
|
201
|
+
method: "GET",
|
|
202
|
+
path: "/rules",
|
|
203
|
+
query: cleanObject({ status, domain, limit, offset }),
|
|
204
|
+
})));
|
|
205
|
+
server.registerTool("bighub_rules_get", {
|
|
206
|
+
description: "Fetch a single rule by rule_id.",
|
|
207
|
+
outputSchema: AnyOutputSchema,
|
|
208
|
+
inputSchema: { rule_id: z.string() },
|
|
209
|
+
}, async ({ rule_id }) => toResult(await client.request({ method: "GET", path: `/rules/${rule_id}` })));
|
|
210
|
+
server.registerTool("bighub_rules_update", {
|
|
211
|
+
description: "Update a rule by rule_id.",
|
|
212
|
+
outputSchema: AnyOutputSchema,
|
|
213
|
+
inputSchema: {
|
|
214
|
+
rule_id: z.string(),
|
|
215
|
+
payload: JsonObjectSchema,
|
|
216
|
+
idempotency_key: z.string().optional(),
|
|
217
|
+
},
|
|
218
|
+
}, async ({ rule_id, payload, idempotency_key }) => toResult(await client.request({
|
|
219
|
+
method: "PATCH",
|
|
220
|
+
path: `/rules/${rule_id}`,
|
|
221
|
+
body: payload,
|
|
222
|
+
idempotencyKey: idempotency_key,
|
|
223
|
+
})));
|
|
224
|
+
server.registerTool("bighub_rules_delete", {
|
|
225
|
+
description: "Delete a rule.",
|
|
226
|
+
inputSchema: {
|
|
227
|
+
rule_id: z.string(),
|
|
228
|
+
idempotency_key: z.string().optional(),
|
|
229
|
+
},
|
|
230
|
+
}, async ({ rule_id, idempotency_key }) => toResult(await client.request({
|
|
231
|
+
method: "DELETE",
|
|
232
|
+
path: `/rules/${rule_id}`,
|
|
233
|
+
idempotencyKey: idempotency_key,
|
|
234
|
+
})));
|
|
235
|
+
server.registerTool("bighub_rules_pause", {
|
|
236
|
+
description: "Pause rule enforcement for a rule_id.",
|
|
237
|
+
inputSchema: {
|
|
238
|
+
rule_id: z.string(),
|
|
239
|
+
idempotency_key: z.string().optional(),
|
|
240
|
+
},
|
|
241
|
+
}, async ({ rule_id, idempotency_key }) => toResult(await client.request({
|
|
242
|
+
method: "POST",
|
|
243
|
+
path: `/rules/${rule_id}/pause`,
|
|
244
|
+
idempotencyKey: idempotency_key,
|
|
245
|
+
})));
|
|
246
|
+
server.registerTool("bighub_rules_resume", {
|
|
247
|
+
description: "Resume a paused rule.",
|
|
248
|
+
inputSchema: {
|
|
249
|
+
rule_id: z.string(),
|
|
250
|
+
idempotency_key: z.string().optional(),
|
|
251
|
+
},
|
|
252
|
+
}, async ({ rule_id, idempotency_key }) => toResult(await client.request({
|
|
253
|
+
method: "POST",
|
|
254
|
+
path: `/rules/${rule_id}/resume`,
|
|
255
|
+
idempotencyKey: idempotency_key,
|
|
256
|
+
})));
|
|
257
|
+
server.registerTool("bighub_rules_dry_run", {
|
|
258
|
+
description: "Dry run a rule payload without persisting.",
|
|
259
|
+
inputSchema: {
|
|
260
|
+
payload: JsonObjectSchema,
|
|
261
|
+
},
|
|
262
|
+
}, async ({ payload }) => toResult(await client.request({
|
|
263
|
+
method: "POST",
|
|
264
|
+
path: "/rules/dry-run",
|
|
265
|
+
body: payload,
|
|
266
|
+
})));
|
|
267
|
+
server.registerTool("bighub_rules_validate", {
|
|
268
|
+
description: "Validate a rule payload.",
|
|
269
|
+
inputSchema: {
|
|
270
|
+
payload: JsonObjectSchema,
|
|
271
|
+
},
|
|
272
|
+
}, async ({ payload }) => toResult(await client.request({
|
|
273
|
+
method: "POST",
|
|
274
|
+
path: "/rules/validate",
|
|
275
|
+
body: payload,
|
|
276
|
+
})));
|
|
277
|
+
server.registerTool("bighub_rules_validate_dry_run", {
|
|
278
|
+
description: "Dry-run validate a rule payload.",
|
|
279
|
+
inputSchema: {
|
|
280
|
+
payload: JsonObjectSchema,
|
|
281
|
+
},
|
|
282
|
+
}, async ({ payload }) => toResult(await client.request({
|
|
283
|
+
method: "POST",
|
|
284
|
+
path: "/rules/validate/dry-run",
|
|
285
|
+
body: payload,
|
|
286
|
+
})));
|
|
287
|
+
server.registerTool("bighub_rules_domains", {
|
|
288
|
+
description: "List available rule domains.",
|
|
289
|
+
inputSchema: {},
|
|
290
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/rules/domains" })));
|
|
291
|
+
server.registerTool("bighub_rules_versions", {
|
|
292
|
+
description: "List historical versions for a rule.",
|
|
293
|
+
outputSchema: AnyOutputSchema,
|
|
294
|
+
inputSchema: {
|
|
295
|
+
rule_id: z.string(),
|
|
296
|
+
limit: z.number().int().optional(),
|
|
297
|
+
},
|
|
298
|
+
}, async ({ rule_id, limit }) => toResult(await client.request({
|
|
299
|
+
method: "GET",
|
|
300
|
+
path: `/rules/${rule_id}/versions`,
|
|
301
|
+
query: cleanObject({ limit }),
|
|
302
|
+
})));
|
|
303
|
+
server.registerTool("bighub_rules_purge_idempotency", {
|
|
304
|
+
description: "Purge rule idempotency records from the backend store.",
|
|
305
|
+
outputSchema: AnyOutputSchema,
|
|
306
|
+
inputSchema: {
|
|
307
|
+
only_expired: z.boolean().default(true),
|
|
308
|
+
older_than_hours: z.number().int().optional(),
|
|
309
|
+
limit: z.number().int().optional(),
|
|
310
|
+
},
|
|
311
|
+
}, async ({ only_expired, older_than_hours, limit }) => toResult(await client.request({
|
|
312
|
+
method: "POST",
|
|
313
|
+
path: "/rules/admin/idempotency/purge",
|
|
314
|
+
query: cleanObject({ only_expired, older_than_hours, limit }),
|
|
315
|
+
})));
|
|
316
|
+
server.registerTool("bighub_rules_apply_patch", {
|
|
317
|
+
description: "Apply JSON Patch operations to a rule with preview/optimistic locking support.",
|
|
318
|
+
outputSchema: AnyOutputSchema,
|
|
319
|
+
inputSchema: {
|
|
320
|
+
rule_id: z.string(),
|
|
321
|
+
patch: JsonPatchSchema,
|
|
322
|
+
preview: z.boolean().default(true),
|
|
323
|
+
reason: z.string().optional(),
|
|
324
|
+
if_match_version: z.number().int().optional(),
|
|
325
|
+
idempotency_key: z.string().optional(),
|
|
326
|
+
if_match: z.string().optional(),
|
|
327
|
+
},
|
|
328
|
+
}, async ({ rule_id, patch, preview, reason, if_match_version, idempotency_key, if_match }) => {
|
|
329
|
+
const patchOps = Array.isArray(patch) ? patch : patch.ops;
|
|
330
|
+
return toResult(await client.request({
|
|
331
|
+
method: "POST",
|
|
332
|
+
path: `/rules/${rule_id}/apply_patch`,
|
|
333
|
+
body: cleanObject({ patch: patchOps, preview, reason, if_match_version }),
|
|
334
|
+
idempotencyKey: idempotency_key,
|
|
335
|
+
headers: cleanObject({ "If-Match": if_match }),
|
|
336
|
+
}));
|
|
337
|
+
});
|
|
338
|
+
server.registerTool("bighub_approvals_list", {
|
|
339
|
+
description: "List approval queue items.",
|
|
340
|
+
outputSchema: AnyOutputSchema,
|
|
341
|
+
inputSchema: {
|
|
342
|
+
status_filter: z.string().default("pending"),
|
|
343
|
+
limit: z.number().int().optional(),
|
|
344
|
+
},
|
|
345
|
+
}, async ({ status_filter, limit }) => toResult(await client.request({
|
|
346
|
+
method: "GET",
|
|
347
|
+
path: "/approvals",
|
|
348
|
+
query: cleanObject({ status: status_filter, limit }),
|
|
349
|
+
})));
|
|
350
|
+
server.registerTool("bighub_approvals_resolve", {
|
|
351
|
+
description: "Resolve an approval request.",
|
|
352
|
+
outputSchema: AnyOutputSchema,
|
|
353
|
+
inputSchema: {
|
|
354
|
+
request_id: z.string(),
|
|
355
|
+
resolution: z.enum(["approved", "rejected"]),
|
|
356
|
+
comment: z.string().optional(),
|
|
357
|
+
},
|
|
358
|
+
}, async ({ request_id, resolution, comment }) => toResult(await client.request({
|
|
359
|
+
method: "POST",
|
|
360
|
+
path: `/approvals/${request_id}/resolve`,
|
|
361
|
+
body: cleanObject({ resolution, comment }),
|
|
362
|
+
})));
|
|
363
|
+
server.registerTool("bighub_kill_switch_status", {
|
|
364
|
+
description: "Read kill switch status.",
|
|
365
|
+
outputSchema: AnyOutputSchema,
|
|
366
|
+
inputSchema: {},
|
|
367
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/kill-switch/status" })));
|
|
368
|
+
server.registerTool("bighub_kill_switch_activate", {
|
|
369
|
+
description: "Activate global/domain kill switch.",
|
|
370
|
+
inputSchema: {
|
|
371
|
+
payload: JsonObjectSchema.optional(),
|
|
372
|
+
},
|
|
373
|
+
}, async ({ payload }) => toResult(await client.request({ method: "POST", path: "/kill-switch/activate", body: payload || {} })));
|
|
374
|
+
server.registerTool("bighub_kill_switch_deactivate", {
|
|
375
|
+
description: "Deactivate kill switch by switch_id.",
|
|
376
|
+
inputSchema: {
|
|
377
|
+
switch_id: z.string(),
|
|
378
|
+
payload: JsonObjectSchema.optional(),
|
|
379
|
+
},
|
|
380
|
+
}, async ({ switch_id, payload }) => toResult(await client.request({
|
|
381
|
+
method: "POST",
|
|
382
|
+
path: `/kill-switch/deactivate/${switch_id}`,
|
|
383
|
+
body: payload || {},
|
|
384
|
+
})));
|
|
385
|
+
server.registerTool("bighub_events_list", {
|
|
386
|
+
description: "List event stream entries.",
|
|
387
|
+
outputSchema: AnyOutputSchema,
|
|
388
|
+
inputSchema: {
|
|
389
|
+
event_type: z.string().optional(),
|
|
390
|
+
severity: z.string().optional(),
|
|
391
|
+
rule_id: z.string().optional(),
|
|
392
|
+
limit: z.number().int().optional(),
|
|
393
|
+
offset: z.number().int().optional(),
|
|
394
|
+
},
|
|
395
|
+
}, async ({ event_type, severity, rule_id, limit, offset }) => toResult(await client.request({
|
|
396
|
+
method: "GET",
|
|
397
|
+
path: "/events",
|
|
398
|
+
query: cleanObject({ event_type, severity, rule_id, limit, offset }),
|
|
399
|
+
})));
|
|
400
|
+
server.registerTool("bighub_events_stats", {
|
|
401
|
+
description: "Get aggregate event stats.",
|
|
402
|
+
inputSchema: {},
|
|
403
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/events/stats" })));
|
|
404
|
+
server.registerTool("bighub_api_keys_create", {
|
|
405
|
+
description: "Create an API key.",
|
|
406
|
+
inputSchema: {
|
|
407
|
+
payload: JsonObjectSchema,
|
|
408
|
+
},
|
|
409
|
+
}, async ({ payload }) => toResult(await client.request({ method: "POST", path: "/api-keys", body: payload })));
|
|
410
|
+
server.registerTool("bighub_api_keys_list", {
|
|
411
|
+
description: "List API keys.",
|
|
412
|
+
outputSchema: AnyOutputSchema,
|
|
413
|
+
inputSchema: {
|
|
414
|
+
include_revoked: z.boolean().default(false),
|
|
415
|
+
},
|
|
416
|
+
}, async ({ include_revoked }) => toResult(await client.request({ method: "GET", path: "/api-keys", query: { include_revoked } })));
|
|
417
|
+
server.registerTool("bighub_api_keys_delete", {
|
|
418
|
+
description: "Delete or revoke an API key.",
|
|
419
|
+
inputSchema: {
|
|
420
|
+
key_id: z.string(),
|
|
421
|
+
reason: z.string().optional(),
|
|
422
|
+
},
|
|
423
|
+
}, async ({ key_id, reason }) => toResult(await client.request({
|
|
424
|
+
method: "DELETE",
|
|
425
|
+
path: `/api-keys/${key_id}`,
|
|
426
|
+
body: reason ? { reason } : undefined,
|
|
427
|
+
})));
|
|
428
|
+
server.registerTool("bighub_api_keys_rotate", {
|
|
429
|
+
description: "Rotate an API key.",
|
|
430
|
+
inputSchema: {
|
|
431
|
+
key_id: z.string(),
|
|
432
|
+
},
|
|
433
|
+
}, async ({ key_id }) => toResult(await client.request({ method: "POST", path: `/api-keys/${key_id}/rotate` })));
|
|
434
|
+
server.registerTool("bighub_api_keys_validate", {
|
|
435
|
+
description: "Validate an API key (query + X-API-Key header).",
|
|
436
|
+
inputSchema: {
|
|
437
|
+
api_key: z.string(),
|
|
438
|
+
},
|
|
439
|
+
}, async ({ api_key }) => toResult(await client.request({
|
|
440
|
+
method: "GET",
|
|
441
|
+
path: "/api-keys/validate",
|
|
442
|
+
query: { api_key },
|
|
443
|
+
headers: { "X-API-Key": api_key },
|
|
444
|
+
})));
|
|
445
|
+
server.registerTool("bighub_api_keys_scopes", {
|
|
446
|
+
description: "List available API key scopes.",
|
|
447
|
+
inputSchema: {},
|
|
448
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/api-keys/scopes" })));
|
|
449
|
+
server.registerTool("bighub_webhooks_create", {
|
|
450
|
+
description: "Create a webhook endpoint.",
|
|
451
|
+
inputSchema: {
|
|
452
|
+
payload: JsonObjectSchema,
|
|
453
|
+
},
|
|
454
|
+
}, async ({ payload }) => toResult(await client.request({ method: "POST", path: "/webhooks", body: payload })));
|
|
455
|
+
server.registerTool("bighub_webhooks_list", {
|
|
456
|
+
description: "List webhooks.",
|
|
457
|
+
outputSchema: AnyOutputSchema,
|
|
458
|
+
inputSchema: {
|
|
459
|
+
include_inactive: z.boolean().default(false),
|
|
460
|
+
},
|
|
461
|
+
}, async ({ include_inactive }) => toResult(await client.request({ method: "GET", path: "/webhooks", query: { include_inactive } })));
|
|
462
|
+
server.registerTool("bighub_webhooks_get", {
|
|
463
|
+
description: "Get a webhook by webhook_id.",
|
|
464
|
+
outputSchema: AnyOutputSchema,
|
|
465
|
+
inputSchema: {
|
|
466
|
+
webhook_id: z.string(),
|
|
467
|
+
},
|
|
468
|
+
}, async ({ webhook_id }) => toResult(await client.request({ method: "GET", path: `/webhooks/${webhook_id}` })));
|
|
469
|
+
server.registerTool("bighub_webhooks_update", {
|
|
470
|
+
description: "Update webhook by webhook_id.",
|
|
471
|
+
inputSchema: {
|
|
472
|
+
webhook_id: z.string(),
|
|
473
|
+
payload: JsonObjectSchema,
|
|
474
|
+
},
|
|
475
|
+
}, async ({ webhook_id, payload }) => toResult(await client.request({ method: "PATCH", path: `/webhooks/${webhook_id}`, body: payload })));
|
|
476
|
+
server.registerTool("bighub_webhooks_delete", {
|
|
477
|
+
description: "Delete a webhook.",
|
|
478
|
+
inputSchema: {
|
|
479
|
+
webhook_id: z.string(),
|
|
480
|
+
},
|
|
481
|
+
}, async ({ webhook_id }) => toResult(await client.request({ method: "DELETE", path: `/webhooks/${webhook_id}` })));
|
|
482
|
+
server.registerTool("bighub_webhooks_deliveries", {
|
|
483
|
+
description: "List webhook delivery logs.",
|
|
484
|
+
inputSchema: {
|
|
485
|
+
webhook_id: z.string(),
|
|
486
|
+
limit: z.number().int().optional(),
|
|
487
|
+
},
|
|
488
|
+
}, async ({ webhook_id, limit }) => toResult(await client.request({
|
|
489
|
+
method: "GET",
|
|
490
|
+
path: `/webhooks/${webhook_id}/deliveries`,
|
|
491
|
+
query: cleanObject({ limit }),
|
|
492
|
+
})));
|
|
493
|
+
server.registerTool("bighub_webhooks_test", {
|
|
494
|
+
description: "Send a test webhook delivery.",
|
|
495
|
+
inputSchema: {
|
|
496
|
+
webhook_id: z.string(),
|
|
497
|
+
event_type: z.string().default("signal.new"),
|
|
498
|
+
},
|
|
499
|
+
}, async ({ webhook_id, event_type }) => toResult(await client.request({
|
|
500
|
+
method: "POST",
|
|
501
|
+
path: `/webhooks/${webhook_id}/test`,
|
|
502
|
+
body: { event_type },
|
|
503
|
+
})));
|
|
504
|
+
server.registerTool("bighub_webhooks_list_events", {
|
|
505
|
+
description: "List supported webhook event types.",
|
|
506
|
+
inputSchema: {},
|
|
507
|
+
}, async () => toResult(await client.request({ method: "GET", path: "/webhooks/events/list" })));
|
|
508
|
+
server.registerTool("bighub_webhooks_verify_signature", {
|
|
509
|
+
description: "Verify webhook signature payload.",
|
|
510
|
+
inputSchema: {
|
|
511
|
+
payload: z.string(),
|
|
512
|
+
signature: z.string(),
|
|
513
|
+
secret: z.string(),
|
|
514
|
+
timestamp: z.number().int(),
|
|
515
|
+
},
|
|
516
|
+
}, async ({ payload, signature, secret, timestamp }) => toResult(await client.request({
|
|
517
|
+
method: "POST",
|
|
518
|
+
path: "/webhooks/verify-signature",
|
|
519
|
+
body: { payload, signature, secret, timestamp },
|
|
520
|
+
})));
|
|
521
|
+
server.registerTool("bighub_webhooks_replay_failed_delivery", {
|
|
522
|
+
description: "Replay a failed webhook delivery.",
|
|
523
|
+
inputSchema: {
|
|
524
|
+
webhook_id: z.string(),
|
|
525
|
+
delivery_id: z.number().int(),
|
|
526
|
+
},
|
|
527
|
+
}, async ({ webhook_id, delivery_id }) => toResult(await client.request({
|
|
528
|
+
method: "POST",
|
|
529
|
+
path: `/webhooks/${webhook_id}/deliveries/${delivery_id}/replay`,
|
|
530
|
+
})));
|
|
531
|
+
server.registerTool("bighub_auth_signup", {
|
|
532
|
+
description: "Sign up and return access/refresh tokens.",
|
|
533
|
+
inputSchema: { payload: JsonObjectSchema },
|
|
534
|
+
}, async ({ payload }) => toResult(await client.request({ method: "POST", path: "/auth/signup", body: payload })));
|
|
535
|
+
server.registerTool("bighub_auth_login", {
|
|
536
|
+
description: "Authenticate and return access/refresh tokens.",
|
|
537
|
+
outputSchema: AnyOutputSchema,
|
|
538
|
+
inputSchema: { payload: JsonObjectSchema },
|
|
539
|
+
}, async ({ payload }) => toResult(await client.request({ method: "POST", path: "/auth/login", body: payload })));
|
|
540
|
+
server.registerTool("bighub_auth_refresh", {
|
|
541
|
+
description: "Rotate auth tokens with refresh token.",
|
|
542
|
+
inputSchema: { refresh_token: z.string() },
|
|
543
|
+
}, async ({ refresh_token }) => toResult(await client.request({ method: "POST", path: "/auth/refresh", body: { refresh_token } })));
|
|
544
|
+
server.registerTool("bighub_auth_logout", {
|
|
545
|
+
description: "Invalidate a refresh token.",
|
|
546
|
+
inputSchema: { refresh_token: z.string() },
|
|
547
|
+
}, async ({ refresh_token }) => toResult(await client.request({ method: "POST", path: "/auth/logout", body: { refresh_token } })));
|
|
548
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bighub/bighub-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Official MCP server for BIGHUB governance APIs.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"bighub-mcp": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"check": "tsc --noEmit",
|
|
20
|
+
"dev": "tsx src/index.ts",
|
|
21
|
+
"start": "node dist/index.js",
|
|
22
|
+
"test": "vitest run"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"bighub",
|
|
26
|
+
"mcp",
|
|
27
|
+
"governance",
|
|
28
|
+
"ai-agents"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
36
|
+
"zod": "^4.3.6"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"@types/node": "^25.3.5",
|
|
40
|
+
"tsx": "^4.21.0",
|
|
41
|
+
"typescript": "^5.9.3",
|
|
42
|
+
"vitest": "^2.1.9"
|
|
43
|
+
}
|
|
44
|
+
}
|