@smarttest/mcp 0.2.5

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,108 @@
1
+ <p align="center">
2
+ <img src="https://www.smarttest.cloud/smarttest.png" alt="SmarTTest" width="520">
3
+ </p>
4
+
5
+ <h1 align="center">SmarTT MCP</h1>
6
+
7
+ <p align="center">
8
+ Connect SmarTTest to your MCP client and work with your QA workspace directly from AI tools.
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://www.smarttest.cloud">www.smarttest.cloud</a>
13
+ </p>
14
+
15
+ ---
16
+
17
+ ## What It Is
18
+
19
+ SmarTT MCP is the official MCP server for SmarTTest.
20
+
21
+ It lets your MCP-compatible client connect to your SmarTTest workspace so you can browse projects, organize folders, manage tags, create and update test cases, and execute test runs from the same workflow where you are already working with AI.
22
+
23
+ This product is designed for teams that want faster access to their QA assets without leaving their MCP-enabled environment.
24
+
25
+ ## How To Configure It
26
+
27
+ To use SmarTT MCP, you need:
28
+
29
+ - A SmarTTest account
30
+ - A valid SmarTT MCP API key
31
+ - An MCP-compatible client
32
+
33
+ Add SmarTT MCP to your client configuration and provide your API key through the `SMARTT_MCP_API_KEY` environment variable.
34
+
35
+ ### Generic MCP Client Example
36
+
37
+ ```json
38
+ {
39
+ "servers": {
40
+ "smarttTest": {
41
+ "command": "npx",
42
+ "args": ["-y", "@smarttest/mcp"],
43
+ "env": {
44
+ "SMARTT_MCP_API_KEY": "sttmcp_<tokenId>.<secret>"
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ### VS Code Example
52
+
53
+ Example `.vscode/mcp.json`:
54
+
55
+ ```json
56
+ {
57
+ "servers": {
58
+ "smarttTest": {
59
+ "command": "npx",
60
+ "args": ["-y", "@smarttest/mcp"],
61
+ "env": {
62
+ "SMARTT_MCP_API_KEY": "sttmcp_<tokenId>.<secret>"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ ```
68
+
69
+ ## Exposed Tools
70
+
71
+ ### Projects
72
+
73
+ - `list_projects`: Lists the projects available to your organization.
74
+
75
+ ### Tags
76
+
77
+ - `list_tags`: Lists the tags available in a project.
78
+ - `create_tag`: Creates a new tag in a writable project.
79
+
80
+ ### Folders
81
+
82
+ - `list_project_folders`: Lists the active folders in a project, including folder paths.
83
+ - `create_folder`: Creates a new folder or subfolder inside a writable project.
84
+
85
+ ### Test Cases
86
+
87
+ - `list_tests`: Lists test cases in a project so you can find what you need quickly.
88
+ - `get_test`: Returns the full detail of a specific test case.
89
+ - `create_test`: Creates a new test case inside an existing folder.
90
+ - `update_test`: Updates an existing test case.
91
+ - `archive_test`: Archives a test case without losing its history.
92
+ - `restore_test`: Restores an archived test case.
93
+
94
+ ### Test Runs
95
+
96
+ - `list_runs`: Lists the runs available for a project with summary information.
97
+ - `get_run`: Returns the full detail of a specific run.
98
+ - `create_run`: Creates a new run for a project.
99
+ - `update_run_test_result`: Updates the result of a test inside a run.
100
+ - `complete_run`: Completes a run once execution is finished.
101
+
102
+ ## Typical Use Cases
103
+
104
+ - Explore QA assets from your MCP client without switching tools
105
+ - Create and maintain structured test cases with AI assistance
106
+ - Organize folders and tags across active projects
107
+ - Launch runs and update execution results from the same workflow
108
+ - Keep testing activity aligned with the rest of your AI-assisted delivery process
package/dist/auth.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { type BackendSession } from "./backend-client.js";
2
+ export type AuthContext = {
3
+ authorizationHeader: string;
4
+ apiBaseUrl: string;
5
+ session: BackendSession;
6
+ };
7
+ export declare function authenticateAuthorizationHeader(apiBaseUrl: string, authorizationHeader: string): Promise<AuthContext | null>;
package/dist/auth.js ADDED
@@ -0,0 +1,16 @@
1
+ import { verifySession } from "./backend-client.js";
2
+ export async function authenticateAuthorizationHeader(apiBaseUrl, authorizationHeader) {
3
+ if (!authorizationHeader.startsWith("Bearer ")) {
4
+ return null;
5
+ }
6
+ const session = await verifySession(apiBaseUrl, authorizationHeader);
7
+ if (!session) {
8
+ return null;
9
+ }
10
+ return {
11
+ authorizationHeader,
12
+ apiBaseUrl,
13
+ session,
14
+ };
15
+ }
16
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAuB,MAAM,qBAAqB,CAAA;AAQxE,MAAM,CAAC,KAAK,UAAU,+BAA+B,CACnD,UAAkB,EAClB,mBAA2B;IAE3B,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/C,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;IACpE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO;QACL,mBAAmB;QACnB,UAAU;QACV,OAAO;KACR,CAAA;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ export type BackendSession = {
2
+ apiKeyId: string;
3
+ organization: {
4
+ id: string;
5
+ name: string;
6
+ tier: string;
7
+ } | null;
8
+ user: {
9
+ id: string;
10
+ email: string;
11
+ firstName: string;
12
+ lastName: string;
13
+ } | null;
14
+ };
15
+ export declare function verifySession(apiBaseUrl: string, authorizationHeader: string): Promise<BackendSession | null>;
16
+ export declare function invokeBackendTool(apiBaseUrl: string, authorizationHeader: string, toolName: string, args: Record<string, unknown>): Promise<Record<string, unknown>>;
@@ -0,0 +1,42 @@
1
+ function buildUrl(baseUrl, path) {
2
+ return `${baseUrl}${path}`;
3
+ }
4
+ async function parseError(response) {
5
+ try {
6
+ const data = (await response.json());
7
+ return data?.error || `Request failed with status ${response.status}`;
8
+ }
9
+ catch {
10
+ return `Request failed with status ${response.status}`;
11
+ }
12
+ }
13
+ export async function verifySession(apiBaseUrl, authorizationHeader) {
14
+ const response = await fetch(buildUrl(apiBaseUrl, "/api/mcp/session"), {
15
+ headers: {
16
+ Authorization: authorizationHeader,
17
+ },
18
+ });
19
+ if (response.status === 401) {
20
+ return null;
21
+ }
22
+ if (!response.ok) {
23
+ throw new Error(await parseError(response));
24
+ }
25
+ return (await response.json());
26
+ }
27
+ export async function invokeBackendTool(apiBaseUrl, authorizationHeader, toolName, args) {
28
+ const response = await fetch(buildUrl(apiBaseUrl, `/api/mcp/tools/${encodeURIComponent(toolName)}`), {
29
+ method: "POST",
30
+ headers: {
31
+ Authorization: authorizationHeader,
32
+ "Content-Type": "application/json",
33
+ },
34
+ body: JSON.stringify({ arguments: args }),
35
+ });
36
+ if (!response.ok) {
37
+ throw new Error(await parseError(response));
38
+ }
39
+ const data = (await response.json());
40
+ return data.result;
41
+ }
42
+ //# sourceMappingURL=backend-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend-client.js","sourceRoot":"","sources":["../src/backend-client.ts"],"names":[],"mappings":"AAeA,SAAS,QAAQ,CAAC,OAAe,EAAE,IAAY;IAC7C,OAAO,GAAG,OAAO,GAAG,IAAI,EAAE,CAAA;AAC5B,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,QAAkB;IAC1C,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA8B,CAAA;QACjE,OAAO,IAAI,EAAE,KAAK,IAAI,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAA;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAA;IACxD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB,EAAE,mBAA2B;IACjF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAC,EAAE;QACrE,OAAO,EAAE;YACP,aAAa,EAAE,mBAAmB;SACnC;KACF,CAAC,CAAA;IAEF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAA;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,UAAkB,EAClB,mBAA2B,EAC3B,QAAgB,EAChB,IAA6B;IAE7B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,CAAC,UAAU,EAAE,kBAAkB,kBAAkB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;QACnG,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,mBAAmB;YAClC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KAC1C,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAA;IAC7C,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwC,CAAA;IAC3E,OAAO,IAAI,CAAC,MAAM,CAAA;AACpB,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import { getServerConfig, parseCliArgs } from "./env.js";
3
+ import { startStdioServer } from "./server.js";
4
+ async function main() {
5
+ const overrides = parseCliArgs(process.argv.slice(2));
6
+ const config = getServerConfig(overrides);
7
+ if (!config.authorizationHeader) {
8
+ throw new Error("SMARTT_MCP_API_KEY is required. Set SMARTT_MCP_API_KEY or pass --api-key.");
9
+ }
10
+ await startStdioServer({
11
+ apiBaseUrl: config.apiBaseUrl,
12
+ authorizationHeader: config.authorizationHeader,
13
+ });
14
+ }
15
+ main().catch((error) => {
16
+ console.error(error instanceof Error ? error.message : "Failed to start SmarTT-MCP.");
17
+ process.exitCode = 1;
18
+ });
19
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAE9C,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAEzC,IAAI,CAAC,MAAM,CAAC,mBAAmB,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,2EAA2E,CAAC,CAAA;IAC9F,CAAC;IAED,MAAM,gBAAgB,CAAC;QACrB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,mBAAmB,EAAE,MAAM,CAAC,mBAAmB;KAChD,CAAC,CAAA;AACJ,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAA;IACrF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;AACtB,CAAC,CAAC,CAAA"}
package/dist/env.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export type CliOverrides = {
2
+ apiBaseUrl?: string;
3
+ apiKey?: string;
4
+ };
5
+ export type ServerConfig = {
6
+ apiBaseUrl: string;
7
+ authorizationHeader?: string;
8
+ };
9
+ export declare function loadPackageEnv(): void;
10
+ export declare function parseCliArgs(argv: string[]): CliOverrides;
11
+ export declare function getServerConfig(overrides?: CliOverrides): ServerConfig;
package/dist/env.js ADDED
@@ -0,0 +1,98 @@
1
+ import { existsSync, readFileSync } from "fs";
2
+ import path from "path";
3
+ import { fileURLToPath } from "url";
4
+ function applyEnvFile(filePath) {
5
+ if (!existsSync(filePath)) {
6
+ return;
7
+ }
8
+ const raw = readFileSync(filePath, "utf8");
9
+ for (const line of raw.split(/\r?\n/)) {
10
+ const trimmed = line.trim();
11
+ if (!trimmed || trimmed.startsWith("#")) {
12
+ continue;
13
+ }
14
+ const separatorIndex = trimmed.indexOf("=");
15
+ if (separatorIndex <= 0) {
16
+ continue;
17
+ }
18
+ const key = trimmed.slice(0, separatorIndex).trim();
19
+ if (!key || process.env[key] !== undefined) {
20
+ continue;
21
+ }
22
+ let value = trimmed.slice(separatorIndex + 1).trim();
23
+ if ((value.startsWith('"') && value.endsWith('"')) ||
24
+ (value.startsWith("'") && value.endsWith("'"))) {
25
+ value = value.slice(1, -1);
26
+ }
27
+ process.env[key] = value;
28
+ }
29
+ }
30
+ export function loadPackageEnv() {
31
+ const currentFile = fileURLToPath(import.meta.url);
32
+ const currentDir = path.dirname(currentFile);
33
+ const packageRoot = path.resolve(currentDir, "..");
34
+ applyEnvFile(path.join(packageRoot, ".env"));
35
+ }
36
+ function normalizeBaseUrl(value) {
37
+ const normalized = value.trim().replace(/\/+$/, "");
38
+ const url = new URL(normalized);
39
+ if (url.protocol !== "http:" && url.protocol !== "https:") {
40
+ throw new Error("SMARTT_API_BASE_URL must use http or https.");
41
+ }
42
+ if (url.username || url.password) {
43
+ throw new Error("SMARTT_API_BASE_URL must not include credentials.");
44
+ }
45
+ return url.toString().replace(/\/+$/, "");
46
+ }
47
+ function normalizeAuthorizationHeader(value) {
48
+ const normalized = value.trim();
49
+ if (!normalized) {
50
+ throw new Error("SMARTT_MCP_API_KEY must not be empty.");
51
+ }
52
+ return normalized.startsWith("Bearer ") ? normalized : `Bearer ${normalized}`;
53
+ }
54
+ export function parseCliArgs(argv) {
55
+ const overrides = {};
56
+ for (let index = 0; index < argv.length; index += 1) {
57
+ const arg = argv[index];
58
+ if (arg === "--api-base-url") {
59
+ const raw = argv[index + 1];
60
+ if (raw?.trim()) {
61
+ overrides.apiBaseUrl = normalizeBaseUrl(raw);
62
+ }
63
+ index += 1;
64
+ continue;
65
+ }
66
+ if (arg === "--api-key") {
67
+ const raw = argv[index + 1];
68
+ if (raw?.trim()) {
69
+ overrides.apiKey = raw.trim();
70
+ }
71
+ index += 1;
72
+ continue;
73
+ }
74
+ if (arg === "--transport") {
75
+ throw new Error("The --transport flag is no longer supported. SmarTT-MCP only runs over stdio.");
76
+ }
77
+ if (arg === "--port") {
78
+ throw new Error("The --port flag is no longer supported. SmarTT-MCP only runs over stdio.");
79
+ }
80
+ }
81
+ return overrides;
82
+ }
83
+ export function getServerConfig(overrides = {}) {
84
+ loadPackageEnv();
85
+ if (process.env.SMARTT_MCP_TRANSPORT) {
86
+ throw new Error("SMARTT_MCP_TRANSPORT is no longer supported. Remove it and run SmarTT-MCP through stdio.");
87
+ }
88
+ if (process.env.SMARTT_MCP_PORT) {
89
+ throw new Error("SMARTT_MCP_PORT is no longer supported. Remove it from your configuration.");
90
+ }
91
+ const apiBaseUrl = normalizeBaseUrl(overrides.apiBaseUrl ?? process.env.SMARTT_API_BASE_URL ?? "https://www.smarttest.cloud");
92
+ const rawApiKey = overrides.apiKey ?? process.env.SMARTT_MCP_API_KEY ?? process.env.SMARTT_API_KEY;
93
+ return {
94
+ apiBaseUrl,
95
+ authorizationHeader: rawApiKey ? normalizeAuthorizationHeader(rawApiKey) : undefined,
96
+ };
97
+ }
98
+ //# sourceMappingURL=env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function startStdioServer({ apiBaseUrl, authorizationHeader, }: {
3
+ apiBaseUrl: string;
4
+ authorizationHeader: string;
5
+ }): Promise<McpServer>;
package/dist/server.js ADDED
@@ -0,0 +1,62 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { authenticateAuthorizationHeader } from "./auth.js";
4
+ import { invokeBackendTool } from "./backend-client.js";
5
+ import { toolDefinitions } from "./tool-definitions.js";
6
+ const SERVER_VERSION = "0.2.4";
7
+ function toolResult(data) {
8
+ return {
9
+ content: [
10
+ {
11
+ type: "text",
12
+ text: JSON.stringify(data, null, 2),
13
+ },
14
+ ],
15
+ structuredContent: data,
16
+ };
17
+ }
18
+ function createSmarttServer(context) {
19
+ const server = new McpServer({
20
+ name: "smartt-mcp",
21
+ version: SERVER_VERSION,
22
+ });
23
+ for (const [name, definition] of Object.entries(toolDefinitions)) {
24
+ server.registerTool(name, {
25
+ description: definition.description,
26
+ inputSchema: definition.inputSchema,
27
+ }, async (input) => {
28
+ const result = await invokeBackendTool(context.apiBaseUrl, context.authorizationHeader, name, input);
29
+ return toolResult(result);
30
+ });
31
+ }
32
+ return server;
33
+ }
34
+ function installSignalHandlers(shutdown) {
35
+ let shuttingDown = false;
36
+ const handleShutdown = () => {
37
+ if (shuttingDown) {
38
+ return;
39
+ }
40
+ shuttingDown = true;
41
+ shutdown();
42
+ };
43
+ process.on("SIGINT", handleShutdown);
44
+ process.on("SIGTERM", handleShutdown);
45
+ }
46
+ export async function startStdioServer({ apiBaseUrl, authorizationHeader, }) {
47
+ const authContext = await authenticateAuthorizationHeader(apiBaseUrl, authorizationHeader);
48
+ if (!authContext) {
49
+ throw new Error(`SMARTT_MCP_API_KEY was rejected by ${apiBaseUrl}.`);
50
+ }
51
+ const server = createSmarttServer(authContext);
52
+ const transport = new StdioServerTransport();
53
+ await server.connect(transport);
54
+ console.error("SmarTT-MCP stdio transport connected.");
55
+ console.error(`Forwarding tool calls to ${apiBaseUrl}`);
56
+ installSignalHandlers(() => {
57
+ void transport.close();
58
+ void server.close().finally(() => process.exit(0));
59
+ });
60
+ return server;
61
+ }
62
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,+BAA+B,EAAoB,MAAM,WAAW,CAAA;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAEvD,MAAM,cAAc,GAAG,OAAO,CAAA;AAE9B,SAAS,UAAU,CAAoC,IAAO;IAC5D,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACpC;SACF;QACD,iBAAiB,EAAE,IAAI;KACxB,CAAA;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAoB;IAC9C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,cAAc;KACxB,CAAC,CAAA;IAEF,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QACjE,MAAM,CAAC,YAAY,CACjB,IAAI,EACJ;YACE,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,WAAW,EAAE,UAAU,CAAC,WAAW;SACpC,EACD,KAAK,EAAE,KAAK,EAAE,EAAE;YACd,MAAM,MAAM,GAAG,MAAM,iBAAiB,CACpC,OAAO,CAAC,UAAU,EAClB,OAAO,CAAC,mBAAmB,EAC3B,IAAI,EACJ,KAAK,CACN,CAAA;YACD,OAAO,UAAU,CAAC,MAAM,CAAC,CAAA;QAC3B,CAAC,CACF,CAAA;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAoB;IACjD,IAAI,YAAY,GAAG,KAAK,CAAA;IAExB,MAAM,cAAc,GAAG,GAAG,EAAE;QAC1B,IAAI,YAAY,EAAE,CAAC;YACjB,OAAM;QACR,CAAC;QAED,YAAY,GAAG,IAAI,CAAA;QACnB,QAAQ,EAAE,CAAA;IACZ,CAAC,CAAA;IAED,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;IACpC,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,UAAU,EACV,mBAAmB,GAIpB;IACC,MAAM,WAAW,GAAG,MAAM,+BAA+B,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAA;IAC1F,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,sCAAsC,UAAU,GAAG,CAAC,CAAA;IACtE,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,WAAW,CAAC,CAAA;IAC9C,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAE/B,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAA;IACtD,OAAO,CAAC,KAAK,CAAC,4BAA4B,UAAU,EAAE,CAAC,CAAA;IAEvD,qBAAqB,CAAC,GAAG,EAAE;QACzB,KAAK,SAAS,CAAC,KAAK,EAAE,CAAA;QACtB,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ import * as z from "zod/v4";
2
+ export type ToolDefinition = {
3
+ description: string;
4
+ inputSchema: Record<string, z.ZodType>;
5
+ };
6
+ export declare const toolDefinitions: Record<string, ToolDefinition>;
@@ -0,0 +1,154 @@
1
+ import * as z from "zod/v4";
2
+ const stepSchema = z.object({
3
+ action: z.string().min(1),
4
+ expectedResult: z.string().optional(),
5
+ attachments: z.array(z.string()).optional(),
6
+ });
7
+ const runResultStatusValues = ["PENDING", "IN_PROGRESS", "PASSED", "FAILED", "SKIPPED"];
8
+ const runResultStatusSchema = z
9
+ .string()
10
+ .trim()
11
+ .transform((value) => value.toUpperCase())
12
+ .pipe(z.enum(runResultStatusValues));
13
+ export const toolDefinitions = {
14
+ list_projects: {
15
+ description: "List projects available for the authenticated organization.",
16
+ inputSchema: {
17
+ includeInactive: z.boolean().default(false),
18
+ },
19
+ },
20
+ list_tags: {
21
+ description: "List tags available for a project.",
22
+ inputSchema: {
23
+ projectId: z.string(),
24
+ },
25
+ },
26
+ create_tag: {
27
+ description: "Create a tag inside a writable project.",
28
+ inputSchema: {
29
+ projectId: z.string(),
30
+ name: z.string().min(1),
31
+ description: z.string().optional(),
32
+ },
33
+ },
34
+ list_project_folders: {
35
+ description: "List all active folders for a project, including their full path.",
36
+ inputSchema: {
37
+ projectId: z.string(),
38
+ },
39
+ },
40
+ create_folder: {
41
+ description: "Create a new root folder or subfolder inside a writable project.",
42
+ inputSchema: {
43
+ projectId: z.string(),
44
+ name: z.string().min(1),
45
+ parentId: z.string().optional(),
46
+ },
47
+ },
48
+ list_tests: {
49
+ description: "List tests for a project. Returns only lightweight metadata so the client can choose one to inspect.",
50
+ inputSchema: {
51
+ projectId: z.string(),
52
+ folderId: z.string().optional(),
53
+ recursive: z.boolean().default(true),
54
+ includeArchived: z.boolean().default(false),
55
+ },
56
+ },
57
+ get_test: {
58
+ description: "Read the full data for a specific test.",
59
+ inputSchema: {
60
+ testCaseId: z.string(),
61
+ includeArchived: z.boolean().default(true),
62
+ },
63
+ },
64
+ create_test: {
65
+ description: "Create a new test inside a writable project and an existing folder.",
66
+ inputSchema: {
67
+ projectId: z.string(),
68
+ folderId: z.string().min(1),
69
+ title: z.string().min(1),
70
+ priority: z.string().nullable().optional(),
71
+ description: z.string().optional(),
72
+ preconditions: z.string().optional(),
73
+ steps: z.array(stepSchema).min(1),
74
+ expectedResult: z.string().optional(),
75
+ expectedResultAttachments: z.array(z.string()).optional(),
76
+ references: z.string().optional(),
77
+ automated: z.string().default("No"),
78
+ automatedReason: z.string().optional(),
79
+ tagNames: z.array(z.string()).optional(),
80
+ },
81
+ },
82
+ update_test: {
83
+ description: "Update an existing test in-place.",
84
+ inputSchema: {
85
+ testCaseId: z.string(),
86
+ folderId: z.string().min(1).optional(),
87
+ title: z.string().min(1).optional(),
88
+ priority: z.string().nullable().optional(),
89
+ description: z.string().nullable().optional(),
90
+ preconditions: z.string().nullable().optional(),
91
+ steps: z.array(stepSchema).min(1).optional(),
92
+ expectedResult: z.string().nullable().optional(),
93
+ expectedResultAttachments: z.array(z.string()).nullable().optional(),
94
+ references: z.string().nullable().optional(),
95
+ automated: z.string().optional(),
96
+ automatedReason: z.string().nullable().optional(),
97
+ addTagNames: z.array(z.string()).optional(),
98
+ removeTagNames: z.array(z.string()).optional(),
99
+ },
100
+ },
101
+ archive_test: {
102
+ description: "Archive a test with a soft delete, preserving it in history.",
103
+ inputSchema: {
104
+ testCaseId: z.string(),
105
+ },
106
+ },
107
+ restore_test: {
108
+ description: "Restore an archived test and record the restoration in history.",
109
+ inputSchema: {
110
+ testCaseId: z.string(),
111
+ },
112
+ },
113
+ list_runs: {
114
+ description: "List runs for a project, including summary counts and general status.",
115
+ inputSchema: {
116
+ projectId: z.string(),
117
+ limit: z.number().int().min(1).max(200).default(50),
118
+ },
119
+ },
120
+ get_run: {
121
+ description: "Read one run with all of its test results.",
122
+ inputSchema: {
123
+ runId: z.string(),
124
+ },
125
+ },
126
+ create_run: {
127
+ description: "Create a run for a project, optionally scoping it to specific folders, tags, or tests. The stored run name always includes a timestamp suffix.",
128
+ inputSchema: {
129
+ projectId: z.string(),
130
+ name: z.string().min(1),
131
+ comment: z.string().optional(),
132
+ folderIds: z.array(z.string()).optional(),
133
+ tagNames: z.array(z.string()).optional(),
134
+ testCaseIds: z.array(z.string()).optional(),
135
+ },
136
+ },
137
+ update_run_test_result: {
138
+ description: "Update the result of a single test inside a run. A comment is required. Runs stay open until complete_run is called manually.",
139
+ inputSchema: {
140
+ runId: z.string(),
141
+ testCaseId: z.string(),
142
+ status: runResultStatusSchema,
143
+ comment: z.string().min(1),
144
+ },
145
+ },
146
+ complete_run: {
147
+ description: "Manually complete a run after all tests have been updated. Requires a final comment and auto-generates a SmarTT Summary.",
148
+ inputSchema: {
149
+ runId: z.string(),
150
+ comment: z.string().min(1),
151
+ },
152
+ },
153
+ };
154
+ //# sourceMappingURL=tool-definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAA;AAE3B,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC5C,CAAC,CAAA;AAEF,MAAM,qBAAqB,GAAG,CAAC,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAA;AAChG,MAAM,qBAAqB,GAAG,CAAC;KAC5B,MAAM,EAAE;KACR,IAAI,EAAE;KACN,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;KACzC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAA;AAOtC,MAAM,CAAC,MAAM,eAAe,GAAmC;IAC7D,aAAa,EAAE;QACb,WAAW,EAAE,6DAA6D;QAC1E,WAAW,EAAE;YACX,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;SAC5C;KACF;IACD,SAAS,EAAE;QACT,WAAW,EAAE,oCAAoC;QACjD,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;SACtB;KACF;IACD,UAAU,EAAE;QACV,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACvB,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SACnC;KACF;IACD,oBAAoB,EAAE;QACpB,WAAW,EAAE,mEAAmE;QAChF,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;SACtB;KACF;IACD,aAAa,EAAE;QACb,WAAW,EAAE,kEAAkE;QAC/E,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;SAChC;KACF;IACD,UAAU,EAAE;QACV,WAAW,EAAE,sGAAsG;QACnH,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC/B,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACpC,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;SAC5C;KACF;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,yCAAyC;QACtD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,eAAe,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;SAC3C;KACF;IACD,WAAW,EAAE;QACX,WAAW,EAAE,qEAAqE;QAClF,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACxB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAClC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACpC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACrC,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACzD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACjC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;YACnC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YACtC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SACzC;KACF;IACD,WAAW,EAAE;QACX,WAAW,EAAE,mCAAmC;QAChD,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YACnC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC1C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC7C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC/C,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;YAC5C,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAChD,yBAAyB,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YACpE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAChC,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;YACjD,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YAC3C,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SAC/C;KACF;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,8DAA8D;QAC3E,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;SACvB;KACF;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,iEAAiE;QAC9E,WAAW,EAAE;YACX,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;SACvB;KACF;IACD,SAAS,EAAE;QACT,WAAW,EAAE,uEAAuE;QACpF,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;SACpD;KACF;IACD,OAAO,EAAE;QACP,WAAW,EAAE,4CAA4C;QACzD,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;SAClB;KACF;IACD,UAAU,EAAE;QACV,WAAW,EAAE,gJAAgJ;QAC7J,WAAW,EAAE;YACX,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;YACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACvB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC9B,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACzC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;YACxC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;SAC5C;KACF;IACD,sBAAsB,EAAE;QACtB,WAAW,EAAE,+HAA+H;QAC5I,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,qBAAqB;YAC7B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;SAC3B;KACF;IACD,YAAY,EAAE;QACZ,WAAW,EAAE,0HAA0H;QACvI,WAAW,EAAE;YACX,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;YACjB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;SAC3B;KACF;CACF,CAAA"}
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@smarttest/mcp",
3
+ "version": "0.2.5",
4
+ "description": "Standalone MCP server for SmarTTest that forwards tool calls to the SmarTTest backend.",
5
+ "license": "UNLICENSED",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "homepage": "https://www.smarttest.cloud",
10
+ "bugs": {
11
+ "url": "https://www.smarttest.cloud"
12
+ },
13
+ "type": "module",
14
+ "bin": {
15
+ "smartt-mcp": "dist/cli.js"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "smarttest.png"
21
+ ],
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "scripts": {
26
+ "dev": "tsx src/cli.ts",
27
+ "build": "tsc -p tsconfig.json",
28
+ "check": "tsc -p tsconfig.json --noEmit",
29
+ "prepublishOnly": "npm run check && npm run build"
30
+ },
31
+ "keywords": [
32
+ "mcp",
33
+ "model-context-protocol",
34
+ "smarttest",
35
+ "qa",
36
+ "testing"
37
+ ],
38
+ "dependencies": {
39
+ "@modelcontextprotocol/sdk": "^1.26.0",
40
+ "zod": "^4.3.6"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.19.22",
44
+ "tsx": "^4.21.0",
45
+ "typescript": "^5.9.3"
46
+ }
47
+ }
package/smarttest.png ADDED
Binary file