@alfe.ai/connectwise-screenconnect-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 ADDED
@@ -0,0 +1,104 @@
1
+ # ConnectWise ScreenConnect MCP
2
+
3
+ Runtime-independent stdio MCP server for ScreenConnect's RESTful API Manager
4
+ extension. Alfe Connections supplies credentials at execution time. Every
5
+ provider operation requires the exact `connectionId` returned by
6
+ `screenconnect_list_connections`.
7
+
8
+ ## Setup
9
+
10
+ 1. Install the **RESTful API Manager** extension in the ScreenConnect
11
+ administration Extension Marketplace. This integration implements the
12
+ documented 1.0.8 API contract (server 22.3 or newer); notes need 1.0.6+.
13
+ 2. Set the extension's `RESTfulAuthenticationSecret` to a strong random secret
14
+ and configure its execution user/permissions for the operations you need.
15
+ 3. Leave `RESTfulAllowedOrigin` empty or set it to the ScreenConnect site's
16
+ origin, such as `https://support.example.com`. The runtime sends that origin
17
+ on requests.
18
+ 4. Add a **ConnectWise ScreenConnect** connection in Alfe with that site's
19
+ HTTPS origin and authentication secret, at a scope the agent can access.
20
+ 5. The connection-driven integration launches the server automatically.
21
+ For manual testing on an already configured agent:
22
+
23
+ ```sh
24
+ npx -y @alfe.ai/connectwise-screenconnect-mcp@0.1.0
25
+ ```
26
+
27
+ `@alfe.ai/config` supplies the Alfe API key and API URL from the normal agent
28
+ configuration. No ScreenConnect credentials are passed through command-line
29
+ arguments or integration environment variables. The binary is
30
+ `connectwise-screenconnect-mcp`.
31
+
32
+ ## Tools
33
+
34
+ | Tool | Purpose |
35
+ | --- | --- |
36
+ | `screenconnect_list_connections` | Discover connections without exposing secrets |
37
+ | `screenconnect_check_connection` | Verify extension access with a read that matches no sessions |
38
+ | `screenconnect_list_sessions` | Query sessions by a required session filter |
39
+ | `screenconnect_find_sessions` | Find sessions by name |
40
+ | `screenconnect_get_session` | Retrieve a session by its GUID |
41
+ | `screenconnect_get_session_details` | Inspect events and connections, omitting screenshot bytes |
42
+ | `screenconnect_create_session` | Create Support or Meeting sessions |
43
+ | `screenconnect_rename_session` | Replace a session's display name |
44
+ | `screenconnect_update_custom_properties` | Replace up to eight positional custom properties |
45
+ | `screenconnect_add_note` | Append a session note |
46
+ | `screenconnect_send_message` | Send a message attributed to a host |
47
+ | `screenconnect_run_command` | Queue a remote command with exact target/content confirmation |
48
+ | `screenconnect_run_toolbox_item` | Queue an existing toolbox item with exact target/item confirmation |
49
+
50
+ The API has no session pagination. The required filter controls the provider
51
+ query; `limit` (1–500, default 100) limits the returned tool result and reports
52
+ truncation. Narrow filters when the provider response exceeds 5 MiB.
53
+
54
+ Create supports `Support` and `Meeting`, and private sessions require a join
55
+ code. Access agent installation is a different API and is not exposed here.
56
+ Custom-property updates replace the entire positional array, so read the
57
+ current values and preserve those you want to keep.
58
+
59
+ Remote command/toolbox responses mean **accepted**, not completed. Inspect
60
+ session details for execution results. Requests are never automatically
61
+ retried; check the resulting session state before retrying a mutation after a
62
+ timeout or transport error.
63
+
64
+ ## Request contract
65
+
66
+ All requests target the fixed extension prefix
67
+ `/App_Extensions/2d558935-686a-4bd0-9991-07539f5fe749/Service.ashx/`.
68
+ Read methods use GET and mutations use POST, with `application/json` positional
69
+ array bodies and the `CTRLAuthHeader` authentication header. Node's HTTPS
70
+ transport supports the documented GET request bodies.
71
+
72
+ Before every request, all DNS answers must be public. The connection is pinned
73
+ to those checked addresses with the original TLS hostname/certificate checks.
74
+ Redirects are never followed. DNS, connection, and response streaming share a
75
+ 30-second deadline. Request bodies are capped at 128 KiB and responses at
76
+ 5 MiB. Errors omit provider bodies, URLs, credential bundles, and original
77
+ network exception causes.
78
+
79
+ ## Verification
80
+
81
+ ```sh
82
+ pnpm --filter @alfe.ai/connectwise-screenconnect-mcp typecheck
83
+ pnpm --filter @alfe.ai/connectwise-screenconnect-mcp lint
84
+ pnpm --filter @alfe.ai/connectwise-screenconnect-mcp test
85
+ pnpm --filter @alfe.ai/connectwise-screenconnect-mcp build
86
+ ```
87
+
88
+ Contract tests verify transport/authentication, pinned DNS and SSRF rejection,
89
+ response bounds, no mutation retries, credential rotation/isolation, and real
90
+ MCP client/server exchanges. These tests do not constitute live tenant
91
+ verification. Before rollout, use an approved ScreenConnect test instance with
92
+ the extension configured to verify creation, updates, notes, messaging, and
93
+ command/toolbox execution against a disposable session.
94
+
95
+ Official references verified 2026-09-08:
96
+
97
+ - [RESTful API Manager](https://docs.connectwise.com/ScreenConnect_Documentation/Developers/RESTful_API_Manager)
98
+ - [Session Manager API](https://docs.connectwise.com/ScreenConnect_Documentation/Developers/Session_Manager_API_Reference)
99
+ - [Session and session-details objects](https://docs.connectwise.com/ScreenConnect_Documentation/Developers/Session_Manager_API_Reference/Objects)
100
+ - [Extension release notes](https://screenconnect.product.connectwise.com/communities/26/topics/4301-restful-api-manager)
101
+
102
+ The documentation site may redirect to ConnectWise University authentication.
103
+ The protocol contract was also available through the official page's search
104
+ index at implementation time.
package/dist/bin.cjs ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ const require_screenconnect_client = require("./screenconnect-client2.cjs");
3
+ const require_server = require("./server2.cjs");
4
+ //#region src/cli.ts
5
+ async function runCli(start = require_server.startServer, runtime = process) {
6
+ let server;
7
+ try {
8
+ server = await start();
9
+ } catch (error) {
10
+ runtime.stderr.write(`[screenconnect-mcp] Failed to start: ${require_screenconnect_client.safeErrorMessage(error)}\n`);
11
+ runtime.exitCode = 1;
12
+ return;
13
+ }
14
+ let closing = false;
15
+ const shutdown = () => {
16
+ if (closing) return;
17
+ closing = true;
18
+ runtime.off("SIGINT", shutdown);
19
+ runtime.off("SIGTERM", shutdown);
20
+ server.close().catch(() => {
21
+ runtime.stderr.write("[screenconnect-mcp] Transport cleanup failed.\n");
22
+ }).finally(() => runtime.exit(0));
23
+ };
24
+ runtime.once("SIGINT", shutdown);
25
+ runtime.once("SIGTERM", shutdown);
26
+ }
27
+ //#endregion
28
+ //#region src/bin.ts
29
+ runCli();
30
+ //#endregion
package/dist/bin.d.cts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/bin.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import { d as safeErrorMessage } from "./screenconnect-client2.js";
3
+ import { i as startServer } from "./server2.js";
4
+ //#region src/cli.ts
5
+ async function runCli(start = startServer, runtime = process) {
6
+ let server;
7
+ try {
8
+ server = await start();
9
+ } catch (error) {
10
+ runtime.stderr.write(`[screenconnect-mcp] Failed to start: ${safeErrorMessage(error)}\n`);
11
+ runtime.exitCode = 1;
12
+ return;
13
+ }
14
+ let closing = false;
15
+ const shutdown = () => {
16
+ if (closing) return;
17
+ closing = true;
18
+ runtime.off("SIGINT", shutdown);
19
+ runtime.off("SIGTERM", shutdown);
20
+ server.close().catch(() => {
21
+ runtime.stderr.write("[screenconnect-mcp] Transport cleanup failed.\n");
22
+ }).finally(() => runtime.exit(0));
23
+ };
24
+ runtime.once("SIGINT", shutdown);
25
+ runtime.once("SIGTERM", shutdown);
26
+ }
27
+ //#endregion
28
+ //#region src/bin.ts
29
+ runCli();
30
+ //#endregion
31
+ export {};
@@ -0,0 +1,5 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_screenconnect_client = require("./screenconnect-client2.cjs");
3
+ exports.EXTENSION_PATH = require_screenconnect_client.EXTENSION_PATH;
4
+ exports.ScreenConnectClient = require_screenconnect_client.ScreenConnectClient;
5
+ exports.pinnedLookup = require_screenconnect_client.pinnedLookup;
@@ -0,0 +1,92 @@
1
+ import { RequestOptions } from "node:https";
2
+ import { ClientRequest, IncomingMessage } from "node:http";
3
+ import { LookupFunction } from "node:net";
4
+ import { z } from "zod";
5
+
6
+ //#region src/boundary.d.ts
7
+
8
+ interface ResolvedAddress {
9
+ address: string;
10
+ family: number;
11
+ }
12
+ type ResolveHost = (hostname: string) => Promise<ResolvedAddress[]>;
13
+ //#endregion
14
+ //#region src/screenconnect-client.d.ts
15
+ declare const EXTENSION_PATH = "/App_Extensions/2d558935-686a-4bd0-9991-07539f5fe749/Service.ashx/";
16
+ /** Positional contracts from the official RESTful API Manager reference. */
17
+ declare const methods: {
18
+ readonly GetSessionsByFilter: {
19
+ readonly method: "GET";
20
+ readonly parameters: z.ZodTuple<[z.ZodString], null>;
21
+ };
22
+ readonly GetSessionsByName: {
23
+ readonly method: "GET";
24
+ readonly parameters: z.ZodTuple<[z.ZodString], null>;
25
+ };
26
+ readonly GetSessionBySessionID: {
27
+ readonly method: "GET";
28
+ readonly parameters: z.ZodTuple<[z.ZodUUID], null>;
29
+ };
30
+ readonly GetSessionDetailsBySessionID: {
31
+ readonly method: "GET";
32
+ readonly parameters: z.ZodTuple<[z.ZodUUID], null>;
33
+ };
34
+ readonly CreateSession: {
35
+ readonly method: "POST";
36
+ readonly parameters: z.ZodTuple<[z.ZodEnum<{
37
+ Support: "Support";
38
+ Meeting: "Meeting";
39
+ }>, z.ZodString, z.ZodBoolean, z.ZodString, z.ZodArray<z.ZodString>], null>;
40
+ };
41
+ readonly UpdateSessionName: {
42
+ readonly method: "POST";
43
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
44
+ };
45
+ readonly UpdateSessionCustomProperties: {
46
+ readonly method: "POST";
47
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodArray<z.ZodString>], null>;
48
+ };
49
+ readonly AddNoteToSession: {
50
+ readonly method: "POST";
51
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
52
+ };
53
+ readonly SendMessageToSession: {
54
+ readonly method: "POST";
55
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString, z.ZodString], null>;
56
+ };
57
+ readonly SendCommandToSession: {
58
+ readonly method: "POST";
59
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
60
+ };
61
+ readonly SendToolboxItemToSession: {
62
+ readonly method: "POST";
63
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
64
+ };
65
+ };
66
+ type ScreenConnectMethod = keyof typeof methods;
67
+ interface ScreenConnectApi {
68
+ call(method: ScreenConnectMethod, parameters: unknown[]): Promise<unknown>;
69
+ }
70
+ type RequestFactory = (url: URL, options: RequestOptions, onResponse: (response: IncomingMessage) => void) => ClientRequest;
71
+ interface ScreenConnectClientOptions {
72
+ siteUrl: string;
73
+ authenticationSecret: string;
74
+ /** Injection boundaries for contract tests; never sourced from tool input. */
75
+ resolveHost?: ResolveHost;
76
+ requestFactory?: RequestFactory;
77
+ requestTimeoutMs?: number;
78
+ }
79
+ declare class ScreenConnectClient implements ScreenConnectApi {
80
+ readonly siteUrl: string;
81
+ private readonly secret;
82
+ private readonly resolveHost?;
83
+ private readonly requestFactory;
84
+ private readonly timeoutMs;
85
+ constructor(options: ScreenConnectClientOptions);
86
+ call(method: ScreenConnectMethod, parameters: unknown[]): Promise<unknown>;
87
+ private send;
88
+ }
89
+ /** No second DNS resolution is allowed between validation and connection. */
90
+ declare function pinnedLookup(addresses: ResolvedAddress[]): LookupFunction;
91
+ //#endregion
92
+ export { ScreenConnectClientOptions as a, ScreenConnectClient as i, RequestFactory as n, ScreenConnectMethod as o, ScreenConnectApi as r, pinnedLookup as s, EXTENSION_PATH as t };
@@ -0,0 +1,92 @@
1
+ import { LookupFunction } from "node:net";
2
+ import { z } from "zod";
3
+ import { RequestOptions } from "node:https";
4
+ import { ClientRequest, IncomingMessage } from "node:http";
5
+
6
+ //#region src/boundary.d.ts
7
+
8
+ interface ResolvedAddress {
9
+ address: string;
10
+ family: number;
11
+ }
12
+ type ResolveHost = (hostname: string) => Promise<ResolvedAddress[]>;
13
+ //#endregion
14
+ //#region src/screenconnect-client.d.ts
15
+ declare const EXTENSION_PATH = "/App_Extensions/2d558935-686a-4bd0-9991-07539f5fe749/Service.ashx/";
16
+ /** Positional contracts from the official RESTful API Manager reference. */
17
+ declare const methods: {
18
+ readonly GetSessionsByFilter: {
19
+ readonly method: "GET";
20
+ readonly parameters: z.ZodTuple<[z.ZodString], null>;
21
+ };
22
+ readonly GetSessionsByName: {
23
+ readonly method: "GET";
24
+ readonly parameters: z.ZodTuple<[z.ZodString], null>;
25
+ };
26
+ readonly GetSessionBySessionID: {
27
+ readonly method: "GET";
28
+ readonly parameters: z.ZodTuple<[z.ZodUUID], null>;
29
+ };
30
+ readonly GetSessionDetailsBySessionID: {
31
+ readonly method: "GET";
32
+ readonly parameters: z.ZodTuple<[z.ZodUUID], null>;
33
+ };
34
+ readonly CreateSession: {
35
+ readonly method: "POST";
36
+ readonly parameters: z.ZodTuple<[z.ZodEnum<{
37
+ Support: "Support";
38
+ Meeting: "Meeting";
39
+ }>, z.ZodString, z.ZodBoolean, z.ZodString, z.ZodArray<z.ZodString>], null>;
40
+ };
41
+ readonly UpdateSessionName: {
42
+ readonly method: "POST";
43
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
44
+ };
45
+ readonly UpdateSessionCustomProperties: {
46
+ readonly method: "POST";
47
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodArray<z.ZodString>], null>;
48
+ };
49
+ readonly AddNoteToSession: {
50
+ readonly method: "POST";
51
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
52
+ };
53
+ readonly SendMessageToSession: {
54
+ readonly method: "POST";
55
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString, z.ZodString], null>;
56
+ };
57
+ readonly SendCommandToSession: {
58
+ readonly method: "POST";
59
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
60
+ };
61
+ readonly SendToolboxItemToSession: {
62
+ readonly method: "POST";
63
+ readonly parameters: z.ZodTuple<[z.ZodUUID, z.ZodString], null>;
64
+ };
65
+ };
66
+ type ScreenConnectMethod = keyof typeof methods;
67
+ interface ScreenConnectApi {
68
+ call(method: ScreenConnectMethod, parameters: unknown[]): Promise<unknown>;
69
+ }
70
+ type RequestFactory = (url: URL, options: RequestOptions, onResponse: (response: IncomingMessage) => void) => ClientRequest;
71
+ interface ScreenConnectClientOptions {
72
+ siteUrl: string;
73
+ authenticationSecret: string;
74
+ /** Injection boundaries for contract tests; never sourced from tool input. */
75
+ resolveHost?: ResolveHost;
76
+ requestFactory?: RequestFactory;
77
+ requestTimeoutMs?: number;
78
+ }
79
+ declare class ScreenConnectClient implements ScreenConnectApi {
80
+ readonly siteUrl: string;
81
+ private readonly secret;
82
+ private readonly resolveHost?;
83
+ private readonly requestFactory;
84
+ private readonly timeoutMs;
85
+ constructor(options: ScreenConnectClientOptions);
86
+ call(method: ScreenConnectMethod, parameters: unknown[]): Promise<unknown>;
87
+ private send;
88
+ }
89
+ /** No second DNS resolution is allowed between validation and connection. */
90
+ declare function pinnedLookup(addresses: ResolvedAddress[]): LookupFunction;
91
+ //#endregion
92
+ export { ScreenConnectClientOptions as a, ScreenConnectClient as i, RequestFactory as n, ScreenConnectMethod as o, ScreenConnectApi as r, pinnedLookup as s, EXTENSION_PATH as t };
@@ -0,0 +1,2 @@
1
+ import { n as ScreenConnectClient, r as pinnedLookup, t as EXTENSION_PATH } from "./screenconnect-client2.js";
2
+ export { EXTENSION_PATH, ScreenConnectClient, pinnedLookup };