@greensecurity/javascript-sdk 0.10.2 → 0.11.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 +67 -11
- package/bin/mcp-server.js +39384 -0
- package/bin/mcp-server.js.map +301 -0
- package/jsr.json +1 -1
- package/lib/config.d.ts +5 -5
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +3 -3
- package/lib/files.js.map +1 -1
- package/mcp-server/build.d.mts.map +1 -0
- package/mcp-server/build.mjs +14 -0
- package/mcp-server/build.mjs.map +1 -0
- package/mcp-server/cli/start/command.d.ts +2 -0
- package/mcp-server/cli/start/command.d.ts.map +1 -0
- package/mcp-server/cli/start/command.js +99 -0
- package/mcp-server/cli/start/command.js.map +1 -0
- package/mcp-server/cli/start/impl.d.ts +15 -0
- package/mcp-server/cli/start/impl.d.ts.map +1 -0
- package/mcp-server/cli/start/impl.js +97 -0
- package/mcp-server/cli/start/impl.js.map +1 -0
- package/mcp-server/cli.d.ts +6 -0
- package/mcp-server/cli.d.ts.map +1 -0
- package/mcp-server/cli.js +10 -0
- package/mcp-server/cli.js.map +1 -0
- package/mcp-server/console-logger.d.ts +7 -0
- package/mcp-server/console-logger.d.ts.map +1 -0
- package/mcp-server/console-logger.js +59 -0
- package/mcp-server/console-logger.js.map +1 -0
- package/mcp-server/mcp-server.d.ts +2 -0
- package/mcp-server/mcp-server.d.ts.map +1 -0
- package/mcp-server/mcp-server.js +29 -0
- package/mcp-server/mcp-server.js.map +1 -0
- package/mcp-server/resources.d.ts +27 -0
- package/mcp-server/resources.d.ts.map +1 -0
- package/mcp-server/resources.js +51 -0
- package/mcp-server/resources.js.map +1 -0
- package/mcp-server/scopes.d.ts +3 -0
- package/mcp-server/scopes.d.ts.map +1 -0
- package/mcp-server/scopes.js +8 -0
- package/mcp-server/scopes.js.map +1 -0
- package/mcp-server/server.d.ts +11 -0
- package/mcp-server/server.d.ts.map +1 -0
- package/mcp-server/server.js +44 -0
- package/mcp-server/server.js.map +1 -0
- package/mcp-server/shared.d.ts +7 -0
- package/mcp-server/shared.d.ts.map +1 -0
- package/mcp-server/shared.js +98 -0
- package/mcp-server/shared.js.map +1 -0
- package/mcp-server/tools/organizationsGetFacility.d.ts +8 -0
- package/mcp-server/tools/organizationsGetFacility.d.ts.map +1 -0
- package/mcp-server/tools/organizationsGetFacility.js +64 -0
- package/mcp-server/tools/organizationsGetFacility.js.map +1 -0
- package/mcp-server/tools/organizationsListOrSearchFacilities.d.ts +8 -0
- package/mcp-server/tools/organizationsListOrSearchFacilities.d.ts.map +1 -0
- package/mcp-server/tools/organizationsListOrSearchFacilities.js +77 -0
- package/mcp-server/tools/organizationsListOrSearchFacilities.js.map +1 -0
- package/mcp-server/tools/userGetCurrentUser.d.ts +3 -0
- package/mcp-server/tools/userGetCurrentUser.d.ts.map +1 -0
- package/mcp-server/tools/userGetCurrentUser.js +26 -0
- package/mcp-server/tools/userGetCurrentUser.js.map +1 -0
- package/mcp-server/tools/userGetUserById.d.ts +8 -0
- package/mcp-server/tools/userGetUserById.d.ts.map +1 -0
- package/mcp-server/tools/userGetUserById.js +64 -0
- package/mcp-server/tools/userGetUserById.js.map +1 -0
- package/mcp-server/tools/userLogsUserIntoTheSystem.d.ts +8 -0
- package/mcp-server/tools/userLogsUserIntoTheSystem.d.ts.map +1 -0
- package/mcp-server/tools/userLogsUserIntoTheSystem.js +94 -0
- package/mcp-server/tools/userLogsUserIntoTheSystem.js.map +1 -0
- package/mcp-server/tools/userMagiclink.d.ts +8 -0
- package/mcp-server/tools/userMagiclink.d.ts.map +1 -0
- package/mcp-server/tools/userMagiclink.js +64 -0
- package/mcp-server/tools/userMagiclink.js.map +1 -0
- package/mcp-server/tools/userPassword.d.ts +8 -0
- package/mcp-server/tools/userPassword.d.ts.map +1 -0
- package/mcp-server/tools/userPassword.js +65 -0
- package/mcp-server/tools/userPassword.js.map +1 -0
- package/mcp-server/tools/userPasswordResetRequest.d.ts +8 -0
- package/mcp-server/tools/userPasswordResetRequest.d.ts.map +1 -0
- package/mcp-server/tools/userPasswordResetRequest.js +64 -0
- package/mcp-server/tools/userPasswordResetRequest.js.map +1 -0
- package/mcp-server/tools/vendorsCreateVendorRegistration.d.ts +8 -0
- package/mcp-server/tools/vendorsCreateVendorRegistration.d.ts.map +1 -0
- package/mcp-server/tools/vendorsCreateVendorRegistration.js +64 -0
- package/mcp-server/tools/vendorsCreateVendorRegistration.js.map +1 -0
- package/mcp-server/tools/vendorsListVendorJobTitles.d.ts +8 -0
- package/mcp-server/tools/vendorsListVendorJobTitles.d.ts.map +1 -0
- package/mcp-server/tools/vendorsListVendorJobTitles.js +64 -0
- package/mcp-server/tools/vendorsListVendorJobTitles.js.map +1 -0
- package/mcp-server/tools.d.ts +25 -0
- package/mcp-server/tools.d.ts.map +1 -0
- package/mcp-server/tools.js +74 -0
- package/mcp-server/tools.js.map +1 -0
- package/models/operations/password.d.ts +2 -2
- package/models/operations/password.d.ts.map +1 -1
- package/models/operations/password.js +2 -2
- package/models/operations/password.js.map +1 -1
- package/package.json +14 -2
- package/src/lib/config.ts +5 -5
- package/src/lib/files.ts +1 -1
- package/src/mcp-server/cli/start/command.ts +67 -0
- package/src/mcp-server/cli/start/impl.ts +123 -0
- package/src/mcp-server/cli.ts +13 -0
- package/src/mcp-server/console-logger.ts +71 -0
- package/src/mcp-server/mcp-server.ts +26 -0
- package/src/mcp-server/resources.ts +96 -0
- package/src/mcp-server/scopes.ts +7 -0
- package/src/mcp-server/server.ts +52 -0
- package/src/mcp-server/shared.ts +75 -0
- package/src/mcp-server/tools/organizationsGetFacility.ts +37 -0
- package/src/mcp-server/tools/organizationsListOrSearchFacilities.ts +52 -0
- package/src/mcp-server/tools/userGetCurrentUser.ts +30 -0
- package/src/mcp-server/tools/userGetUserById.ts +37 -0
- package/src/mcp-server/tools/userLogsUserIntoTheSystem.ts +67 -0
- package/src/mcp-server/tools/userMagiclink.ts +37 -0
- package/src/mcp-server/tools/userPassword.ts +38 -0
- package/src/mcp-server/tools/userPasswordResetRequest.ts +37 -0
- package/src/mcp-server/tools/vendorsCreateVendorRegistration.ts +38 -0
- package/src/mcp-server/tools/vendorsListVendorJobTitles.ts +37 -0
- package/src/mcp-server/tools.ts +116 -0
- package/src/models/operations/password.ts +4 -4
package/src/lib/config.ts
CHANGED
|
@@ -36,11 +36,11 @@ export type SDKOptions = {
|
|
|
36
36
|
/**
|
|
37
37
|
* Allows overriding the default server used by the SDK
|
|
38
38
|
*/
|
|
39
|
-
serverIdx?: number;
|
|
39
|
+
serverIdx?: number | undefined;
|
|
40
40
|
/**
|
|
41
41
|
* Allows overriding the default server URL used by the SDK
|
|
42
42
|
*/
|
|
43
|
-
serverURL?: string;
|
|
43
|
+
serverURL?: string | undefined;
|
|
44
44
|
/**
|
|
45
45
|
* Allows overriding the default retry config used by the SDK
|
|
46
46
|
*/
|
|
@@ -69,8 +69,8 @@ export function serverURLFromOptions(options: SDKOptions): URL | null {
|
|
|
69
69
|
export const SDK_METADATA = {
|
|
70
70
|
language: "typescript",
|
|
71
71
|
openapiDocVersion: "0.0.3",
|
|
72
|
-
sdkVersion: "0.
|
|
73
|
-
genVersion: "2.
|
|
72
|
+
sdkVersion: "0.11.0",
|
|
73
|
+
genVersion: "2.518.1",
|
|
74
74
|
userAgent:
|
|
75
|
-
"speakeasy-sdk/typescript 0.
|
|
75
|
+
"speakeasy-sdk/typescript 0.11.0 2.518.1 0.0.3 @greensecurity/javascript-sdk",
|
|
76
76
|
} as const;
|
package/src/lib/files.ts
CHANGED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { buildCommand } from "@stricli/core";
|
|
6
|
+
import { numberParser } from "@stricli/core";
|
|
7
|
+
import * as z from "zod";
|
|
8
|
+
import { consoleLoggerLevels } from "../../console-logger.js";
|
|
9
|
+
import { mcpScopes } from "../../scopes.js";
|
|
10
|
+
|
|
11
|
+
export const startCommand = buildCommand({
|
|
12
|
+
loader: async () => {
|
|
13
|
+
const { main } = await import("./impl.js");
|
|
14
|
+
return main;
|
|
15
|
+
},
|
|
16
|
+
parameters: {
|
|
17
|
+
flags: {
|
|
18
|
+
"log-level": {
|
|
19
|
+
kind: "enum",
|
|
20
|
+
brief: "The log level to use for the server",
|
|
21
|
+
default: "info",
|
|
22
|
+
values: consoleLoggerLevels,
|
|
23
|
+
},
|
|
24
|
+
transport: {
|
|
25
|
+
kind: "enum",
|
|
26
|
+
brief: "The transport to use for communicating with the server",
|
|
27
|
+
default: "stdio",
|
|
28
|
+
values: ["stdio", "sse"],
|
|
29
|
+
},
|
|
30
|
+
port: {
|
|
31
|
+
kind: "parsed",
|
|
32
|
+
brief: "The port to use when the SSE transport is enabled",
|
|
33
|
+
default: "2718",
|
|
34
|
+
parse: (val: string) =>
|
|
35
|
+
z.coerce.number().int().gte(0).lt(65536).parse(val),
|
|
36
|
+
},
|
|
37
|
+
...(mcpScopes.length
|
|
38
|
+
? {
|
|
39
|
+
scope: {
|
|
40
|
+
kind: "enum",
|
|
41
|
+
brief:
|
|
42
|
+
"Mount tools/resources that match given scope (repeatable flag)",
|
|
43
|
+
values: mcpScopes,
|
|
44
|
+
variadic: true,
|
|
45
|
+
optional: true,
|
|
46
|
+
},
|
|
47
|
+
}
|
|
48
|
+
: {}),
|
|
49
|
+
|
|
50
|
+
"server-url": {
|
|
51
|
+
kind: "parsed",
|
|
52
|
+
brief: "Overrides the default server URL used by the SDK",
|
|
53
|
+
optional: true,
|
|
54
|
+
parse: (value) => new URL(value).toString(),
|
|
55
|
+
},
|
|
56
|
+
"server-index": {
|
|
57
|
+
kind: "parsed",
|
|
58
|
+
brief: "Selects a predefined server used by the SDK",
|
|
59
|
+
optional: true,
|
|
60
|
+
parse: numberParser,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
docs: {
|
|
65
|
+
brief: "Run the Model Context Protocol server",
|
|
66
|
+
},
|
|
67
|
+
});
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
6
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
7
|
+
import express from "express";
|
|
8
|
+
import { SDKOptions } from "../../../lib/config.js";
|
|
9
|
+
import { LocalContext } from "../../cli.js";
|
|
10
|
+
import {
|
|
11
|
+
ConsoleLoggerLevel,
|
|
12
|
+
createConsoleLogger,
|
|
13
|
+
} from "../../console-logger.js";
|
|
14
|
+
import { MCPScope } from "../../scopes.js";
|
|
15
|
+
import { createMCPServer } from "../../server.js";
|
|
16
|
+
|
|
17
|
+
interface StartCommandFlags {
|
|
18
|
+
readonly "log-level": ConsoleLoggerLevel;
|
|
19
|
+
readonly transport: "stdio" | "sse";
|
|
20
|
+
readonly port: number;
|
|
21
|
+
readonly scope?: MCPScope[];
|
|
22
|
+
readonly "server-url"?: string;
|
|
23
|
+
readonly "server-index"?: SDKOptions["serverIdx"];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export async function main(this: LocalContext, flags: StartCommandFlags) {
|
|
27
|
+
switch (flags.transport) {
|
|
28
|
+
case "stdio":
|
|
29
|
+
await startStdio(flags);
|
|
30
|
+
break;
|
|
31
|
+
case "sse":
|
|
32
|
+
await startSSE(flags);
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
throw new Error(`Invalid transport: ${flags.transport}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function startStdio(flags: StartCommandFlags) {
|
|
40
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
41
|
+
const transport = new StdioServerTransport();
|
|
42
|
+
const server = createMCPServer({
|
|
43
|
+
logger,
|
|
44
|
+
scopes: flags.scope,
|
|
45
|
+
serverURL: flags["server-url"],
|
|
46
|
+
serverIdx: flags["server-index"],
|
|
47
|
+
});
|
|
48
|
+
await server.connect(transport);
|
|
49
|
+
|
|
50
|
+
const abort = async () => {
|
|
51
|
+
await server.close();
|
|
52
|
+
process.exit(0);
|
|
53
|
+
};
|
|
54
|
+
process.on("SIGTERM", abort);
|
|
55
|
+
process.on("SIGINT", abort);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function startSSE(flags: StartCommandFlags) {
|
|
59
|
+
const logger = createConsoleLogger(flags["log-level"]);
|
|
60
|
+
const app = express();
|
|
61
|
+
const mcpServer = createMCPServer({
|
|
62
|
+
logger,
|
|
63
|
+
scopes: flags.scope,
|
|
64
|
+
serverURL: flags["server-url"],
|
|
65
|
+
serverIdx: flags["server-index"],
|
|
66
|
+
});
|
|
67
|
+
let transport: SSEServerTransport | undefined;
|
|
68
|
+
const controller = new AbortController();
|
|
69
|
+
|
|
70
|
+
app.get("/sse", async (_req, res) => {
|
|
71
|
+
transport = new SSEServerTransport("/message", res);
|
|
72
|
+
|
|
73
|
+
await mcpServer.connect(transport);
|
|
74
|
+
|
|
75
|
+
mcpServer.server.onclose = async () => {
|
|
76
|
+
res.end();
|
|
77
|
+
};
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
app.post("/message", async (req, res) => {
|
|
81
|
+
if (!transport) {
|
|
82
|
+
throw new Error("Server transport not initialized");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
await transport.handlePostMessage(req, res);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const httpServer = app.listen(flags.port, "0.0.0.0", () => {
|
|
89
|
+
const ha = httpServer.address();
|
|
90
|
+
const host = typeof ha === "string" ? ha : `${ha?.address}:${ha?.port}`;
|
|
91
|
+
logger.info("MCP HTTP server started", { host });
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
let closing = false;
|
|
95
|
+
controller.signal.addEventListener("abort", async () => {
|
|
96
|
+
if (closing) {
|
|
97
|
+
logger.info("Received second signal. Forcing shutdown.");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
closing = true;
|
|
101
|
+
|
|
102
|
+
logger.info("Shutting down MCP server");
|
|
103
|
+
|
|
104
|
+
await mcpServer.close();
|
|
105
|
+
|
|
106
|
+
logger.info("Shutting down HTTP server");
|
|
107
|
+
|
|
108
|
+
const timer = setTimeout(() => {
|
|
109
|
+
logger.info("Forcing shutdown");
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}, 5000);
|
|
112
|
+
|
|
113
|
+
httpServer.close(() => {
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
logger.info("Graceful shutdown complete");
|
|
116
|
+
process.exit(0);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
const abort = () => controller.abort();
|
|
121
|
+
process.on("SIGTERM", abort);
|
|
122
|
+
process.on("SIGINT", abort);
|
|
123
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { CommandContext, StricliProcess } from "@stricli/core";
|
|
6
|
+
|
|
7
|
+
export interface LocalContext extends CommandContext {
|
|
8
|
+
readonly process: StricliProcess;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function buildContext(process: NodeJS.Process): LocalContext {
|
|
12
|
+
return { process: process as StricliProcess };
|
|
13
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export const consoleLoggerLevels = [
|
|
6
|
+
"debug",
|
|
7
|
+
"warning",
|
|
8
|
+
"info",
|
|
9
|
+
"error",
|
|
10
|
+
] as const;
|
|
11
|
+
|
|
12
|
+
export type ConsoleLoggerLevel = (typeof consoleLoggerLevels)[number];
|
|
13
|
+
|
|
14
|
+
export type ConsoleLogger = {
|
|
15
|
+
[key in ConsoleLoggerLevel]: (
|
|
16
|
+
message: string,
|
|
17
|
+
data?: Record<string, unknown>,
|
|
18
|
+
) => void;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export function createConsoleLogger(level: ConsoleLoggerLevel): ConsoleLogger {
|
|
22
|
+
const min = consoleLoggerLevels.indexOf(level);
|
|
23
|
+
const noop = () => {};
|
|
24
|
+
|
|
25
|
+
const logger: ConsoleLogger = {
|
|
26
|
+
debug: noop,
|
|
27
|
+
warning: noop,
|
|
28
|
+
info: noop,
|
|
29
|
+
error: noop,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
return consoleLoggerLevels.reduce((logger, level, i) => {
|
|
33
|
+
if (i < min) {
|
|
34
|
+
return logger;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
logger[level] = log.bind(null, level);
|
|
38
|
+
|
|
39
|
+
return logger;
|
|
40
|
+
}, logger);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function log(
|
|
44
|
+
level: ConsoleLoggerLevel,
|
|
45
|
+
message: string,
|
|
46
|
+
data?: Record<string, unknown>,
|
|
47
|
+
) {
|
|
48
|
+
let line = "";
|
|
49
|
+
const allData = [{ msg: message, l: level }, data];
|
|
50
|
+
|
|
51
|
+
for (const ctx of allData) {
|
|
52
|
+
for (const [key, value] of Object.entries(ctx || {})) {
|
|
53
|
+
if (value == null) {
|
|
54
|
+
line += ` ${key}=<${value}>`;
|
|
55
|
+
} else if (typeof value === "function") {
|
|
56
|
+
line += ` ${key}=<function>`;
|
|
57
|
+
} else if (typeof value === "symbol") {
|
|
58
|
+
line += ` ${key}=${value.toString()}`;
|
|
59
|
+
} else if (typeof value === "string") {
|
|
60
|
+
const v = value.search(/\s/g) >= 0 ? JSON.stringify(value) : value;
|
|
61
|
+
line += ` ${key}=${v}`;
|
|
62
|
+
} else if (typeof value !== "object") {
|
|
63
|
+
line += ` ${key}=${value}`;
|
|
64
|
+
} else {
|
|
65
|
+
line += ` ${key}="${JSON.stringify(value)}"`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
console.error(line);
|
|
71
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { buildApplication, buildRouteMap, run } from "@stricli/core";
|
|
6
|
+
import process from "node:process";
|
|
7
|
+
import { buildContext } from "./cli.js";
|
|
8
|
+
import { startCommand } from "./cli/start/command.js";
|
|
9
|
+
|
|
10
|
+
const routes = buildRouteMap({
|
|
11
|
+
routes: {
|
|
12
|
+
start: startCommand,
|
|
13
|
+
},
|
|
14
|
+
docs: {
|
|
15
|
+
brief: "MCP server CLI",
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
export const app = buildApplication(routes, {
|
|
20
|
+
name: "mcp",
|
|
21
|
+
versionInfo: {
|
|
22
|
+
currentVersion: "0.11.0",
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
run(app, process.argv.slice(2), buildContext(process));
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
7
|
+
import { Variables } from "@modelcontextprotocol/sdk/shared/uriTemplate.js";
|
|
8
|
+
import { ReadResourceResult } from "@modelcontextprotocol/sdk/types.js";
|
|
9
|
+
import { GreenSecurityCore } from "../core.js";
|
|
10
|
+
import { Result } from "../types/fp.js";
|
|
11
|
+
import { MCPScope } from "./scopes.js";
|
|
12
|
+
import { isAsyncIterable, isBinaryData, valueToBase64 } from "./shared.js";
|
|
13
|
+
|
|
14
|
+
export type ReadResourceCallback = (
|
|
15
|
+
client: GreenSecurityCore,
|
|
16
|
+
uri: URL,
|
|
17
|
+
extra: RequestHandlerExtra,
|
|
18
|
+
) => ReadResourceResult | Promise<ReadResourceResult>;
|
|
19
|
+
|
|
20
|
+
export type ResourceDefinition = {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
scopes?: MCPScope[];
|
|
24
|
+
resource: string;
|
|
25
|
+
read: ReadResourceCallback;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type ReadResourceTemplateCallback = (
|
|
29
|
+
client: GreenSecurityCore,
|
|
30
|
+
uri: URL,
|
|
31
|
+
vars: Variables,
|
|
32
|
+
extra: RequestHandlerExtra,
|
|
33
|
+
) => ReadResourceResult | Promise<ReadResourceResult>;
|
|
34
|
+
|
|
35
|
+
export type ResourceTemplateDefinition = {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
scopes?: MCPScope[];
|
|
39
|
+
resource: ResourceTemplate;
|
|
40
|
+
read: ReadResourceTemplateCallback;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export async function formatResult(
|
|
44
|
+
result: Result<unknown, Error>,
|
|
45
|
+
uri: URL,
|
|
46
|
+
init: { response?: Response | undefined },
|
|
47
|
+
): Promise<ReadResourceResult> {
|
|
48
|
+
if (!result.ok) {
|
|
49
|
+
throw result.error;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { value } = result;
|
|
53
|
+
if (typeof value === "undefined") {
|
|
54
|
+
return { contents: [] };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { response } = init;
|
|
58
|
+
const mimeType = response?.headers.get("content-type") ?? "";
|
|
59
|
+
let contents: ReadResourceResult["contents"] = [];
|
|
60
|
+
|
|
61
|
+
if (mimeType.search(/\bjson\b/g)) {
|
|
62
|
+
contents = [{ uri: uri.toString(), mimeType, text: JSON.stringify(value) }];
|
|
63
|
+
} else if (
|
|
64
|
+
mimeType.startsWith("text/event-stream")
|
|
65
|
+
&& isAsyncIterable(value)
|
|
66
|
+
) {
|
|
67
|
+
contents = [
|
|
68
|
+
{
|
|
69
|
+
uri: uri.toString(),
|
|
70
|
+
mimeType: "application/json",
|
|
71
|
+
text: await stringifySSEToJSON(value),
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
} else if (mimeType.startsWith("text/") && typeof value === "string") {
|
|
75
|
+
contents = [{ uri: uri.toString(), mimeType, text: value }];
|
|
76
|
+
} else if (isBinaryData(value)) {
|
|
77
|
+
const blob = await valueToBase64(value);
|
|
78
|
+
contents = blob == null ? [] : [{ uri: uri.toString(), blob, mimeType }];
|
|
79
|
+
} else {
|
|
80
|
+
throw new Error(`Unsupported content type: "${mimeType}"`);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return { contents };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function stringifySSEToJSON(
|
|
87
|
+
value: AsyncIterable<unknown>,
|
|
88
|
+
): Promise<string> {
|
|
89
|
+
const payloads = [];
|
|
90
|
+
|
|
91
|
+
for await (const chunk of value) {
|
|
92
|
+
payloads.push(chunk);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return JSON.stringify(payloads);
|
|
96
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import { GreenSecurityCore } from "../core.js";
|
|
7
|
+
import { SDKOptions } from "../lib/config.js";
|
|
8
|
+
import type { ConsoleLogger } from "./console-logger.js";
|
|
9
|
+
import { MCPScope, mcpScopes } from "./scopes.js";
|
|
10
|
+
import { createRegisterTool } from "./tools.js";
|
|
11
|
+
import { tool$organizationsGetFacility } from "./tools/organizationsGetFacility.js";
|
|
12
|
+
import { tool$organizationsListOrSearchFacilities } from "./tools/organizationsListOrSearchFacilities.js";
|
|
13
|
+
import { tool$userGetCurrentUser } from "./tools/userGetCurrentUser.js";
|
|
14
|
+
import { tool$userGetUserById } from "./tools/userGetUserById.js";
|
|
15
|
+
import { tool$userLogsUserIntoTheSystem } from "./tools/userLogsUserIntoTheSystem.js";
|
|
16
|
+
import { tool$userMagiclink } from "./tools/userMagiclink.js";
|
|
17
|
+
import { tool$userPassword } from "./tools/userPassword.js";
|
|
18
|
+
import { tool$userPasswordResetRequest } from "./tools/userPasswordResetRequest.js";
|
|
19
|
+
import { tool$vendorsCreateVendorRegistration } from "./tools/vendorsCreateVendorRegistration.js";
|
|
20
|
+
import { tool$vendorsListVendorJobTitles } from "./tools/vendorsListVendorJobTitles.js";
|
|
21
|
+
|
|
22
|
+
export function createMCPServer(deps: {
|
|
23
|
+
logger: ConsoleLogger;
|
|
24
|
+
scopes?: MCPScope[] | undefined;
|
|
25
|
+
serverURL?: string | undefined;
|
|
26
|
+
serverIdx?: SDKOptions["serverIdx"];
|
|
27
|
+
}) {
|
|
28
|
+
const server = new McpServer({
|
|
29
|
+
name: "GreenSecurity",
|
|
30
|
+
version: "0.11.0",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const client = new GreenSecurityCore({
|
|
34
|
+
serverURL: deps.serverURL,
|
|
35
|
+
serverIdx: deps.serverIdx,
|
|
36
|
+
});
|
|
37
|
+
const scopes = new Set(deps.scopes ?? mcpScopes);
|
|
38
|
+
const tool = createRegisterTool(deps.logger, server, client, scopes);
|
|
39
|
+
|
|
40
|
+
tool(tool$vendorsCreateVendorRegistration);
|
|
41
|
+
tool(tool$vendorsListVendorJobTitles);
|
|
42
|
+
tool(tool$userGetCurrentUser);
|
|
43
|
+
tool(tool$userGetUserById);
|
|
44
|
+
tool(tool$userLogsUserIntoTheSystem);
|
|
45
|
+
tool(tool$userMagiclink);
|
|
46
|
+
tool(tool$userPasswordResetRequest);
|
|
47
|
+
tool(tool$userPassword);
|
|
48
|
+
tool(tool$organizationsListOrSearchFacilities);
|
|
49
|
+
tool(tool$organizationsGetFacility);
|
|
50
|
+
|
|
51
|
+
return server;
|
|
52
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as z from "zod";
|
|
6
|
+
import { bytesToBase64 } from "../lib/base64.js";
|
|
7
|
+
|
|
8
|
+
type BinaryData =
|
|
9
|
+
| Uint8Array
|
|
10
|
+
| ArrayBuffer
|
|
11
|
+
| Blob
|
|
12
|
+
| ReadableStream
|
|
13
|
+
| Response
|
|
14
|
+
| string;
|
|
15
|
+
|
|
16
|
+
export async function consumeStream(
|
|
17
|
+
stream: ReadableStream<Uint8Array>,
|
|
18
|
+
): Promise<Uint8Array> {
|
|
19
|
+
const reader = stream.getReader();
|
|
20
|
+
const chunks: Uint8Array[] = [];
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
while (true) {
|
|
24
|
+
const { done, value } = await reader.read();
|
|
25
|
+
if (value != null) chunks.push(value);
|
|
26
|
+
if (done) break;
|
|
27
|
+
}
|
|
28
|
+
} finally {
|
|
29
|
+
reader.releaseLock();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return new Uint8Array(await new Blob(chunks).arrayBuffer());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function isAsyncIterable(
|
|
36
|
+
value: unknown,
|
|
37
|
+
): value is AsyncIterable<string> {
|
|
38
|
+
return (
|
|
39
|
+
typeof value === "object" && value != null && Symbol.asyncIterator in value
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function isBinaryData(value: unknown): value is BinaryData {
|
|
44
|
+
return (
|
|
45
|
+
value instanceof Uint8Array
|
|
46
|
+
|| value instanceof ArrayBuffer
|
|
47
|
+
|| value instanceof Blob
|
|
48
|
+
|| value instanceof ReadableStream
|
|
49
|
+
|| value instanceof Response
|
|
50
|
+
|| typeof value === "string"
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const base64Schema = z.string().base64();
|
|
55
|
+
|
|
56
|
+
export async function valueToBase64(
|
|
57
|
+
value: BinaryData | null | undefined,
|
|
58
|
+
): Promise<string | null> {
|
|
59
|
+
if (value == null) {
|
|
60
|
+
return null;
|
|
61
|
+
} else if (value instanceof Uint8Array) {
|
|
62
|
+
return bytesToBase64(value);
|
|
63
|
+
} else if (value instanceof ArrayBuffer) {
|
|
64
|
+
return bytesToBase64(new Uint8Array(value));
|
|
65
|
+
} else if (value instanceof Response || value instanceof Blob) {
|
|
66
|
+
return bytesToBase64(new Uint8Array(await value.arrayBuffer()));
|
|
67
|
+
} else if (value instanceof ReadableStream) {
|
|
68
|
+
return bytesToBase64(await consumeStream(value));
|
|
69
|
+
} else if (typeof value === "string") {
|
|
70
|
+
return base64Schema.parse(value);
|
|
71
|
+
} else {
|
|
72
|
+
value satisfies never;
|
|
73
|
+
throw new Error(`Unsupported image value type: ${typeof value}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { organizationsGetFacility } from "../../funcs/organizationsGetFacility.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.GetFacilityRequest$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$organizationsGetFacility: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "organizations_get-facility",
|
|
15
|
+
description: `Get facility
|
|
16
|
+
|
|
17
|
+
Retrieve an individual facility.`,
|
|
18
|
+
args,
|
|
19
|
+
tool: async (client, args, ctx) => {
|
|
20
|
+
const [result, apiCall] = await organizationsGetFacility(
|
|
21
|
+
client,
|
|
22
|
+
args.request,
|
|
23
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
24
|
+
).$inspect();
|
|
25
|
+
|
|
26
|
+
if (!result.ok) {
|
|
27
|
+
return {
|
|
28
|
+
content: [{ type: "text", text: result.error.message }],
|
|
29
|
+
isError: true,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const value = result.value;
|
|
34
|
+
|
|
35
|
+
return formatResult(value, apiCall);
|
|
36
|
+
},
|
|
37
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { organizationsListOrSearchFacilities } from "../../funcs/organizationsListOrSearchFacilities.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.ListOrSearchFacilitiesRequest$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$organizationsListOrSearchFacilities: ToolDefinition<
|
|
14
|
+
typeof args
|
|
15
|
+
> = {
|
|
16
|
+
name: "organizations_list-or-search-facilities",
|
|
17
|
+
description: `List or search facilities
|
|
18
|
+
|
|
19
|
+
List or search facilities.
|
|
20
|
+
|
|
21
|
+
Available \`expand\` scopes are:
|
|
22
|
+
|
|
23
|
+
- facility.appointment_policy
|
|
24
|
+
- facility.contacts
|
|
25
|
+
- facility.vendor_counts
|
|
26
|
+
- facility.flu_credential
|
|
27
|
+
- facility.scrubs_policy
|
|
28
|
+
- facility.system
|
|
29
|
+
- facility.vendor_guest_policy
|
|
30
|
+
- facility.vendor_policy
|
|
31
|
+
- facility.visitor_policy
|
|
32
|
+
- facility.workflow`,
|
|
33
|
+
args,
|
|
34
|
+
tool: async (client, args, ctx) => {
|
|
35
|
+
const [result, apiCall] = await organizationsListOrSearchFacilities(
|
|
36
|
+
client,
|
|
37
|
+
args.request,
|
|
38
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
39
|
+
).$inspect();
|
|
40
|
+
|
|
41
|
+
if (!result.ok) {
|
|
42
|
+
return {
|
|
43
|
+
content: [{ type: "text", text: result.error.message }],
|
|
44
|
+
isError: true,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const value = result.value;
|
|
49
|
+
|
|
50
|
+
return formatResult(value, apiCall);
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userGetCurrentUser } from "../../funcs/userGetCurrentUser.js";
|
|
6
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
7
|
+
|
|
8
|
+
export const tool$userGetCurrentUser: ToolDefinition = {
|
|
9
|
+
name: "user_get-current-user",
|
|
10
|
+
description: `Get current user
|
|
11
|
+
|
|
12
|
+
Returns a user object for the user represented by the authorization token`,
|
|
13
|
+
tool: async (client, ctx) => {
|
|
14
|
+
const [result, apiCall] = await userGetCurrentUser(
|
|
15
|
+
client,
|
|
16
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
17
|
+
).$inspect();
|
|
18
|
+
|
|
19
|
+
if (!result.ok) {
|
|
20
|
+
return {
|
|
21
|
+
content: [{ type: "text", text: result.error.message }],
|
|
22
|
+
isError: true,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const value = result.value;
|
|
27
|
+
|
|
28
|
+
return formatResult(value, apiCall);
|
|
29
|
+
},
|
|
30
|
+
};
|