-
-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathbuild.ts
More file actions
76 lines (72 loc) · 2.58 KB
/
build.ts
File metadata and controls
76 lines (72 loc) · 2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { compactDualOutput, assertNoFlagInjection, INPUT_LIMITS } from "@paretools/shared";
import { docker } from "../lib/docker-runner.js";
import { parseBuildOutput } from "../lib/parsers.js";
import { formatBuild, compactBuildMap, formatBuildCompact } from "../lib/formatters.js";
import { DockerBuildSchema } from "../schemas/index.js";
export function registerBuildTool(server: McpServer) {
server.registerTool(
"build",
{
title: "Docker Build",
description:
"Builds a Docker image and returns structured build results including image ID, duration, and errors. Use instead of running `docker build` in the terminal.",
inputSchema: {
path: z
.string()
.max(INPUT_LIMITS.PATH_MAX)
.optional()
.describe("Build context path (default: cwd)"),
tag: z
.string()
.max(INPUT_LIMITS.SHORT_STRING_MAX)
.optional()
.describe("Image tag (e.g., myapp:latest)"),
file: z
.string()
.max(INPUT_LIMITS.PATH_MAX)
.optional()
.describe("Dockerfile path (default: Dockerfile)"),
args: z
.array(z.string().max(INPUT_LIMITS.STRING_MAX))
.max(INPUT_LIMITS.ARRAY_MAX)
.optional()
.default([])
.describe("Additional build arguments"),
compact: z
.boolean()
.optional()
.default(true)
.describe(
"Auto-compact when structured output exceeds raw CLI tokens. Set false to always get full schema.",
),
},
outputSchema: DockerBuildSchema,
},
async ({ path, tag, file, args, compact }) => {
if (tag) assertNoFlagInjection(tag, "tag");
if (file) assertNoFlagInjection(file, "file");
for (const a of args ?? []) {
assertNoFlagInjection(a, "args");
}
const cwd = path || process.cwd();
const dockerArgs = ["build", "."];
if (tag) dockerArgs.push("-t", tag);
if (file) dockerArgs.push("-f", file);
if (args) dockerArgs.push(...args);
const start = Date.now();
const result = await docker(dockerArgs, cwd);
const duration = Math.round((Date.now() - start) / 100) / 10;
const data = parseBuildOutput(result.stdout, result.stderr, result.exitCode, duration);
return compactDualOutput(
data,
result.stdout,
formatBuild,
compactBuildMap,
formatBuildCompact,
compact === false,
);
},
);
}