mcp-sunsama 0.2.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/.changeset/README.md +8 -0
- package/.changeset/config.json +11 -0
- package/.claude/settings.local.json +29 -0
- package/.env.example +10 -0
- package/CHANGELOG.md +29 -0
- package/CLAUDE.md +137 -0
- package/LICENSE +21 -0
- package/README.md +143 -0
- package/TODO_PREPUBLISH.md +182 -0
- package/bun.lock +515 -0
- package/dist/auth/http.d.ts +20 -0
- package/dist/auth/http.d.ts.map +1 -0
- package/dist/auth/http.js +52 -0
- package/dist/auth/stdio.d.ts +13 -0
- package/dist/auth/stdio.d.ts.map +1 -0
- package/dist/auth/stdio.js +27 -0
- package/dist/auth/types.d.ts +9 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +1 -0
- package/dist/config/transport.d.ts +32 -0
- package/dist/config/transport.d.ts.map +1 -0
- package/dist/config/transport.js +62 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +473 -0
- package/dist/schemas.d.ts +522 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +124 -0
- package/dist/utils/client-resolver.d.ts +10 -0
- package/dist/utils/client-resolver.d.ts.map +1 -0
- package/dist/utils/client-resolver.js +19 -0
- package/dist/utils/task-filters.d.ts +29 -0
- package/dist/utils/task-filters.d.ts.map +1 -0
- package/dist/utils/task-filters.js +42 -0
- package/dist/utils/task-trimmer.d.ts +47 -0
- package/dist/utils/task-trimmer.d.ts.map +1 -0
- package/dist/utils/task-trimmer.js +50 -0
- package/dist/utils/to-tsv.d.ts +8 -0
- package/dist/utils/to-tsv.d.ts.map +1 -0
- package/dist/utils/to-tsv.js +64 -0
- package/mcp-inspector.json +14 -0
- package/package.json +56 -0
- package/src/auth/http.ts +61 -0
- package/src/auth/stdio.ts +33 -0
- package/src/auth/types.ts +9 -0
- package/src/config/transport.ts +80 -0
- package/src/main.ts +542 -0
- package/src/schemas.ts +169 -0
- package/src/utils/client-resolver.ts +23 -0
- package/src/utils/task-filters.ts +49 -0
- package/src/utils/task-trimmer.ts +81 -0
- package/src/utils/to-tsv.ts +73 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { IncomingMessage } from "http";
|
|
2
|
+
import { SunsamaClient } from "sunsama-api";
|
|
3
|
+
/**
|
|
4
|
+
* Parse HTTP Basic Auth credentials from Authorization header
|
|
5
|
+
* @param authHeader - The Authorization header value
|
|
6
|
+
* @returns Object containing email and password
|
|
7
|
+
* @throws {Error} If the header format is invalid
|
|
8
|
+
*/
|
|
9
|
+
export function parseBasicAuth(authHeader) {
|
|
10
|
+
const base64Credentials = authHeader.replace('Basic ', '');
|
|
11
|
+
const credentials = Buffer.from(base64Credentials, 'base64').toString('ascii');
|
|
12
|
+
const [email, password] = credentials.split(':');
|
|
13
|
+
if (!email || !password) {
|
|
14
|
+
throw new Error("Invalid Basic Auth format");
|
|
15
|
+
}
|
|
16
|
+
return { email, password };
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* HTTP Basic Auth authenticator for httpStream transport
|
|
20
|
+
* @param request - The incoming request object
|
|
21
|
+
* @returns SessionData with authenticated SunsamaClient
|
|
22
|
+
* @throws {Response} HTTP 401 response for authentication failures
|
|
23
|
+
*/
|
|
24
|
+
export async function httpStreamAuthenticator(request) {
|
|
25
|
+
const authHeader = request.headers["authorization"];
|
|
26
|
+
if (!authHeader || Array.isArray(authHeader) || !authHeader.startsWith('Basic ')) {
|
|
27
|
+
throw new Response(null, {
|
|
28
|
+
status: 401,
|
|
29
|
+
statusText: "Unauthorized: Basic Auth required",
|
|
30
|
+
headers: { 'WWW-Authenticate': 'Basic realm="Sunsama MCP"' }
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
// Parse Basic Auth credentials
|
|
35
|
+
const { email, password } = parseBasicAuth(authHeader);
|
|
36
|
+
// Create and authenticate SunsamaClient
|
|
37
|
+
const sunsamaClient = new SunsamaClient();
|
|
38
|
+
await sunsamaClient.login(email, password);
|
|
39
|
+
console.log(`HTTP session authenticated for user: ${email}`);
|
|
40
|
+
return {
|
|
41
|
+
sunsamaClient,
|
|
42
|
+
email
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
console.log("Authentication failed:", error instanceof Error ? error.message : 'Unknown error');
|
|
47
|
+
throw new Response(null, {
|
|
48
|
+
status: 401,
|
|
49
|
+
statusText: "Unauthorized: Invalid Sunsama credentials"
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SunsamaClient } from "sunsama-api";
|
|
2
|
+
/**
|
|
3
|
+
* Initialize stdio authentication using environment variables
|
|
4
|
+
* @throws {Error} If credentials are missing or authentication fails
|
|
5
|
+
*/
|
|
6
|
+
export declare function initializeStdioAuth(): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Get the global Sunsama client instance for stdio transport
|
|
9
|
+
* @returns {SunsamaClient} The authenticated global client
|
|
10
|
+
* @throws {Error} If global client is not initialized
|
|
11
|
+
*/
|
|
12
|
+
export declare function getGlobalSunsamaClient(): SunsamaClient;
|
|
13
|
+
//# sourceMappingURL=stdio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../../src/auth/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAO5C;;;GAGG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CASzD;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,aAAa,CAKtD"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SunsamaClient } from "sunsama-api";
|
|
2
|
+
/**
|
|
3
|
+
* Global Sunsama client instance for stdio transport
|
|
4
|
+
*/
|
|
5
|
+
let globalSunsamaClient = null;
|
|
6
|
+
/**
|
|
7
|
+
* Initialize stdio authentication using environment variables
|
|
8
|
+
* @throws {Error} If credentials are missing or authentication fails
|
|
9
|
+
*/
|
|
10
|
+
export async function initializeStdioAuth() {
|
|
11
|
+
if (!process.env.SUNSAMA_EMAIL || !process.env.SUNSAMA_PASSWORD) {
|
|
12
|
+
throw new Error("Sunsama credentials not configured. Please set SUNSAMA_EMAIL and SUNSAMA_PASSWORD environment variables.");
|
|
13
|
+
}
|
|
14
|
+
globalSunsamaClient = new SunsamaClient();
|
|
15
|
+
await globalSunsamaClient.login(process.env.SUNSAMA_EMAIL, process.env.SUNSAMA_PASSWORD);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get the global Sunsama client instance for stdio transport
|
|
19
|
+
* @returns {SunsamaClient} The authenticated global client
|
|
20
|
+
* @throws {Error} If global client is not initialized
|
|
21
|
+
*/
|
|
22
|
+
export function getGlobalSunsamaClient() {
|
|
23
|
+
if (!globalSunsamaClient) {
|
|
24
|
+
throw new Error("Global Sunsama client not initialized.");
|
|
25
|
+
}
|
|
26
|
+
return globalSunsamaClient;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,WAAY,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC1D,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import { SunsamaClient } from "sunsama-api";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport configuration for the Sunsama MCP Server
|
|
3
|
+
* Supports both stdio and httpStream transports based on environment variables
|
|
4
|
+
*/
|
|
5
|
+
export type TransportType = "stdio" | "httpStream";
|
|
6
|
+
export interface TransportConfig {
|
|
7
|
+
transportType: TransportType;
|
|
8
|
+
httpStream?: {
|
|
9
|
+
port: number;
|
|
10
|
+
endpoint: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Gets the transport configuration based on environment variables
|
|
15
|
+
*
|
|
16
|
+
* Environment Variables:
|
|
17
|
+
* - TRANSPORT_TYPE: "stdio" | "httpStream" (default: "stdio")
|
|
18
|
+
* - PORT: HTTP server port (default: 3000, only for httpStream)
|
|
19
|
+
* - HTTP_ENDPOINT: HTTP endpoint path (default: "/mcp", only for httpStream)
|
|
20
|
+
*
|
|
21
|
+
* @throws {z.ZodError} When environment variables are invalid
|
|
22
|
+
*/
|
|
23
|
+
export declare function getTransportConfig(): TransportConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Returns true if the current transport configuration is for HTTP streaming
|
|
26
|
+
*/
|
|
27
|
+
export declare function isHttpStreamTransport(): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Returns true if the current transport configuration is for stdio
|
|
30
|
+
*/
|
|
31
|
+
export declare function isStdioTransport(): boolean;
|
|
32
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/config/transport.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,YAAY,CAAC;AAEnD,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,aAAa,CAAC;IAC7B,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAcD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CA0BpD;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transport configuration for the Sunsama MCP Server
|
|
3
|
+
* Supports both stdio and httpStream transports based on environment variables
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
/**
|
|
7
|
+
* Zod schema for validating transport-related environment variables
|
|
8
|
+
*/
|
|
9
|
+
const TransportEnvSchema = z.object({
|
|
10
|
+
TRANSPORT_TYPE: z.enum(["stdio", "httpStream"]).default("stdio"),
|
|
11
|
+
PORT: z.string()
|
|
12
|
+
.transform(val => parseInt(val, 10))
|
|
13
|
+
.pipe(z.number().min(1).max(65535))
|
|
14
|
+
.optional(),
|
|
15
|
+
HTTP_ENDPOINT: z.string().default("/mcp")
|
|
16
|
+
});
|
|
17
|
+
/**
|
|
18
|
+
* Gets the transport configuration based on environment variables
|
|
19
|
+
*
|
|
20
|
+
* Environment Variables:
|
|
21
|
+
* - TRANSPORT_TYPE: "stdio" | "httpStream" (default: "stdio")
|
|
22
|
+
* - PORT: HTTP server port (default: 3000, only for httpStream)
|
|
23
|
+
* - HTTP_ENDPOINT: HTTP endpoint path (default: "/mcp", only for httpStream)
|
|
24
|
+
*
|
|
25
|
+
* @throws {z.ZodError} When environment variables are invalid
|
|
26
|
+
*/
|
|
27
|
+
export function getTransportConfig() {
|
|
28
|
+
try {
|
|
29
|
+
const env = TransportEnvSchema.parse(process.env);
|
|
30
|
+
if (env.TRANSPORT_TYPE === "httpStream") {
|
|
31
|
+
return {
|
|
32
|
+
transportType: "httpStream",
|
|
33
|
+
httpStream: {
|
|
34
|
+
port: env.PORT || 3000,
|
|
35
|
+
endpoint: env.HTTP_ENDPOINT
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
transportType: "stdio"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
if (error instanceof z.ZodError) {
|
|
45
|
+
const issues = error.issues.map(issue => `${issue.path.join('.')}: ${issue.message}`).join(', ');
|
|
46
|
+
throw new Error(`Invalid transport configuration: ${issues}`);
|
|
47
|
+
}
|
|
48
|
+
throw error;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns true if the current transport configuration is for HTTP streaming
|
|
53
|
+
*/
|
|
54
|
+
export function isHttpStreamTransport() {
|
|
55
|
+
return getTransportConfig().transportType === "httpStream";
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Returns true if the current transport configuration is for stdio
|
|
59
|
+
*/
|
|
60
|
+
export function isStdioTransport() {
|
|
61
|
+
return getTransportConfig().transportType === "stdio";
|
|
62
|
+
}
|
package/dist/main.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":""}
|