@timetick/mcp 0.2.0 → 0.3.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/LICENSE +662 -0
- package/README.md +65 -70
- package/dist/index.js +3355 -236
- package/package.json +10 -5
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timetick/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Timetick (https://app.timetick.io) platform",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"author": "Timetick <support@timetick.io>",
|
|
@@ -14,12 +14,14 @@
|
|
|
14
14
|
"ocpp",
|
|
15
15
|
"ev-charging",
|
|
16
16
|
"claude",
|
|
17
|
+
"codex",
|
|
18
|
+
"gemini",
|
|
17
19
|
"ai-agent",
|
|
18
20
|
"load-testing"
|
|
19
21
|
],
|
|
20
22
|
"type": "module",
|
|
21
23
|
"bin": {
|
|
22
|
-
"timetick-mcp": "
|
|
24
|
+
"timetick-mcp": "dist/index.js"
|
|
23
25
|
},
|
|
24
26
|
"main": "./dist/index.js",
|
|
25
27
|
"files": [
|
|
@@ -27,7 +29,7 @@
|
|
|
27
29
|
"README.md"
|
|
28
30
|
],
|
|
29
31
|
"engines": {
|
|
30
|
-
"node": ">=18"
|
|
32
|
+
"node": ">=18.14"
|
|
31
33
|
},
|
|
32
34
|
"publishConfig": {
|
|
33
35
|
"access": "public",
|
|
@@ -35,15 +37,18 @@
|
|
|
35
37
|
},
|
|
36
38
|
"scripts": {
|
|
37
39
|
"build": "tsup",
|
|
40
|
+
"prepublishOnly": "yarn build",
|
|
38
41
|
"dev": "tsup --watch",
|
|
39
42
|
"typecheck": "tsc --noEmit",
|
|
40
43
|
"start": "node dist/index.js",
|
|
41
44
|
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
42
|
-
"test": "vitest run"
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:contract": "vitest run src/__tests__/contract",
|
|
47
|
+
"plugin:sync": "node scripts/sync-plugin.mjs"
|
|
43
48
|
},
|
|
44
49
|
"dependencies": {
|
|
45
50
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
46
|
-
"@timetick/sdk": "^
|
|
51
|
+
"@timetick/sdk": "^3.0.0",
|
|
47
52
|
"graphql": "^16.0.0",
|
|
48
53
|
"zod": "^4.4.3"
|
|
49
54
|
},
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/tools/context.ts","../src/sdk.ts","../src/context.ts","../src/result.ts","../src/tools/data.ts","../src/resolve.ts","../src/pagination.ts","../src/tools/simulators.ts","../src/tools/tests.ts","../src/tools/test-runs.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\n\nimport { registerContextTools } from \"./tools/context.js\";\nimport { registerDataTools } from \"./tools/data.js\";\nimport { registerSimulatorTools } from \"./tools/simulators.js\";\nimport { registerTestTools } from \"./tools/tests.js\";\nimport { registerTestRunTools } from \"./tools/test-runs.js\";\n\nasync function main() {\n if (!process.env.TIMETICK_API_TOKEN) {\n console.error(\n \"TIMETICK_API_TOKEN is not set. Generate an API key in the Timetick portal \" +\n \"(Account → API keys) and expose it to the MCP server as TIMETICK_API_TOKEN.\",\n );\n process.exit(1);\n }\n\n const server = new McpServer({ name: \"timetick\", version: \"0.1.0\" });\n\n registerContextTools(server);\n registerDataTools(server);\n registerSimulatorTools(server);\n registerTestTools(server);\n registerTestRunTools(server);\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Timetick MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Fatal error starting Timetick MCP server:\", error);\n process.exit(1);\n});\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { getContext, useProject, peekContext } from \"../context.js\";\nimport { ok, guard } from \"../result.js\";\n\nexport function registerContextTools(server: McpServer) {\n server.registerTool(\n \"get_context\",\n {\n title: \"Get active context\",\n description:\n \"Show the project and sim world the MCP server is currently operating on. \" +\n \"If no project is selected yet and you have only one project, it is auto-selected.\",\n inputSchema: {},\n },\n async () =>\n guard(async () => {\n const ctx = peekContext() ?? (await getContext());\n return ok(\n `Active project: ${ctx.projectName} (id: ${ctx.projectId}); sim world: ${ctx.simWorldId} [${ctx.source}]`,\n ctx,\n );\n }),\n );\n\n server.registerTool(\n \"use_project\",\n {\n title: \"Select project\",\n description:\n \"Switch the active project by name or id. Only needed if you have more than one project. \" +\n \"Caches the project's sim world for subsequent tools.\",\n inputSchema: {\n project: z.string().describe(\"Project name or id to make active\"),\n },\n },\n async ({ project }) =>\n guard(async () => {\n const ctx = await useProject({ project });\n return ok(`Active project is now ${ctx.projectName} (id: ${ctx.projectId}).`, ctx);\n }),\n );\n}\n","import { createClient, type TimetickClient } from \"@timetick/sdk\";\n\nlet client: TimetickClient | null = null;\n\n/** Lazily-created singleton Timetick SDK client, authenticated from the environment. */\nexport function sdk(): TimetickClient {\n if (client) return client;\n\n const apiKey = process.env.TIMETICK_API_TOKEN;\n if (!apiKey) {\n throw new Error(\n \"TIMETICK_API_TOKEN is not set. Generate an API key in the Timetick portal \" +\n \"(Account → API keys) and expose it to the MCP server as TIMETICK_API_TOKEN.\",\n );\n }\n\n client = createClient({ apiKey, endpoint: process.env.TIMETICK_API_URL });\n return client;\n}\n","import { sdk } from \"./sdk.js\";\n\nexport interface Context {\n projectId: string;\n projectName: string;\n simWorldId: string;\n /** Scope id used by hardware/device queries — distinct from simWorldId. */\n deviceScopeId: string;\n /** How the project was chosen — surfaced to the user for transparency. */\n source: \"single-project\" | \"explicit\";\n}\n\n/** Thrown when the project/sim world can't be resolved without user input. */\nexport class ContextError extends Error {}\n\nlet cached: Context | null = null;\n\n/** Resolves a project's sim world (one sim world per project today). */\nasync function buildContext(\n projectId: string,\n projectName: string,\n source: Context[\"source\"],\n): Promise<Context> {\n const worlds = await sdk().simWorlds.list(projectId);\n const world = worlds?.[0];\n if (!world?.id) {\n throw new ContextError(`Project \"${projectName}\" has no sim world to operate on.`);\n }\n return {\n projectId,\n projectName,\n simWorldId: world.id,\n deviceScopeId: world.deviceScopeId ?? world.id,\n source,\n };\n}\n\nconst PROJECT_LIST_LIMIT = 15;\n\ntype ProjectSummary = { id?: string | null; name?: string | null } | null | undefined;\n\nfunction formatProjects(projects: readonly ProjectSummary[] | null | undefined): string {\n const all = projects ?? [];\n const lines = all\n .slice(0, PROJECT_LIST_LIMIT)\n .map((p) => ` - ${p?.name} (id: ${p?.id})`);\n if (all.length > PROJECT_LIST_LIMIT) {\n lines.push(` …and ${all.length - PROJECT_LIST_LIMIT} more — call list_projects to see them all.`);\n }\n return lines.join(\"\\n\");\n}\n\nasync function findProject(project: string): Promise<{ id: string; name: string }> {\n const projects = await sdk().projects.list();\n const needle = project.toLowerCase();\n const match = projects?.find(\n (p) => p?.id === project || p?.name?.toLowerCase() === needle,\n );\n if (!match?.id) {\n throw new ContextError(\n `No project matching \"${project}\". Available:\\n${formatProjects(projects)}`,\n );\n }\n return { id: match.id, name: match.name ?? \"(unnamed)\" };\n}\n\n/**\n * Returns the active context, auto-selecting the project when there is only one.\n * Throws ContextError (with the project list) when the choice is ambiguous.\n */\nexport async function getContext(): Promise<Context> {\n if (cached) return cached;\n\n const projects = await sdk().projects.list();\n if (!projects || projects.length === 0) {\n throw new ContextError(\"No projects are available for this API key.\");\n }\n if (projects.length > 1) {\n throw new ContextError(\n `You have ${projects.length} projects. Call \\`use_project\\` with a project name or id ` +\n `first:\\n${formatProjects(projects)}`,\n );\n }\n\n const only = projects[0]!;\n cached = await buildContext(only.id!, only.name ?? \"(unnamed)\", \"single-project\");\n return cached;\n}\n\n/** Explicitly switches the active project by name or id, and caches its sim world. */\nexport async function useProject(input: { project: string }): Promise<Context> {\n const match = await findProject(input.project);\n cached = await buildContext(match.id, match.name, \"explicit\");\n return cached;\n}\n\nexport async function lookupProject(project: string): Promise<Context> {\n const match = await findProject(project);\n return buildContext(match.id, match.name, \"explicit\");\n}\n\n/** Returns the cached context without resolving, if any. */\nexport function peekContext(): Context | null {\n return cached;\n}\n","import { TimetickError } from \"@timetick/sdk\";\n\ntype ToolResult = {\n content: { type: \"text\"; text: string }[];\n isError?: boolean;\n};\n\n/** Wraps a value into an MCP text result, pretty-printing objects as JSON. */\nexport function ok(text: string, data?: unknown): ToolResult {\n const body = data === undefined ? text : `${text}\\n\\n${JSON.stringify(data, null, 2)}`;\n return { content: [{ type: \"text\", text: body }] };\n}\n\nexport function fail(message: string): ToolResult {\n return { content: [{ type: \"text\", text: message }], isError: true };\n}\n\n/** Runs a tool handler, normalizing SDK/unknown errors into an isError result. */\nexport async function guard(fn: () => Promise<ToolResult>): Promise<ToolResult> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof TimetickError) return fail(`Timetick API error: ${err.message}`);\n return fail(err instanceof Error ? err.message : String(err));\n }\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { sdk } from \"../sdk.js\";\nimport { resolveSimWorld, resolveSimulator } from \"../resolve.js\";\nimport { paginationArgs, pagination, pageSummary } from \"../pagination.js\";\nimport { ok, guard } from \"../result.js\";\n\nconst protocolEnum = z.enum([\"OCPP_1_6\", \"OCPP_2_0_1\"]);\n\nfunction summarizeArgs(params: unknown): Record<string, string> | undefined {\n if (!params || typeof params !== \"object\") return undefined;\n const summary: Record<string, string> = {};\n for (const [name, spec] of Object.entries(params as Record<string, unknown>)) {\n if (!spec || typeof spec !== \"object\") continue;\n const { type, allowNull, defaultValue, visible } = spec as Record<string, unknown>;\n if (visible === false) continue;\n const parts = [String(type ?? \"unknown\"), allowNull === false ? \"required\" : \"optional\"];\n if (defaultValue !== undefined) parts.push(`default ${JSON.stringify(defaultValue)}`);\n summary[name] = parts.join(\", \");\n }\n return Object.keys(summary).length > 0 ? summary : undefined;\n}\n\nexport function registerDataTools(server: McpServer) {\n server.registerTool(\n \"list_projects\",\n {\n title: \"List projects\",\n description: \"List all projects available to your API key.\",\n inputSchema: {},\n },\n async () =>\n guard(async () => {\n const projects = await sdk().projects.list();\n return ok(`Found ${projects?.length ?? 0} project(s).`, projects);\n }),\n );\n\n server.registerTool(\n \"list_simulators\",\n {\n title: \"List simulators\",\n description:\n \"List simulators (virtual chargers) in the active project's sim world. \" +\n \"Optionally filter by name search or protocol.\",\n inputSchema: {\n search: z.string().optional().describe(\"Filter by simulator base name\"),\n protocol: protocolEnum.optional(),\n ...paginationArgs,\n project: z.string().optional().describe(\"Project name or id (defaults to active project)\"),\n },\n },\n async ({ search, protocol, page, pageSize, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const result = await sdk().simulators.list({\n simWorldId: ctx.simWorldId,\n searchValue: search,\n filters: protocol ? { protocol } : undefined,\n pagination: pagination(page, pageSize),\n });\n return ok(\n pageSummary(\"simulator(s)\", result?.records?.length ?? 0, result?.pageInfo),\n result,\n );\n }),\n );\n\n server.registerTool(\n \"get_simulator\",\n {\n title: \"Get simulator\",\n description:\n \"Get a simulator's details and live status (network status, launched/power status, connectors) \" +\n \"by id or base name.\",\n inputSchema: {\n simulator: z.string().describe(\"Simulator id or base name\"),\n project: z.string().optional().describe(\"Project name or id (defaults to active project)\"),\n },\n },\n async ({ simulator, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const resolved = await resolveSimulator(ctx.simWorldId, simulator);\n const details = await sdk().simulators.get(resolved.id);\n return ok(`Simulator ${resolved.baseName} (id: ${resolved.id}).`, details);\n }),\n );\n\n server.registerTool(\n \"list_hardware\",\n {\n title: \"List hardware\",\n description: \"List physical OCPP hardware devices in the active project's sim world.\",\n inputSchema: {\n search: z.string().optional().describe(\"Filter by serial number / model\"),\n ...paginationArgs,\n project: z.string().optional().describe(\"Project name or id (defaults to active project)\"),\n },\n },\n async ({ search, page, pageSize, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const result = await sdk().hardware.list({\n deviceScopeId: ctx.deviceScopeId,\n searchValue: search,\n pagination: pagination(page, pageSize),\n });\n return ok(\n pageSummary(\"hardware device(s)\", result?.records?.length ?? 0, result?.pageInfo),\n result,\n );\n }),\n );\n\n server.registerTool(\n \"list_actions\",\n {\n title: \"List actions (test steps)\",\n description:\n \"List available actions (steps) you can use to build a test — e.g. 'Power On Charger', \" +\n \"'Plug In Connector', 'Charge a Vehicle'. Filter by protocol. Each action lists its \" +\n \"arguments: the name, whether it is required (allowNull false), and any default.\",\n inputSchema: {\n protocol: protocolEnum.optional(),\n search: z.string().optional().describe(\"Filter by action name\"),\n ...paginationArgs,\n project: z.string().optional().describe(\"Project name or id (defaults to active project)\"),\n },\n },\n async ({ protocol, search, page, pageSize, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const result = await sdk().actions.list({\n simWorldId: ctx.simWorldId,\n searchValue: search,\n filters: { isSystem: true, deviceType: \"CHARGER\", ...(protocol ? { protocol } : {}) },\n pagination: pagination(page, pageSize, 100),\n });\n const actions = (result?.records ?? []).map((a) => ({\n name: a?.name,\n description: a?.description ?? undefined,\n args: summarizeArgs(a?.params),\n }));\n return ok(pageSummary(\"action(s)\", actions.length, result?.pageInfo), actions);\n }),\n );\n}\n","import { sdk } from \"./sdk.js\";\nimport { getContext, lookupProject, type Context } from \"./context.js\";\n\n/** Resolves the sim world to operate in: explicit project arg wins, else session context. */\nexport async function resolveSimWorld(project?: string): Promise<Context> {\n if (project) return lookupProject(project);\n return getContext();\n}\n\nexport interface ResolvedSimulator {\n id: string;\n baseName: string;\n protocol: string;\n}\n\n/** Resolves a simulator by id or by (case-insensitive) base name within a sim world. */\nexport async function resolveSimulator(\n simWorldId: string,\n simulator: string,\n): Promise<ResolvedSimulator> {\n const needle = simulator.toLowerCase();\n const page = await sdk().simulators.list({ simWorldId, searchValue: simulator });\n const records = page?.records ?? [];\n\n const exact =\n records.find((r) => r?.id === simulator) ??\n records.find((r) => r?.baseName?.toLowerCase() === needle) ??\n (records.length === 1 ? records[0] : undefined);\n\n if (exact?.id) {\n return { id: exact.id, baseName: exact.baseName ?? \"\", protocol: String(exact.protocol) };\n }\n\n // Fall back to treating the input as a raw id.\n const byId = await sdk().simulators.get(simulator).catch(() => null);\n if (byId?.id) {\n return { id: byId.id, baseName: byId.baseName ?? \"\", protocol: String(byId.protocol) };\n }\n\n const candidates = records.map((r) => ` - ${r?.baseName} (id: ${r?.id})`).join(\"\\n\");\n throw new Error(\n `No simulator matching \"${simulator}\".` +\n (candidates ? `\\nCandidates:\\n${candidates}` : \" No simulators found in this sim world.\"),\n );\n}\n\n/** Finds a system action by exact name for a given protocol; returns its id. */\nexport async function resolveActionId(\n simWorldId: string,\n protocol: string,\n actionName: string,\n): Promise<string> {\n const page = await sdk().actions.list({\n simWorldId,\n searchValue: actionName,\n filters: { isSystem: true, protocol: protocol as any, deviceType: \"CHARGER\" },\n pagination: { page: 1, pageSize: 50 },\n });\n const records = page?.records ?? [];\n const needle = actionName.toLowerCase();\n const match =\n records.find((a) => a?.name?.toLowerCase() === needle) ??\n records.find((a) => a?.name?.toLowerCase().includes(needle));\n\n if (!match?.id) {\n const available = records.map((a) => ` - ${a?.name}`).join(\"\\n\");\n throw new Error(\n `Action \"${actionName}\" not found for ${protocol}.` +\n (available ? `\\nAvailable system actions matching your search:\\n${available}` : \"\"),\n );\n }\n return match.id;\n}\n","import { z } from \"zod\";\n\nexport const DEFAULT_PAGE_SIZE = 20;\n\nexport const paginationArgs = {\n page: z.number().int().min(1).optional().describe(\"Page number, starting at 1 (default 1)\"),\n pageSize: z\n .number()\n .int()\n .min(1)\n .max(200)\n .optional()\n .describe(`Results per page (default ${DEFAULT_PAGE_SIZE})`),\n};\n\nexport function pagination(page?: number, pageSize?: number, defaultPageSize = DEFAULT_PAGE_SIZE) {\n return { page: page ?? 1, pageSize: pageSize ?? defaultPageSize };\n}\n\ninterface PageInfoLike {\n page?: number | null;\n pageSize?: number | null;\n hasNextPage?: boolean | null;\n totalCount?: number | null;\n}\n\nexport function pageSummary(noun: string, count: number, pageInfo?: PageInfoLike | null): string {\n const total = pageInfo?.totalCount;\n const head =\n total != null && total !== count\n ? `Showing ${count} of ${total} ${noun} (page ${pageInfo?.page ?? 1}).`\n : `Found ${count} ${noun}.`;\n return pageInfo?.hasNextPage ? `${head} More results available — request the next page.` : head;\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { sdk } from \"../sdk.js\";\nimport { resolveSimWorld, resolveSimulator, resolveActionId } from \"../resolve.js\";\nimport { ok, guard } from \"../result.js\";\n\n/** Runs a single named action against a simulator via the SDK's runAction. */\nasync function runOnSimulator(\n project: string | undefined,\n simulator: string,\n actionName: string,\n args: { key: string; value: string }[] = [],\n) {\n const ctx = await resolveSimWorld(project);\n const sim = await resolveSimulator(ctx.simWorldId, simulator);\n const actionId = await resolveActionId(ctx.simWorldId, sim.protocol, actionName);\n\n const status = await sdk().testRuns.runAction({\n chargerId: sim.id,\n action: { requirementKey: \"1\", stream: 1, order: 1, actionId, args },\n });\n return { sim, actionName, status };\n}\n\nexport function registerSimulatorTools(server: McpServer) {\n const projectArg = z\n .string()\n .optional()\n .describe(\"Project name or id (defaults to active project)\");\n\n server.registerTool(\n \"power_on_simulator\",\n {\n title: \"Power on simulator\",\n description: \"Power on a simulator (boots it and connects it to the OCPP server).\",\n inputSchema: {\n simulator: z.string().describe(\"Simulator id or base name\"),\n project: projectArg,\n },\n },\n async ({ simulator, project }) =>\n guard(async () => {\n const { sim, status } = await runOnSimulator(project, simulator, \"Power On Charger\");\n return ok(`Powered on ${sim.baseName} (id: ${sim.id}).`, { status });\n }),\n );\n\n server.registerTool(\n \"power_off_simulator\",\n {\n title: \"Power off simulator\",\n description: \"Power off a simulator.\",\n inputSchema: {\n simulator: z.string().describe(\"Simulator id or base name\"),\n project: projectArg,\n },\n },\n async ({ simulator, project }) =>\n guard(async () => {\n const { sim, status } = await runOnSimulator(project, simulator, \"Power Off Charger\");\n return ok(`Powered off ${sim.baseName} (id: ${sim.id}).`, { status });\n }),\n );\n\n server.registerTool(\n \"run_simulator_action\",\n {\n title: \"Run simulator action\",\n description:\n \"Run a single named action against a simulator — e.g. 'Reset Charger', 'Plug In Connector', \" +\n \"'Plug Out Connector'. Use list_actions to discover names and required args. \" +\n \"Args are passed as key/value pairs (e.g. connectorId=1).\",\n inputSchema: {\n simulator: z.string().describe(\"Simulator id or base name\"),\n actionName: z.string().describe(\"Exact action name, e.g. 'Reset Charger'\"),\n args: z\n .array(z.object({ key: z.string(), value: z.string() }))\n .optional()\n .describe(\"Action arguments as key/value pairs\"),\n project: projectArg,\n },\n },\n async ({ simulator, actionName, args, project }) =>\n guard(async () => {\n const { sim, status } = await runOnSimulator(project, simulator, actionName, args ?? []);\n return ok(`Ran \"${actionName}\" on ${sim.baseName} (id: ${sim.id}).`, { status });\n }),\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { sdk } from \"../sdk.js\";\nimport { resolveSimWorld, resolveActionId } from \"../resolve.js\";\nimport { paginationArgs, pagination, pageSummary } from \"../pagination.js\";\nimport { ok, guard } from \"../result.js\";\n\nconst protocolEnum = z.enum([\"OCPP_1_6\", \"OCPP_2_0_1\"]);\n\nexport function registerTestTools(server: McpServer) {\n const projectArg = z\n .string()\n .optional()\n .describe(\"Project name or id (defaults to active project)\");\n\n server.registerTool(\n \"list_tests\",\n {\n title: \"List tests\",\n description: \"List tests (scenarios) in the active project's sim world.\",\n inputSchema: {\n protocol: protocolEnum.optional(),\n search: z.string().optional().describe(\"Filter by test name\"),\n ...paginationArgs,\n project: projectArg,\n },\n },\n async ({ protocol, search, page, pageSize, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const result = await sdk().tests.list({\n simWorldId: ctx.simWorldId,\n searchValue: search,\n filters: protocol ? { protocol } : undefined,\n pagination: pagination(page, pageSize),\n });\n return ok(pageSummary(\"test(s)\", result?.records?.length ?? 0, result?.pageInfo), result);\n }),\n );\n\n server.registerTool(\n \"get_test\",\n {\n title: \"Get test\",\n description: \"Get a test by id, including its device requirements.\",\n inputSchema: {\n testId: z.string().describe(\"Test (scenario) id\"),\n },\n },\n async ({ testId }) =>\n guard(async () => {\n const test = await sdk().tests.get(testId);\n if (!test) return ok(`No test found with id ${testId}.`);\n return ok(`Test ${test.name} (id: ${testId}).`, test);\n }),\n );\n\n server.registerTool(\n \"create_test\",\n {\n title: \"Create test\",\n description:\n \"Create a test from an ordered list of steps. Each step references an action by name \" +\n \"(use list_actions to discover them) plus optional key/value args. The steps run in order \" +\n \"against a single simulator. Example steps: 'Power On Charger', 'Plug In Connector', \" +\n \"'Use RFID Card', 'Charge a Vehicle', 'Plug Out Connector', 'Power Off Charger'.\",\n inputSchema: {\n name: z.string().describe(\"Test name\"),\n protocol: protocolEnum,\n steps: z\n .array(\n z.object({\n actionName: z.string().describe(\"Exact action name, e.g. 'Power On Charger'\"),\n args: z\n .array(z.object({ key: z.string(), value: z.string() }))\n .optional()\n .describe(\"Action arguments as key/value pairs\"),\n }),\n )\n .min(1)\n .describe(\"Ordered list of steps\"),\n project: projectArg,\n },\n },\n async ({ name, protocol, steps, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n\n const actions = [];\n for (let i = 0; i < steps.length; i++) {\n const actionId = await resolveActionId(ctx.simWorldId, protocol, steps[i].actionName);\n actions.push({\n order: i + 1,\n stream: 1,\n actionId,\n requirementKey: \"charger\",\n args: steps[i].args ?? [],\n });\n }\n\n const test = await sdk().tests.create({\n simWorldId: ctx.simWorldId,\n name,\n deviceType: \"CHARGER\",\n requirements: [\n { key: \"charger\", type: \"CHARGER\", params: [{ key: \"protocol\", value: protocol }] },\n ],\n actions,\n });\n return ok(`Created test \"${name}\" (id: ${test?.id}).`, test);\n }),\n );\n}\n","import { z } from \"zod\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { sdk } from \"../sdk.js\";\nimport { resolveSimWorld, resolveSimulator } from \"../resolve.js\";\nimport { paginationArgs, pagination, pageSummary } from \"../pagination.js\";\nimport { ok, fail, guard } from \"../result.js\";\n\nexport function registerTestRunTools(server: McpServer) {\n const projectArg = z\n .string()\n .optional()\n .describe(\"Project name or id (defaults to active project)\");\n\n server.registerTool(\n \"run_test\",\n {\n title: \"Run test\",\n description:\n \"Run a test (scenario) on a simulator, starting immediately. \" +\n \"Returns the test run id and status — poll with get_test_run to follow it. \" +\n \"A simulator runs one test at a time; if it is busy this says so and starts nothing.\",\n inputSchema: {\n testId: z.string().describe(\"Test (scenario) id to run\"),\n simulator: z.string().describe(\"Simulator id or base name to run the test on\"),\n project: projectArg,\n },\n },\n async ({ testId, simulator, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const test = await sdk().tests.get(testId);\n const requirementId = test?.requirements?.[0]?.id;\n if (!requirementId) return fail(`Test ${testId} has no device requirement to assign.`);\n\n const sim = await resolveSimulator(ctx.simWorldId, simulator);\n const run = await sdk()\n .testRuns.create({\n scenarioId: testId,\n simWorldId: ctx.simWorldId,\n scheduleMode: \"NOW\",\n speedup: 1,\n forceDelete: false,\n requirementDevices: [\n { requirementId, deviceId: sim.id, deviceMode: \"SIMULATOR\" },\n ],\n })\n .catch(async (err: unknown) => {\n const message = err instanceof Error ? err.message : String(err);\n if (!/conflict/i.test(message)) throw err;\n\n const details = await sdk().simulators.get(sim.id).catch(() => null);\n const blocking = details?.lastRun;\n throw new Error(\n `${sim.baseName} (id: ${sim.id}) is busy` +\n (blocking?.id ? ` with test run ${blocking.id} (${blocking.status})` : \"\") +\n `, so nothing was started. Stop that run with stop_test_run — the simulator is ` +\n `free once it stops — then run this test again.`,\n );\n });\n return ok(\n `Started test \"${test?.name}\" on ${sim.baseName} — run id ${run?.id}, status ${run?.status}.`,\n run,\n );\n }),\n );\n\n server.registerTool(\n \"get_test_run\",\n {\n title: \"Get test run\",\n description: \"Get a test run's status by id.\",\n inputSchema: {\n runId: z.string().describe(\"Test run id\"),\n },\n },\n async ({ runId }) =>\n guard(async () => {\n const run = await sdk().testRuns.get(runId);\n if (!run) return ok(`No test run found with id ${runId}.`);\n const reason = run.failReason ? ` — ${run.failReason}` : \"\";\n return ok(`Test run ${runId} (\"${run.scenario?.name}\"): ${run.status}${reason}.`, run);\n }),\n );\n\n server.registerTool(\n \"list_test_runs\",\n {\n title: \"List test runs\",\n description: \"List recent test runs in the active project's sim world.\",\n inputSchema: {\n ...paginationArgs,\n project: projectArg,\n },\n },\n async ({ page, pageSize, project }) =>\n guard(async () => {\n const ctx = await resolveSimWorld(project);\n const result = await sdk().testRuns.list({\n simWorldId: ctx.simWorldId,\n pagination: pagination(page, pageSize),\n });\n return ok(pageSummary(\"test run(s)\", result?.records?.length ?? 0, result?.pageInfo), result);\n }),\n );\n\n server.registerTool(\n \"stop_test_run\",\n {\n title: \"Stop test run\",\n description: \"Shut down (stop) a running or scheduled test run by id.\",\n inputSchema: {\n runId: z.string().describe(\"Test run id\"),\n },\n },\n async ({ runId }) =>\n guard(async () => {\n const existing = await sdk().testRuns.get(runId);\n if (!existing) return fail(`No test run found with id ${runId}.`);\n\n await sdk().testRuns.shutDown(runId);\n const after = await sdk().testRuns.get(runId);\n return ok(\n `Shut down test run ${runId} (was ${existing.status}, now ${after?.status ?? \"unknown\"}).`,\n after,\n );\n }),\n );\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","protocolEnum","z","z","z"]}
|