@kynver-app/mcp-estimator 0.2.8 → 0.2.10
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/dist/server.js +16 -0
- package/dist/tools/catalog-tools.js +1 -1
- package/dist/tools/email-pdf-tools.d.ts +45 -0
- package/dist/tools/email-pdf-tools.js +21 -0
- package/dist/tools/intake-tools.d.ts +463 -0
- package/dist/tools/intake-tools.js +82 -0
- package/dist/tools/price-catalog-tools.d.ts +96 -0
- package/dist/tools/price-catalog-tools.js +72 -0
- package/dist/tools/remodel-deliverable-tools.d.ts +1868 -0
- package/dist/tools/remodel-deliverable-tools.js +138 -0
- package/dist/tools/remodel-estimate-tools.d.ts +525 -0
- package/dist/tools/remodel-estimate-tools.js +71 -0
- package/dist/tools/takeoff-tools.d.ts +274 -0
- package/dist/tools/takeoff-tools.js +38 -4
- package/dist/tools/vision-tools.js +2 -2
- package/package.json +6 -1
- package/src/index.ts +0 -18
- package/src/lib/kynver-client.ts +0 -136
- package/src/lib/mcp-sse-server.ts +0 -249
- package/src/lib/package-version.ts +0 -55
- package/src/server.ts +0 -141
- package/src/sse.ts +0 -10
- package/src/tools/catalog-tools.ts +0 -217
- package/src/tools/client-tools.ts +0 -114
- package/src/tools/company-tools.ts +0 -108
- package/src/tools/email-pdf-tools.ts +0 -27
- package/src/tools/estimate-tools.ts +0 -281
- package/src/tools/intake-tools.ts +0 -95
- package/src/tools/photo-tools.ts +0 -60
- package/src/tools/price-catalog-tools.ts +0 -80
- package/src/tools/remodel-deliverable-tools.ts +0 -163
- package/src/tools/remodel-estimate-tools.ts +0 -80
- package/src/tools/stats-pdf-tools.ts +0 -80
- package/src/tools/takeoff-tools.ts +0 -319
- package/src/tools/template-tools.ts +0 -80
- package/src/tools/version-tools.ts +0 -39
- package/src/tools/vision-tools.ts +0 -48
- package/tsconfig.json +0 -15
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as client from "../lib/kynver-client.js";
|
|
3
|
+
const remodelProjectTypeSchema = z.enum([
|
|
4
|
+
"kitchen_remodel",
|
|
5
|
+
"bath_remodel",
|
|
6
|
+
"kitchen_and_bath_remodel",
|
|
7
|
+
"whole_home_remodel",
|
|
8
|
+
"other_remodel",
|
|
9
|
+
]);
|
|
10
|
+
const normalizeRemodelIntakeSchema = z.object({
|
|
11
|
+
projectType: remodelProjectTypeSchema,
|
|
12
|
+
projectName: z.string().optional(),
|
|
13
|
+
siteAddress: z.string().optional(),
|
|
14
|
+
baseScopes: z
|
|
15
|
+
.array(z.object({
|
|
16
|
+
key: z.string().optional(),
|
|
17
|
+
label: z.string(),
|
|
18
|
+
quantity: z.number().optional(),
|
|
19
|
+
unit: z.string().optional(),
|
|
20
|
+
serviceCode: z.string().optional(),
|
|
21
|
+
budgetLump: z.number().optional(),
|
|
22
|
+
notes: z.string().optional(),
|
|
23
|
+
confidence: z.enum(["high", "medium", "low", "unknown"]).optional(),
|
|
24
|
+
isAlternate: z.boolean().optional(),
|
|
25
|
+
alternateGroup: z.string().optional(),
|
|
26
|
+
}))
|
|
27
|
+
.optional(),
|
|
28
|
+
alternates: z
|
|
29
|
+
.array(z.object({
|
|
30
|
+
key: z.string(),
|
|
31
|
+
label: z.string(),
|
|
32
|
+
scopeKeys: z.array(z.string()).optional(),
|
|
33
|
+
lumpAdd: z.number().optional(),
|
|
34
|
+
notes: z.string().optional(),
|
|
35
|
+
}))
|
|
36
|
+
.optional(),
|
|
37
|
+
attachments: z
|
|
38
|
+
.array(z.object({
|
|
39
|
+
id: z.string(),
|
|
40
|
+
kind: z.enum(["photo", "drawing", "plan_set", "spec_pdf", "spreadsheet", "other"]),
|
|
41
|
+
fileName: z.string().optional(),
|
|
42
|
+
caption: z.string().optional(),
|
|
43
|
+
url: z.string().optional(),
|
|
44
|
+
mimeType: z.string().optional(),
|
|
45
|
+
}))
|
|
46
|
+
.optional(),
|
|
47
|
+
exclusions: z.array(z.string()).optional(),
|
|
48
|
+
surprises: z.array(z.string()).optional(),
|
|
49
|
+
rateReferences: z
|
|
50
|
+
.array(z.object({
|
|
51
|
+
key: z.string(),
|
|
52
|
+
label: z.string(),
|
|
53
|
+
value: z.number(),
|
|
54
|
+
unit: z.string().optional(),
|
|
55
|
+
source: z.enum(["operating_rule", "catalog", "user", "takeoff"]),
|
|
56
|
+
catalogId: z.string().optional(),
|
|
57
|
+
confidence: z.enum(["high", "medium", "low", "unknown"]).optional(),
|
|
58
|
+
}))
|
|
59
|
+
.optional(),
|
|
60
|
+
assumptionsNeedingReview: z
|
|
61
|
+
.array(z.object({
|
|
62
|
+
id: z.string(),
|
|
63
|
+
text: z.string(),
|
|
64
|
+
severity: z.enum(["info", "warn", "blocker"]),
|
|
65
|
+
relatedScopeKey: z.string().optional(),
|
|
66
|
+
}))
|
|
67
|
+
.optional(),
|
|
68
|
+
remodelHints: z.record(z.string(), z.unknown()).optional(),
|
|
69
|
+
includeStandardAlternates: z.boolean().optional(),
|
|
70
|
+
notes: z.string().optional(),
|
|
71
|
+
});
|
|
72
|
+
export const normalizeRemodelIntake = {
|
|
73
|
+
name: "estimator_normalize_remodel_intake",
|
|
74
|
+
description: "Validate and normalize a residential remodel intake payload for kitchen/bath estimating. Accepts project type, base scopes vs alternates, drawing/photo attachment metadata, exclusions/surprises, rate references, and optional remodelHints from takeoff. Returns provenance-backed scopes, Will Portland default rates, assumptions needing review, and an estimate-builder-ready payload.",
|
|
75
|
+
inputSchemaZod: normalizeRemodelIntakeSchema,
|
|
76
|
+
execute: async (args) => {
|
|
77
|
+
if (!client.hasApiKey())
|
|
78
|
+
return client.noApiKeyMessage();
|
|
79
|
+
const data = await client.post("/estimator/intake/normalize-remodel", args);
|
|
80
|
+
return JSON.stringify(data, null, 2);
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
declare const listPriceCatalogsSchema: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
3
|
+
export declare const listPriceCatalogs: {
|
|
4
|
+
name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
inputSchemaZod: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
|
|
7
|
+
execute: (_args: z.infer<typeof listPriceCatalogsSchema>) => Promise<string>;
|
|
8
|
+
};
|
|
9
|
+
declare const getPriceCatalogSchema: z.ZodObject<{
|
|
10
|
+
catalogId: z.ZodString;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
12
|
+
catalogId: string;
|
|
13
|
+
}, {
|
|
14
|
+
catalogId: string;
|
|
15
|
+
}>;
|
|
16
|
+
export declare const getPriceCatalog: {
|
|
17
|
+
name: string;
|
|
18
|
+
description: string;
|
|
19
|
+
inputSchemaZod: z.ZodObject<{
|
|
20
|
+
catalogId: z.ZodString;
|
|
21
|
+
}, "strip", z.ZodTypeAny, {
|
|
22
|
+
catalogId: string;
|
|
23
|
+
}, {
|
|
24
|
+
catalogId: string;
|
|
25
|
+
}>;
|
|
26
|
+
execute: (args: z.infer<typeof getPriceCatalogSchema>) => Promise<string>;
|
|
27
|
+
};
|
|
28
|
+
declare const resolvePriceSchema: z.ZodObject<{
|
|
29
|
+
serviceCode: z.ZodString;
|
|
30
|
+
materialType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
31
|
+
region: z.ZodOptional<z.ZodString>;
|
|
32
|
+
overrideMaterialCost: z.ZodOptional<z.ZodNumber>;
|
|
33
|
+
overrideLaborCost: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
}, "strip", z.ZodTypeAny, {
|
|
35
|
+
serviceCode: string;
|
|
36
|
+
materialType?: string | null | undefined;
|
|
37
|
+
region?: string | undefined;
|
|
38
|
+
overrideMaterialCost?: number | undefined;
|
|
39
|
+
overrideLaborCost?: number | undefined;
|
|
40
|
+
}, {
|
|
41
|
+
serviceCode: string;
|
|
42
|
+
materialType?: string | null | undefined;
|
|
43
|
+
region?: string | undefined;
|
|
44
|
+
overrideMaterialCost?: number | undefined;
|
|
45
|
+
overrideLaborCost?: number | undefined;
|
|
46
|
+
}>;
|
|
47
|
+
export declare const resolvePrice: {
|
|
48
|
+
name: string;
|
|
49
|
+
description: string;
|
|
50
|
+
inputSchemaZod: z.ZodObject<{
|
|
51
|
+
serviceCode: z.ZodString;
|
|
52
|
+
materialType: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
53
|
+
region: z.ZodOptional<z.ZodString>;
|
|
54
|
+
overrideMaterialCost: z.ZodOptional<z.ZodNumber>;
|
|
55
|
+
overrideLaborCost: z.ZodOptional<z.ZodNumber>;
|
|
56
|
+
}, "strip", z.ZodTypeAny, {
|
|
57
|
+
serviceCode: string;
|
|
58
|
+
materialType?: string | null | undefined;
|
|
59
|
+
region?: string | undefined;
|
|
60
|
+
overrideMaterialCost?: number | undefined;
|
|
61
|
+
overrideLaborCost?: number | undefined;
|
|
62
|
+
}, {
|
|
63
|
+
serviceCode: string;
|
|
64
|
+
materialType?: string | null | undefined;
|
|
65
|
+
region?: string | undefined;
|
|
66
|
+
overrideMaterialCost?: number | undefined;
|
|
67
|
+
overrideLaborCost?: number | undefined;
|
|
68
|
+
}>;
|
|
69
|
+
execute: (args: z.infer<typeof resolvePriceSchema>) => Promise<string>;
|
|
70
|
+
};
|
|
71
|
+
declare const seedPriceCatalogSchema: z.ZodObject<{
|
|
72
|
+
catalogId: z.ZodString;
|
|
73
|
+
overwrite: z.ZodOptional<z.ZodBoolean>;
|
|
74
|
+
}, "strip", z.ZodTypeAny, {
|
|
75
|
+
catalogId: string;
|
|
76
|
+
overwrite?: boolean | undefined;
|
|
77
|
+
}, {
|
|
78
|
+
catalogId: string;
|
|
79
|
+
overwrite?: boolean | undefined;
|
|
80
|
+
}>;
|
|
81
|
+
export declare const seedPriceCatalog: {
|
|
82
|
+
name: string;
|
|
83
|
+
description: string;
|
|
84
|
+
inputSchemaZod: z.ZodObject<{
|
|
85
|
+
catalogId: z.ZodString;
|
|
86
|
+
overwrite: z.ZodOptional<z.ZodBoolean>;
|
|
87
|
+
}, "strip", z.ZodTypeAny, {
|
|
88
|
+
catalogId: string;
|
|
89
|
+
overwrite?: boolean | undefined;
|
|
90
|
+
}, {
|
|
91
|
+
catalogId: string;
|
|
92
|
+
overwrite?: boolean | undefined;
|
|
93
|
+
}>;
|
|
94
|
+
execute: (args: z.infer<typeof seedPriceCatalogSchema>) => Promise<string>;
|
|
95
|
+
};
|
|
96
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import * as client from "../lib/kynver-client.js";
|
|
3
|
+
const listPriceCatalogsSchema = z.object({});
|
|
4
|
+
export const listPriceCatalogs = {
|
|
5
|
+
name: "estimator_list_price_catalogs",
|
|
6
|
+
description: "List durable builtin price catalogs shipped with the estimator (region, effective date, markup policy). These are the MCP's stored price lists — not AgentOS memory. Use before seeding or resolving remodel defaults.",
|
|
7
|
+
inputSchemaZod: listPriceCatalogsSchema,
|
|
8
|
+
execute: async (_args) => {
|
|
9
|
+
if (!client.hasApiKey())
|
|
10
|
+
return client.noApiKeyMessage();
|
|
11
|
+
const data = await client.get("/estimator/price-catalog");
|
|
12
|
+
return JSON.stringify(data);
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const getPriceCatalogSchema = z.object({
|
|
16
|
+
catalogId: z.string(),
|
|
17
|
+
});
|
|
18
|
+
export const getPriceCatalog = {
|
|
19
|
+
name: "estimator_get_price_catalog",
|
|
20
|
+
description: "Read all unit-price lines from a builtin price catalog (service codes, units, material/labor split, review/confidence metadata). Default Portland remodel catalog id: portland-remodel-will-2026-06.",
|
|
21
|
+
inputSchemaZod: getPriceCatalogSchema,
|
|
22
|
+
execute: async (args) => {
|
|
23
|
+
if (!client.hasApiKey())
|
|
24
|
+
return client.noApiKeyMessage();
|
|
25
|
+
const data = await client.get(`/estimator/price-catalog/${encodeURIComponent(args.catalogId)}`);
|
|
26
|
+
return JSON.stringify(data);
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
const resolvePriceSchema = z.object({
|
|
30
|
+
serviceCode: z.string(),
|
|
31
|
+
materialType: z.string().nullable().optional(),
|
|
32
|
+
region: z.string().optional(),
|
|
33
|
+
overrideMaterialCost: z.number().min(0).optional(),
|
|
34
|
+
overrideLaborCost: z.number().min(0).optional(),
|
|
35
|
+
});
|
|
36
|
+
export const resolvePrice = {
|
|
37
|
+
name: "estimator_resolve_price",
|
|
38
|
+
description: "Resolve unit pricing for one service code with provenance: user price book → builtin catalog → optional intake override (overrideMaterialCost/overrideLaborCost). Returns source, region, effective date, and markupIncluded flag.",
|
|
39
|
+
inputSchemaZod: resolvePriceSchema,
|
|
40
|
+
execute: async (args) => {
|
|
41
|
+
if (!client.hasApiKey())
|
|
42
|
+
return client.noApiKeyMessage();
|
|
43
|
+
const params = new URLSearchParams({ serviceCode: args.serviceCode });
|
|
44
|
+
if (args.materialType)
|
|
45
|
+
params.set("materialType", args.materialType);
|
|
46
|
+
if (args.region)
|
|
47
|
+
params.set("region", args.region);
|
|
48
|
+
if (args.overrideMaterialCost != null) {
|
|
49
|
+
params.set("overrideMaterialCost", String(args.overrideMaterialCost));
|
|
50
|
+
}
|
|
51
|
+
if (args.overrideLaborCost != null) {
|
|
52
|
+
params.set("overrideLaborCost", String(args.overrideLaborCost));
|
|
53
|
+
}
|
|
54
|
+
const data = await client.get(`/estimator/price-catalog/resolve?${params.toString()}`);
|
|
55
|
+
return JSON.stringify(data);
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
const seedPriceCatalogSchema = z.object({
|
|
59
|
+
catalogId: z.string(),
|
|
60
|
+
overwrite: z.boolean().optional(),
|
|
61
|
+
});
|
|
62
|
+
export const seedPriceCatalog = {
|
|
63
|
+
name: "estimator_seed_price_catalog",
|
|
64
|
+
description: "Copy a builtin price catalog into the user's ServiceCatalogItem price book (skips existing codes unless overwrite=true). Use portland-remodel-will-2026-06 for Will's Portland remodel working rates.",
|
|
65
|
+
inputSchemaZod: seedPriceCatalogSchema,
|
|
66
|
+
execute: async (args) => {
|
|
67
|
+
if (!client.hasApiKey())
|
|
68
|
+
return client.noApiKeyMessage();
|
|
69
|
+
const data = await client.post("/estimator/price-catalog/seed", args);
|
|
70
|
+
return JSON.stringify(data);
|
|
71
|
+
},
|
|
72
|
+
};
|