@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
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userGetUserById } from "../../funcs/userGetUserById.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.GetUserByIdRequest$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$userGetUserById: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "user_get-user-by-id",
|
|
15
|
+
description: `Get user by id
|
|
16
|
+
|
|
17
|
+
Returns a user object for the user represented by the identifier in the path.`,
|
|
18
|
+
args,
|
|
19
|
+
tool: async (client, args, ctx) => {
|
|
20
|
+
const [result, apiCall] = await userGetUserById(
|
|
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,67 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userLogsUserIntoTheSystem } from "../../funcs/userLogsUserIntoTheSystem.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.LogsUserIntoTheSystemRequestBody$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$userLogsUserIntoTheSystem: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "user_logs-user-into-the-system",
|
|
15
|
+
description: `Logs user into the system
|
|
16
|
+
|
|
17
|
+
This endpoint allows a user to authenticate themselves and retrieve a permanent token for access.
|
|
18
|
+
|
|
19
|
+
Permanent tokens should only ever be stored in an encrypted storage because they represent a fully logged in user.
|
|
20
|
+
|
|
21
|
+
Users may log in with \`email/password\`, \`SAML\`, \`magic link\` or \`mfa\`. The application should handle all of the above as equally valid login methods.
|
|
22
|
+
|
|
23
|
+
The most common way to authenticate a user is to log in with an email and password. If the user provides valid credentials, the server will either respond with a full user object including the token.
|
|
24
|
+
|
|
25
|
+
When the user's account is protected via MFA, the server will send a 6 digit code to the user via their default MFA provider. You should collect that code and resend the email, password and mfa_code together to get a successful authentication.
|
|
26
|
+
|
|
27
|
+
The ideal flow for a login sequence is the following:
|
|
28
|
+
|
|
29
|
+
1. Present an email address field only and allow the user to submit
|
|
30
|
+
2. Send \`email\` and \`return_url\` payload to this endpoint
|
|
31
|
+
3. Follow the flow based on the response \`requires\` field
|
|
32
|
+
|
|
33
|
+
Requires: \`password\`
|
|
34
|
+
|
|
35
|
+
1. Show a password field for the user to fill out
|
|
36
|
+
2. Submit the \`email\` and \`password\` to this endpoint
|
|
37
|
+
3. If the response is \`200\`, the login is done. If the response is \`201\`, then check if \`requires: mfa_code\` is returned and show MFA flow
|
|
38
|
+
4. Submit \`email\`, \`password\`, \`mfa_code\` to this endpoint
|
|
39
|
+
5. If the response is \`200\`, the login is done. Otherwise, show the appropriate error to the user and go back to step 1 or 3 depending on the error.
|
|
40
|
+
|
|
41
|
+
Requires: \`saml_login\`
|
|
42
|
+
|
|
43
|
+
1. [Open a browser](https://docs.expo.dev/versions/latest/sdk/webbrowser/#webbrowseropenauthsessionasyncurl-redirecturl-options) to the url returned in \`sso_url\`
|
|
44
|
+
2. User completes sign-in using their configured SAML IdP
|
|
45
|
+
3. Site redirects to your selected \`return_url\`
|
|
46
|
+
4. The \`user_token\` will be appended as a query string parameter to your \`return_url\` - you must parse this token and store it
|
|
47
|
+
5. Fetch the user object from \`/users/me\` using the token`,
|
|
48
|
+
args,
|
|
49
|
+
tool: async (client, args, ctx) => {
|
|
50
|
+
const [result, apiCall] = await userLogsUserIntoTheSystem(
|
|
51
|
+
client,
|
|
52
|
+
args.request,
|
|
53
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
54
|
+
).$inspect();
|
|
55
|
+
|
|
56
|
+
if (!result.ok) {
|
|
57
|
+
return {
|
|
58
|
+
content: [{ type: "text", text: result.error.message }],
|
|
59
|
+
isError: true,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const value = result.value;
|
|
64
|
+
|
|
65
|
+
return formatResult(value, apiCall);
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userMagiclink } from "../../funcs/userMagiclink.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.MagiclinkRequestBody$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$userMagiclink: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "user_magiclink",
|
|
15
|
+
description: `Magic link
|
|
16
|
+
|
|
17
|
+
It sends an email with a magic link to allow the user to log in.`,
|
|
18
|
+
args,
|
|
19
|
+
tool: async (client, args, ctx) => {
|
|
20
|
+
const [result, apiCall] = await userMagiclink(
|
|
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,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userPassword } from "../../funcs/userPassword.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.PasswordRequestBody$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$userPassword: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "user_password",
|
|
15
|
+
description: `Password reset
|
|
16
|
+
|
|
17
|
+
Resets the a user's password using a password_reset_id that was sent to them via email.
|
|
18
|
+
See /users/passwordresetrequest to initiate a password reset flow.`,
|
|
19
|
+
args,
|
|
20
|
+
tool: async (client, args, ctx) => {
|
|
21
|
+
const [result, apiCall] = await userPassword(
|
|
22
|
+
client,
|
|
23
|
+
args.request,
|
|
24
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
25
|
+
).$inspect();
|
|
26
|
+
|
|
27
|
+
if (!result.ok) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{ type: "text", text: result.error.message }],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const value = result.value;
|
|
35
|
+
|
|
36
|
+
return formatResult(value, apiCall);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { userPasswordResetRequest } from "../../funcs/userPasswordResetRequest.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.PasswordResetRequestRequestBody$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$userPasswordResetRequest: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "user_password-reset-request",
|
|
15
|
+
description: `Password reset request
|
|
16
|
+
|
|
17
|
+
It sends an email with a link for resetting a user's password.`,
|
|
18
|
+
args,
|
|
19
|
+
tool: async (client, args, ctx) => {
|
|
20
|
+
const [result, apiCall] = await userPasswordResetRequest(
|
|
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,38 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { vendorsCreateVendorRegistration } from "../../funcs/vendorsCreateVendorRegistration.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.CreateVendorRegistrationRequestBody$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$vendorsCreateVendorRegistration: ToolDefinition<typeof args> =
|
|
14
|
+
{
|
|
15
|
+
name: "vendors_create-vendor-registration",
|
|
16
|
+
description: `Create vendor registration
|
|
17
|
+
|
|
18
|
+
Create an initial vendor registration. Once successful, the vendor will be able to continue to filling out the rest of their onboarding profile.`,
|
|
19
|
+
args,
|
|
20
|
+
tool: async (client, args, ctx) => {
|
|
21
|
+
const [result, apiCall] = await vendorsCreateVendorRegistration(
|
|
22
|
+
client,
|
|
23
|
+
args.request,
|
|
24
|
+
{ fetchOptions: { signal: ctx.signal } },
|
|
25
|
+
).$inspect();
|
|
26
|
+
|
|
27
|
+
if (!result.ok) {
|
|
28
|
+
return {
|
|
29
|
+
content: [{ type: "text", text: result.error.message }],
|
|
30
|
+
isError: true,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const value = result.value;
|
|
35
|
+
|
|
36
|
+
return formatResult(value, apiCall);
|
|
37
|
+
},
|
|
38
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { vendorsListVendorJobTitles } from "../../funcs/vendorsListVendorJobTitles.js";
|
|
6
|
+
import * as operations from "../../models/operations/index.js";
|
|
7
|
+
import { formatResult, ToolDefinition } from "../tools.js";
|
|
8
|
+
|
|
9
|
+
const args = {
|
|
10
|
+
request: operations.ListVendorJobTitlesRequest$inboundSchema,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const tool$vendorsListVendorJobTitles: ToolDefinition<typeof args> = {
|
|
14
|
+
name: "vendors_list-vendor-job-titles",
|
|
15
|
+
description: `List vendor job titles
|
|
16
|
+
|
|
17
|
+
List valid job titles for Vendors. This can be used during sign up or in a filter.`,
|
|
18
|
+
args,
|
|
19
|
+
tool: async (client, args, ctx) => {
|
|
20
|
+
const [result, apiCall] = await vendorsListVendorJobTitles(
|
|
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,116 @@
|
|
|
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 { RequestHandlerExtra } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
7
|
+
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
8
|
+
import { objectOutputType, ZodRawShape, ZodTypeAny } from "zod";
|
|
9
|
+
import { GreenSecurityCore } from "../core.js";
|
|
10
|
+
import { ConsoleLogger } from "./console-logger.js";
|
|
11
|
+
import { MCPScope } from "./scopes.js";
|
|
12
|
+
import { isAsyncIterable, isBinaryData, valueToBase64 } from "./shared.js";
|
|
13
|
+
|
|
14
|
+
export type ToolDefinition<Args extends undefined | ZodRawShape = undefined> =
|
|
15
|
+
Args extends ZodRawShape ? {
|
|
16
|
+
name: string;
|
|
17
|
+
description: string;
|
|
18
|
+
scopes?: MCPScope[];
|
|
19
|
+
args: Args;
|
|
20
|
+
tool: (
|
|
21
|
+
client: GreenSecurityCore,
|
|
22
|
+
args: objectOutputType<Args, ZodTypeAny>,
|
|
23
|
+
extra: RequestHandlerExtra,
|
|
24
|
+
) => CallToolResult | Promise<CallToolResult>;
|
|
25
|
+
}
|
|
26
|
+
: {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
scopes?: MCPScope[];
|
|
30
|
+
args?: undefined;
|
|
31
|
+
tool: (
|
|
32
|
+
client: GreenSecurityCore,
|
|
33
|
+
extra: RequestHandlerExtra,
|
|
34
|
+
) => CallToolResult | Promise<CallToolResult>;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export async function formatResult(
|
|
38
|
+
value: unknown,
|
|
39
|
+
init: { response?: Response | undefined },
|
|
40
|
+
): Promise<CallToolResult> {
|
|
41
|
+
if (typeof value === "undefined") {
|
|
42
|
+
return { content: [] };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const { response } = init;
|
|
46
|
+
const contentType = response?.headers.get("content-type") ?? "";
|
|
47
|
+
let content: CallToolResult["content"] = [];
|
|
48
|
+
|
|
49
|
+
if (contentType.search(/\bjson\b/g)) {
|
|
50
|
+
content = [{ type: "text", text: JSON.stringify(value) }];
|
|
51
|
+
} else if (
|
|
52
|
+
contentType.startsWith("text/event-stream")
|
|
53
|
+
&& isAsyncIterable(value)
|
|
54
|
+
) {
|
|
55
|
+
content = await consumeSSE(value);
|
|
56
|
+
} else if (contentType.startsWith("text/") && typeof value === "string") {
|
|
57
|
+
content = [{ type: "text", text: value }];
|
|
58
|
+
} else if (isBinaryData(value) && contentType.startsWith("image/")) {
|
|
59
|
+
const data = await valueToBase64(value);
|
|
60
|
+
content = data == null
|
|
61
|
+
? []
|
|
62
|
+
: [{ type: "image", data, mimeType: contentType }];
|
|
63
|
+
} else {
|
|
64
|
+
return {
|
|
65
|
+
content: [{
|
|
66
|
+
type: "text",
|
|
67
|
+
text: `Unsupported content type: "${contentType}"`,
|
|
68
|
+
}],
|
|
69
|
+
isError: true,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { content };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function consumeSSE(
|
|
77
|
+
value: AsyncIterable<unknown>,
|
|
78
|
+
): Promise<CallToolResult["content"]> {
|
|
79
|
+
const content: CallToolResult["content"] = [];
|
|
80
|
+
|
|
81
|
+
for await (const chunk of value) {
|
|
82
|
+
if (typeof chunk === "string") {
|
|
83
|
+
content.push({ type: "text", text: chunk });
|
|
84
|
+
} else {
|
|
85
|
+
content.push({ type: "text", text: JSON.stringify(chunk) });
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return content;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function createRegisterTool(
|
|
93
|
+
logger: ConsoleLogger,
|
|
94
|
+
server: McpServer,
|
|
95
|
+
sdk: GreenSecurityCore,
|
|
96
|
+
allowedScopes: Set<MCPScope>,
|
|
97
|
+
): <A extends ZodRawShape | undefined>(tool: ToolDefinition<A>) => void {
|
|
98
|
+
return <A extends ZodRawShape | undefined>(tool: ToolDefinition<A>): void => {
|
|
99
|
+
const toolScopes = tool.scopes ?? [];
|
|
100
|
+
if (!toolScopes.every((s) => allowedScopes.has(s))) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (tool.args) {
|
|
105
|
+
server.tool(tool.name, tool.description, tool.args, async (args, ctx) => {
|
|
106
|
+
return tool.tool(sdk, args, ctx);
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
server.tool(tool.name, tool.description, async (ctx) => {
|
|
110
|
+
return tool.tool(sdk, ctx);
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
logger.debug("Registered tool", { name: tool.name });
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -17,7 +17,7 @@ export type PasswordRequestBody = {
|
|
|
17
17
|
* The request was successful, and the server has returned the requested resource in the response body.
|
|
18
18
|
*/
|
|
19
19
|
export type PasswordResponseBody = {
|
|
20
|
-
success
|
|
20
|
+
success?: boolean | null | undefined;
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/** @internal */
|
|
@@ -91,12 +91,12 @@ export const PasswordResponseBody$inboundSchema: z.ZodType<
|
|
|
91
91
|
z.ZodTypeDef,
|
|
92
92
|
unknown
|
|
93
93
|
> = z.object({
|
|
94
|
-
success: z.
|
|
94
|
+
success: z.nullable(z.boolean()).optional(),
|
|
95
95
|
});
|
|
96
96
|
|
|
97
97
|
/** @internal */
|
|
98
98
|
export type PasswordResponseBody$Outbound = {
|
|
99
|
-
success
|
|
99
|
+
success?: boolean | null | undefined;
|
|
100
100
|
};
|
|
101
101
|
|
|
102
102
|
/** @internal */
|
|
@@ -105,7 +105,7 @@ export const PasswordResponseBody$outboundSchema: z.ZodType<
|
|
|
105
105
|
z.ZodTypeDef,
|
|
106
106
|
PasswordResponseBody
|
|
107
107
|
> = z.object({
|
|
108
|
-
success: z.
|
|
108
|
+
success: z.nullable(z.boolean()).optional(),
|
|
109
109
|
});
|
|
110
110
|
|
|
111
111
|
/**
|