propstack-mcp-server 1.0.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.
Files changed (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +321 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +55 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/propstack-client.d.ts +24 -0
  8. package/dist/propstack-client.d.ts.map +1 -0
  9. package/dist/propstack-client.js +99 -0
  10. package/dist/propstack-client.js.map +1 -0
  11. package/dist/tools/activities.d.ts +4 -0
  12. package/dist/tools/activities.d.ts.map +1 -0
  13. package/dist/tools/activities.js +177 -0
  14. package/dist/tools/activities.js.map +1 -0
  15. package/dist/tools/admin.d.ts +4 -0
  16. package/dist/tools/admin.d.ts.map +1 -0
  17. package/dist/tools/admin.js +148 -0
  18. package/dist/tools/admin.js.map +1 -0
  19. package/dist/tools/composites.d.ts +4 -0
  20. package/dist/tools/composites.d.ts.map +1 -0
  21. package/dist/tools/composites.js +807 -0
  22. package/dist/tools/composites.js.map +1 -0
  23. package/dist/tools/contacts.d.ts +4 -0
  24. package/dist/tools/contacts.d.ts.map +1 -0
  25. package/dist/tools/contacts.js +386 -0
  26. package/dist/tools/contacts.js.map +1 -0
  27. package/dist/tools/deals.d.ts +4 -0
  28. package/dist/tools/deals.d.ts.map +1 -0
  29. package/dist/tools/deals.js +230 -0
  30. package/dist/tools/deals.js.map +1 -0
  31. package/dist/tools/documents.d.ts +4 -0
  32. package/dist/tools/documents.d.ts.map +1 -0
  33. package/dist/tools/documents.js +109 -0
  34. package/dist/tools/documents.js.map +1 -0
  35. package/dist/tools/emails.d.ts +4 -0
  36. package/dist/tools/emails.d.ts.map +1 -0
  37. package/dist/tools/emails.js +111 -0
  38. package/dist/tools/emails.js.map +1 -0
  39. package/dist/tools/helpers.d.ts +39 -0
  40. package/dist/tools/helpers.d.ts.map +1 -0
  41. package/dist/tools/helpers.js +160 -0
  42. package/dist/tools/helpers.js.map +1 -0
  43. package/dist/tools/lookups.d.ts +4 -0
  44. package/dist/tools/lookups.d.ts.map +1 -0
  45. package/dist/tools/lookups.js +333 -0
  46. package/dist/tools/lookups.js.map +1 -0
  47. package/dist/tools/projects.d.ts +4 -0
  48. package/dist/tools/projects.d.ts.map +1 -0
  49. package/dist/tools/projects.js +104 -0
  50. package/dist/tools/projects.js.map +1 -0
  51. package/dist/tools/properties.d.ts +4 -0
  52. package/dist/tools/properties.d.ts.map +1 -0
  53. package/dist/tools/properties.js +397 -0
  54. package/dist/tools/properties.js.map +1 -0
  55. package/dist/tools/relationships.d.ts +4 -0
  56. package/dist/tools/relationships.d.ts.map +1 -0
  57. package/dist/tools/relationships.js +55 -0
  58. package/dist/tools/relationships.js.map +1 -0
  59. package/dist/tools/search-profiles.d.ts +4 -0
  60. package/dist/tools/search-profiles.d.ts.map +1 -0
  61. package/dist/tools/search-profiles.js +345 -0
  62. package/dist/tools/search-profiles.js.map +1 -0
  63. package/dist/tools/tasks.d.ts +4 -0
  64. package/dist/tools/tasks.d.ts.map +1 -0
  65. package/dist/tools/tasks.js +251 -0
  66. package/dist/tools/tasks.js.map +1 -0
  67. package/dist/types/propstack.d.ts +444 -0
  68. package/dist/types/propstack.d.ts.map +1 -0
  69. package/dist/types/propstack.js +3 -0
  70. package/dist/types/propstack.js.map +1 -0
  71. package/package.json +54 -0
@@ -0,0 +1,345 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult, fmt, fmtPrice, stripUndefined, unwrapNumber, unwrapPropstackValue } from "./helpers.js";
3
+ // ── Response formatting ──────────────────────────────────────────────
4
+ function fmtRange(from, to, unit = "") {
5
+ const f = unwrapNumber(from);
6
+ const t = unwrapNumber(to);
7
+ if (f === null && t === null)
8
+ return null;
9
+ if (f !== null && t !== null)
10
+ return `${f}–${t}${unit ? ` ${unit}` : ""}`;
11
+ if (f !== null)
12
+ return `≥ ${f}${unit ? ` ${unit}` : ""}`;
13
+ return t !== null ? `≤ ${t}${unit ? ` ${unit}` : ""}` : null;
14
+ }
15
+ function fmtPriceRange(from, to) {
16
+ const f = unwrapNumber(from);
17
+ const t = unwrapNumber(to);
18
+ if (f === null && t === null)
19
+ return null;
20
+ if (f !== null && t !== null)
21
+ return `${fmtPrice(f)} – ${fmtPrice(t)}`;
22
+ if (f !== null)
23
+ return `≥ ${fmtPrice(f)}`;
24
+ return t !== null ? `≤ ${fmtPrice(t)}` : null;
25
+ }
26
+ function fmtFeature(value) {
27
+ const v = unwrapPropstackValue(value);
28
+ if (v === true || v === "true")
29
+ return "yes";
30
+ if (v === false || v === "false")
31
+ return "no";
32
+ return "any";
33
+ }
34
+ function formatSearchProfile(sp) {
35
+ const lines = [
36
+ `**Search Profile #${sp.id}** (Contact: ${fmt(sp.client_id)})`,
37
+ `Active: ${sp.active ? "yes" : "no"}`,
38
+ `Type: ${fmt(sp.marketing_type, "any")}`,
39
+ ];
40
+ // Location
41
+ if (sp.cities?.length)
42
+ lines.push(`Cities: ${sp.cities.join(", ")}`);
43
+ if (sp.regions?.length)
44
+ lines.push(`Regions: ${sp.regions.join(", ")}`);
45
+ if (sp.lat !== null && sp.lat !== undefined && sp.lng !== null && sp.lng !== undefined) {
46
+ lines.push(`Center: ${sp.lat}, ${sp.lng} (radius: ${sp.radius ?? "?"}m)`);
47
+ }
48
+ // Property types
49
+ if (sp.rs_types?.length)
50
+ lines.push(`Types: ${sp.rs_types.join(", ")}`);
51
+ if (sp.rs_categories?.length)
52
+ lines.push(`Categories: ${sp.rs_categories.join(", ")}`);
53
+ // Price ranges
54
+ const price = fmtPriceRange(sp.price, sp.price_to);
55
+ if (price)
56
+ lines.push(`Price: ${price}`);
57
+ const rent = fmtPriceRange(sp.base_rent, sp.base_rent_to);
58
+ if (rent)
59
+ lines.push(`Base rent: ${rent}`);
60
+ const totalRent = fmtPriceRange(sp.total_rent, sp.total_rent_to);
61
+ if (totalRent)
62
+ lines.push(`Total rent: ${totalRent}`);
63
+ // Space ranges
64
+ const living = fmtRange(sp.living_space, sp.living_space_to, "m²");
65
+ if (living)
66
+ lines.push(`Living space: ${living}`);
67
+ const plot = fmtRange(sp.plot_area, sp.plot_area_to, "m²");
68
+ if (plot)
69
+ lines.push(`Plot area: ${plot}`);
70
+ // Room ranges
71
+ const rooms = fmtRange(sp.number_of_rooms, sp.number_of_rooms_to);
72
+ if (rooms)
73
+ lines.push(`Rooms: ${rooms}`);
74
+ const bedrooms = fmtRange(sp.number_of_bed_rooms, sp.number_of_bed_rooms_to);
75
+ if (bedrooms)
76
+ lines.push(`Bedrooms: ${bedrooms}`);
77
+ // Other ranges
78
+ const floor = fmtRange(sp.floor, sp.floor_to);
79
+ if (floor)
80
+ lines.push(`Floor: ${floor}`);
81
+ const year = fmtRange(sp.construction_year, sp.construction_year_to);
82
+ if (year)
83
+ lines.push(`Built: ${year}`);
84
+ // Features — only show if set
85
+ const features = [];
86
+ if (sp.lift !== null && sp.lift !== undefined)
87
+ features.push(`Lift: ${fmtFeature(sp.lift)}`);
88
+ if (sp.balcony !== null && sp.balcony !== undefined)
89
+ features.push(`Balcony: ${fmtFeature(sp.balcony)}`);
90
+ if (sp.garden !== null && sp.garden !== undefined)
91
+ features.push(`Garden: ${fmtFeature(sp.garden)}`);
92
+ if (sp.built_in_kitchen !== null && sp.built_in_kitchen !== undefined)
93
+ features.push(`Kitchen: ${fmtFeature(sp.built_in_kitchen)}`);
94
+ if (sp.cellar !== null && sp.cellar !== undefined)
95
+ features.push(`Cellar: ${fmtFeature(sp.cellar)}`);
96
+ if (sp.rented !== null && sp.rented !== undefined)
97
+ features.push(`Rented: ${fmtFeature(sp.rented)}`);
98
+ if (features.length)
99
+ lines.push(`Features: ${features.join(", ")}`);
100
+ // Investment
101
+ const ppsqm = fmtPriceRange(sp.price_per_sqm, sp.price_per_sqm_to);
102
+ if (ppsqm)
103
+ lines.push(`Price/m²: ${ppsqm}`);
104
+ const mult = fmtRange(sp.price_multiplier, sp.price_multiplier_to, "x");
105
+ if (mult)
106
+ lines.push(`Multiplier: ${mult}`);
107
+ const yld = fmtRange(sp.yield_actual, sp.yield_actual_to, "%");
108
+ if (yld)
109
+ lines.push(`Yield: ${yld}`);
110
+ if (fmt(sp.note, ""))
111
+ lines.push(`Note: ${fmt(sp.note)}`);
112
+ lines.push(`Created: ${fmt(sp.created_at)}`);
113
+ return lines.filter(Boolean).join("\n");
114
+ }
115
+ // ── Shared Zod params for create / update ────────────────────────────
116
+ function searchProfileFields() {
117
+ return {
118
+ active: z.boolean().optional()
119
+ .describe("Whether the search profile is active (default: true)"),
120
+ marketing_type: z.enum(["BUY", "RENT"]).optional()
121
+ .describe("Marketing type: BUY (Kauf) or RENT (Miete)"),
122
+ // Location
123
+ cities: z.array(z.string()).optional()
124
+ .describe("City names to search in (e.g. ['Berlin', 'Potsdam'])"),
125
+ regions: z.array(z.string()).optional()
126
+ .describe("Region names to search in"),
127
+ lat: z.number().optional()
128
+ .describe("Latitude for radius search center"),
129
+ lng: z.number().optional()
130
+ .describe("Longitude for radius search center"),
131
+ radius: z.number().optional()
132
+ .describe("Search radius in meters from lat/lng center"),
133
+ location_ids: z.array(z.number()).optional()
134
+ .describe("Propstack location/district IDs"),
135
+ // Property types
136
+ rs_types: z.array(z.string()).optional()
137
+ .describe("Property types (e.g. ['APARTMENT', 'HOUSE'])"),
138
+ rs_categories: z.array(z.string()).optional()
139
+ .describe("Property categories (e.g. ['APARTMENT_NORMAL', 'HOUSE_DETACHED'])"),
140
+ // Price ranges
141
+ price: z.number().optional()
142
+ .describe("Minimum purchase price (EUR)"),
143
+ price_to: z.number().optional()
144
+ .describe("Maximum purchase price (EUR)"),
145
+ base_rent: z.number().optional()
146
+ .describe("Minimum base rent (EUR/month)"),
147
+ base_rent_to: z.number().optional()
148
+ .describe("Maximum base rent (EUR/month)"),
149
+ total_rent: z.number().optional()
150
+ .describe("Minimum total rent (EUR/month)"),
151
+ total_rent_to: z.number().optional()
152
+ .describe("Maximum total rent (EUR/month)"),
153
+ // Space ranges
154
+ living_space: z.number().optional()
155
+ .describe("Minimum living space (m²)"),
156
+ living_space_to: z.number().optional()
157
+ .describe("Maximum living space (m²)"),
158
+ plot_area: z.number().optional()
159
+ .describe("Minimum plot area (m²)"),
160
+ plot_area_to: z.number().optional()
161
+ .describe("Maximum plot area (m²)"),
162
+ // Room ranges
163
+ number_of_rooms: z.number().optional()
164
+ .describe("Minimum number of rooms"),
165
+ number_of_rooms_to: z.number().optional()
166
+ .describe("Maximum number of rooms"),
167
+ number_of_bed_rooms: z.number().optional()
168
+ .describe("Minimum number of bedrooms"),
169
+ number_of_bed_rooms_to: z.number().optional()
170
+ .describe("Maximum number of bedrooms"),
171
+ // Other ranges
172
+ floor: z.number().optional()
173
+ .describe("Minimum floor"),
174
+ floor_to: z.number().optional()
175
+ .describe("Maximum floor"),
176
+ construction_year: z.number().optional()
177
+ .describe("Minimum construction year"),
178
+ construction_year_to: z.number().optional()
179
+ .describe("Maximum construction year"),
180
+ // Feature booleans — API accepts string "true"/"false" or empty
181
+ lift: z.string().optional()
182
+ .describe("Lift/elevator required: 'true', 'false', or omit for any"),
183
+ balcony: z.string().optional()
184
+ .describe("Balcony required: 'true', 'false', or omit for any"),
185
+ garden: z.string().optional()
186
+ .describe("Garden required: 'true', 'false', or omit for any"),
187
+ built_in_kitchen: z.string().optional()
188
+ .describe("Built-in kitchen required: 'true', 'false', or omit for any"),
189
+ cellar: z.string().optional()
190
+ .describe("Cellar required: 'true', 'false', or omit for any"),
191
+ rented: z.string().optional()
192
+ .describe("Currently rented: 'true', 'false', or omit for any"),
193
+ // Investment criteria
194
+ price_per_sqm: z.number().optional()
195
+ .describe("Minimum price per m² (EUR)"),
196
+ price_per_sqm_to: z.number().optional()
197
+ .describe("Maximum price per m² (EUR)"),
198
+ price_multiplier: z.number().optional()
199
+ .describe("Minimum price multiplier (Vervielfältiger)"),
200
+ price_multiplier_to: z.number().optional()
201
+ .describe("Maximum price multiplier"),
202
+ yield_actual: z.number().optional()
203
+ .describe("Minimum actual yield (%)"),
204
+ yield_actual_to: z.number().optional()
205
+ .describe("Maximum actual yield (%)"),
206
+ // Tags & notes
207
+ group_ids: z.array(z.number()).optional()
208
+ .describe("Tag/group IDs to assign"),
209
+ note: z.string().optional()
210
+ .describe("Free-text note about this search profile"),
211
+ };
212
+ }
213
+ // ── Tool registration ────────────────────────────────────────────────
214
+ export function registerSearchProfileTools(server, client) {
215
+ // ── list_search_profiles ────────────────────────────────────────
216
+ server.tool("list_search_profiles", `List search profiles (Suchprofile) in Propstack.
217
+
218
+ A search profile captures what a buyer or renter is looking for — cities,
219
+ price range, room count, features, etc. Every search profile belongs to
220
+ a contact.
221
+
222
+ Use this tool to:
223
+ - See what a specific contact is looking for (filter by client)
224
+ - List all active search profiles
225
+ - Review criteria before matching properties
226
+
227
+ Filter by contact ID to answer "What is this buyer looking for?"`, {
228
+ client: z.number().optional()
229
+ .describe("Contact ID — show only this contact's search profiles"),
230
+ page: z.number().optional()
231
+ .describe("Page number (default: 1)"),
232
+ per_page: z.number().optional()
233
+ .describe("Results per page (default: 25)"),
234
+ }, async (args) => {
235
+ try {
236
+ const res = await client.get("/saved_queries", { params: args });
237
+ if (!res.data || res.data.length === 0) {
238
+ return textResult("No search profiles found.");
239
+ }
240
+ const header = res.meta?.total_count !== undefined
241
+ ? `Found ${res.meta.total_count} search profiles (showing ${res.data.length}):\n\n`
242
+ : `Found ${res.data.length} search profiles:\n\n`;
243
+ const formatted = res.data.map(formatSearchProfile).join("\n\n---\n\n");
244
+ return textResult(header + formatted);
245
+ }
246
+ catch (err) {
247
+ return errorResult("Search profile", err);
248
+ }
249
+ });
250
+ // ── create_search_profile ───────────────────────────────────────
251
+ server.tool("create_search_profile", `Create a search profile (Suchprofil) for a contact in Propstack.
252
+
253
+ This is THE killer feature for an AI real estate assistant. When a buyer
254
+ or renter describes what they're looking for in natural language, map it
255
+ to structured search criteria:
256
+
257
+ Example conversation:
258
+ "Herr Weber sucht eine 3-Zimmer-Wohnung in Berlin oder Potsdam,
259
+ Budget 300.000–400.000 €, muss einen Balkon haben"
260
+
261
+ client_id: <Herr Weber's ID>
262
+ marketing_type: "BUY"
263
+ rs_types: ["APARTMENT"]
264
+ cities: ["Berlin", "Potsdam"]
265
+ number_of_rooms: 3, number_of_rooms_to: 3
266
+ price: 300000, price_to: 400000
267
+ balcony: "true"
268
+
269
+ Mapping guide:
270
+ - "Wohnung" / "apartment" → rs_types: ["APARTMENT"]
271
+ - "Haus" / "house" → rs_types: ["HOUSE"]
272
+ - "kaufen" / "buy" → marketing_type: "BUY"
273
+ - "mieten" / "rent" → marketing_type: "RENT"
274
+ - "3 Zimmer" → number_of_rooms: 3, number_of_rooms_to: 3
275
+ - "3-4 Zimmer" → number_of_rooms: 3, number_of_rooms_to: 4
276
+ - "bis 400k" → price_to: 400000
277
+ - "mind. 80m²" → living_space: 80
278
+ - "mit Balkon" → balcony: "true"
279
+ - "mit Aufzug" → lift: "true"
280
+ - "mit Garten" → garden: "true"
281
+ - "mit EBK" → built_in_kitchen: "true"
282
+ - "Neubau" → construction_year: 2020
283
+
284
+ Feature booleans use strings: "true" = required, "false" = excluded,
285
+ omit = don't care.
286
+
287
+ Use radius search (lat/lng/radius) for "within 5km of Alexanderplatz".`, {
288
+ client_id: z.number()
289
+ .describe("Contact ID this search profile belongs to (required)"),
290
+ ...searchProfileFields(),
291
+ }, async (args) => {
292
+ try {
293
+ const profile = await client.post("/saved_queries", { body: { saved_query: stripUndefined(args) } });
294
+ return textResult(`Search profile created successfully.\n\n${formatSearchProfile(profile)}`);
295
+ }
296
+ catch (err) {
297
+ return errorResult("Search profile", err);
298
+ }
299
+ });
300
+ // ── update_search_profile ───────────────────────────────────────
301
+ server.tool("update_search_profile", `Update an existing search profile in Propstack.
302
+
303
+ Use this tool to:
304
+ - Expand or narrow budget ("increase max price to 450k")
305
+ - Add or change cities ("also look in Potsdam")
306
+ - Adjust room count or space requirements
307
+ - Toggle feature requirements (add/remove balcony, lift, etc.)
308
+ - Activate or deactivate the profile
309
+
310
+ Only provide the fields you want to change.`, {
311
+ id: z.number()
312
+ .describe("Search profile ID to update"),
313
+ client_id: z.number().optional()
314
+ .describe("Contact ID (rarely changed)"),
315
+ ...searchProfileFields(),
316
+ }, async (args) => {
317
+ try {
318
+ const { id, ...fields } = args;
319
+ const profile = await client.put(`/saved_queries/${id}`, { body: { saved_query: stripUndefined(fields) } });
320
+ return textResult(`Search profile updated successfully.\n\n${formatSearchProfile(profile)}`);
321
+ }
322
+ catch (err) {
323
+ return errorResult("Search profile", err);
324
+ }
325
+ });
326
+ // ── delete_search_profile ───────────────────────────────────────
327
+ server.tool("delete_search_profile", `Delete a search profile from Propstack.
328
+
329
+ Use this tool when:
330
+ - A contact has found a property and is no longer searching
331
+ - The search profile was created in error
332
+ - A contact explicitly asks to stop receiving matching notifications`, {
333
+ id: z.number()
334
+ .describe("Search profile ID to delete"),
335
+ }, async (args) => {
336
+ try {
337
+ await client.delete(`/saved_queries/${args.id}`);
338
+ return textResult(`Search profile ${args.id} deleted.`);
339
+ }
340
+ catch (err) {
341
+ return errorResult("Search profile", err);
342
+ }
343
+ });
344
+ }
345
+ //# sourceMappingURL=search-profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-profiles.js","sourceRoot":"","sources":["../../src/tools/search-profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { PropstackClient } from "../propstack-client.js";
3
+ export declare function registerTaskTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA4E9D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA6NlF"}
@@ -0,0 +1,251 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult, fmt, stripUndefined } from "./helpers.js";
3
+ // ── Response formatting ──────────────────────────────────────────────
4
+ function taskMode(t) {
5
+ if (t.reservation_reason_id)
6
+ return "Cancellation (Absage)";
7
+ if (t.is_event)
8
+ return "Appointment (Termin)";
9
+ if (t.is_reminder)
10
+ return "To-do (Aufgabe)";
11
+ return "Note (Notiz)";
12
+ }
13
+ function formatTask(t) {
14
+ const lines = [
15
+ `**${fmt(t.title, "Untitled")}** (ID: ${t.id})`,
16
+ `Type: ${taskMode(t)}`,
17
+ fmt(t.body, "") ? `Body: ${fmt(t.body)}` : null,
18
+ `Broker: ${fmt(t.broker_id, "unassigned")}`,
19
+ ];
20
+ // To-do fields
21
+ if (t.is_reminder) {
22
+ lines.push(`Due: ${fmt(t.due_date, "no date")}`);
23
+ lines.push(`Remind at: ${fmt(t.remind_at, "none")}`);
24
+ lines.push(`Done: ${t.done ? "yes" : "no"}`);
25
+ }
26
+ // Event fields
27
+ if (t.is_event) {
28
+ lines.push(`Starts: ${fmt(t.starts_at)}`);
29
+ lines.push(`Ends: ${fmt(t.ends_at)}`);
30
+ lines.push(fmt(t.location, "") ? `Location: ${fmt(t.location)}` : null);
31
+ lines.push(t.all_day ? `All day: yes` : null);
32
+ lines.push(t.private ? `Private: yes` : null);
33
+ lines.push(t.recurring ? `Recurring: yes (${fmt(t.rrule)})` : null);
34
+ }
35
+ // Cancellation
36
+ if (t.reservation_reason_id) {
37
+ lines.push(`Reason ID: ${t.reservation_reason_id}`);
38
+ }
39
+ // State
40
+ if (t.state) {
41
+ lines.push(`State: ${t.state}`);
42
+ }
43
+ // Linked entities
44
+ if (t.client_ids?.length)
45
+ lines.push(`Contact IDs: ${t.client_ids.join(", ")}`);
46
+ if (t.property_ids?.length)
47
+ lines.push(`Property IDs: ${t.property_ids.join(", ")}`);
48
+ if (t.project_ids?.length)
49
+ lines.push(`Project IDs: ${t.project_ids.join(", ")}`);
50
+ // Include-expanded relations
51
+ if (t.clients?.length) {
52
+ const names = t.clients.map((c) => `${fmt(c.name) !== "none" ? fmt(c.name) : [fmt(c.first_name, ""), fmt(c.last_name, "")].filter(Boolean).join(" ") || "Unnamed"} (${c.id})`);
53
+ lines.push(`Contacts: ${names.join(", ")}`);
54
+ }
55
+ if (t.units?.length) {
56
+ const titles = t.units.map((u) => `${fmt(u.title, "Untitled")} (${u.id})`);
57
+ lines.push(`Properties: ${titles.join(", ")}`);
58
+ }
59
+ if (t.projects?.length) {
60
+ const titles = t.projects.map((p) => `${fmt(p.title ?? p.name, "Untitled")} (${p.id})`);
61
+ lines.push(`Projects: ${titles.join(", ")}`);
62
+ }
63
+ // Timestamps
64
+ lines.push(`Created: ${fmt(t.created_at)}`);
65
+ lines.push(`Updated: ${fmt(t.updated_at)}`);
66
+ return lines.filter(Boolean).join("\n");
67
+ }
68
+ // ── Tool registration ────────────────────────────────────────────────
69
+ export function registerTaskTools(server, client) {
70
+ // ── create_task ─────────────────────────────────────────────────
71
+ server.tool("create_task", `Create a task (note, to-do, appointment, or cancellation) in Propstack.
72
+
73
+ This is the central write endpoint for ALL activity types. The mode is
74
+ determined by which flags you set:
75
+
76
+ MODE 1 — Note (Notiz):
77
+ Just provide title + body. No special flags needed.
78
+ Example: log a call note after a conversation.
79
+
80
+ MODE 2 — To-do (Aufgabe):
81
+ Set is_reminder: true + due_date.
82
+ Example: "remind me to call Herr Müller back tomorrow"
83
+
84
+ MODE 3 — Appointment (Termin):
85
+ Set is_event: true + starts_at + ends_at.
86
+ Example: "schedule a viewing at Musterstr 12 at 3pm"
87
+
88
+ MODE 4 — Cancellation (Absage):
89
+ Set reservation_reason_id to a valid reason.
90
+ Example: "cancel deal — buyer withdrew financing"
91
+
92
+ Always link tasks to contacts/properties/projects via the *_ids arrays
93
+ so they appear in the correct activity feeds.
94
+
95
+ The body field accepts HTML content.`, {
96
+ title: z.string()
97
+ .describe("Task title / subject line"),
98
+ body: z.string().optional()
99
+ .describe("Task body (HTML allowed). Call notes, meeting minutes, etc."),
100
+ note_type_id: z.number().optional()
101
+ .describe("Activity type ID (e.g. for note, brief, SMS subtypes)"),
102
+ broker_id: z.number().optional()
103
+ .describe("ID of the assigned broker/agent"),
104
+ // Linked entities
105
+ client_ids: z.array(z.number()).optional()
106
+ .describe("Contact IDs to link this task to"),
107
+ property_ids: z.array(z.number()).optional()
108
+ .describe("Property IDs to link this task to"),
109
+ project_ids: z.array(z.number()).optional()
110
+ .describe("Project IDs to link this task to"),
111
+ // To-do (Aufgabe) fields
112
+ is_reminder: z.boolean().optional()
113
+ .describe("Set true to create a To-do/Aufgabe (MODE 2)"),
114
+ due_date: z.string().optional()
115
+ .describe("Due date for to-do (ISO 8601). Requires is_reminder: true"),
116
+ remind_at: z.string().optional()
117
+ .describe("Reminder notification time (ISO 8601). Requires is_reminder: true"),
118
+ done: z.boolean().optional()
119
+ .describe("Mark to-do as completed (default: false)"),
120
+ // Appointment (Termin) fields
121
+ is_event: z.boolean().optional()
122
+ .describe("Set true to create an Appointment/Termin (MODE 3)"),
123
+ starts_at: z.string().optional()
124
+ .describe("Event start time (ISO 8601). Requires is_event: true"),
125
+ ends_at: z.string().optional()
126
+ .describe("Event end time (ISO 8601). Requires is_event: true"),
127
+ location: z.string().optional()
128
+ .describe("Event location (address or description)"),
129
+ all_day: z.boolean().optional()
130
+ .describe("All-day event flag"),
131
+ private: z.boolean().optional()
132
+ .describe("Private event — hidden from other brokers"),
133
+ recurring: z.boolean().optional()
134
+ .describe("Recurring event flag"),
135
+ rrule: z.string().optional()
136
+ .describe("iCal RRULE for recurring events (e.g. 'FREQ=WEEKLY;COUNT=4')"),
137
+ // Cancellation (Absage) fields
138
+ reservation_reason_id: z.number().optional()
139
+ .describe("Cancellation reason ID — setting this activates MODE 4 (Absage)"),
140
+ // State
141
+ state: z.string().optional()
142
+ .describe("Event state (e.g. 'neutral', 'took_place', 'cancelled')"),
143
+ }, async (args) => {
144
+ try {
145
+ const task = await client.post("/tasks", { body: { task: stripUndefined(args) } });
146
+ return textResult(`Task created successfully.\n\n${formatTask(task)}`);
147
+ }
148
+ catch (err) {
149
+ return errorResult("Task", err);
150
+ }
151
+ });
152
+ // ── update_task ─────────────────────────────────────────────────
153
+ server.tool("update_task", `Update an existing task in Propstack.
154
+
155
+ Use this tool to:
156
+ - Mark a to-do as done
157
+ - Reschedule an appointment (change starts_at/ends_at)
158
+ - Add notes to an existing task (update body)
159
+ - Change broker assignment
160
+ - Update event state (took_place, cancelled)
161
+ - Link additional contacts or properties
162
+
163
+ Only provide the fields you want to change.`, {
164
+ id: z.number()
165
+ .describe("Task ID to update"),
166
+ title: z.string().optional()
167
+ .describe("Task title / subject line"),
168
+ body: z.string().optional()
169
+ .describe("Task body (HTML allowed)"),
170
+ note_type_id: z.number().optional()
171
+ .describe("Activity type ID"),
172
+ broker_id: z.number().optional()
173
+ .describe("ID of the assigned broker/agent"),
174
+ // Linked entities
175
+ client_ids: z.array(z.number()).optional()
176
+ .describe("Contact IDs to link this task to"),
177
+ property_ids: z.array(z.number()).optional()
178
+ .describe("Property IDs to link this task to"),
179
+ project_ids: z.array(z.number()).optional()
180
+ .describe("Project IDs to link this task to"),
181
+ // To-do fields
182
+ is_reminder: z.boolean().optional()
183
+ .describe("To-do flag"),
184
+ due_date: z.string().optional()
185
+ .describe("Due date (ISO 8601)"),
186
+ remind_at: z.string().optional()
187
+ .describe("Reminder notification time (ISO 8601)"),
188
+ done: z.boolean().optional()
189
+ .describe("Mark to-do as completed"),
190
+ // Appointment fields
191
+ is_event: z.boolean().optional()
192
+ .describe("Appointment flag"),
193
+ starts_at: z.string().optional()
194
+ .describe("Event start time (ISO 8601)"),
195
+ ends_at: z.string().optional()
196
+ .describe("Event end time (ISO 8601)"),
197
+ location: z.string().optional()
198
+ .describe("Event location"),
199
+ all_day: z.boolean().optional()
200
+ .describe("All-day event flag"),
201
+ private: z.boolean().optional()
202
+ .describe("Private event flag"),
203
+ recurring: z.boolean().optional()
204
+ .describe("Recurring event flag"),
205
+ rrule: z.string().optional()
206
+ .describe("iCal RRULE for recurring events"),
207
+ // Cancellation
208
+ reservation_reason_id: z.number().optional()
209
+ .describe("Cancellation reason ID"),
210
+ // State
211
+ state: z.string().optional()
212
+ .describe("Event state (e.g. 'neutral', 'took_place', 'cancelled')"),
213
+ }, async (args) => {
214
+ try {
215
+ const { id, ...fields } = args;
216
+ const task = await client.put(`/tasks/${id}`, { body: { task: stripUndefined(fields) } });
217
+ return textResult(`Task updated successfully.\n\n${formatTask(task)}`);
218
+ }
219
+ catch (err) {
220
+ return errorResult("Task", err);
221
+ }
222
+ });
223
+ // ── get_task ────────────────────────────────────────────────────
224
+ server.tool("get_task", `Get full details of a single task by ID.
225
+
226
+ Returns the task with all linked entities expanded (contacts, properties,
227
+ projects, viewings) by default.
228
+
229
+ Use this tool to:
230
+ - View full context of an activity before acting on it
231
+ - Check linked contacts and properties
232
+ - See appointment details (time, location, state)
233
+ - Check if a to-do has been completed`, {
234
+ id: z.number()
235
+ .describe("Task ID"),
236
+ include: z.string().optional()
237
+ .describe("Comma-separated related data to include (default: 'clients,units,projects,viewings')"),
238
+ }, async (args) => {
239
+ try {
240
+ const params = {
241
+ include: args.include ?? "clients,units,projects,viewings",
242
+ };
243
+ const task = await client.get(`/tasks/${args.id}`, { params });
244
+ return textResult(formatTask(task));
245
+ }
246
+ catch (err) {
247
+ return errorResult("Task", err);
248
+ }
249
+ });
250
+ }
251
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/tools/tasks.ts"],"names":[],"mappings":"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"}