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 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/tools/projects.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 registerPropertyTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=properties.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"properties.d.ts","sourceRoot":"","sources":["../../src/tools/properties.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA2E9D,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAoYtF"}
@@ -0,0 +1,397 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult, fmt, fmtPrice, fmtArea, stripUndefined } from "./helpers.js";
3
+ // ── Response formatting ──────────────────────────────────────────────
4
+ function formatProperty(p) {
5
+ const title = fmt(p.title, "Untitled");
6
+ const marketingType = fmt(p.marketing_type);
7
+ const rsType = fmt(p.rs_type);
8
+ const rsCategory = fmt(p.rs_category, "");
9
+ const address = [fmt(p.street, ""), fmt(p.house_number, "")].filter(Boolean).join(" ");
10
+ const cityLine = [fmt(p.zip_code, ""), fmt(p.city, "")].filter(Boolean).join(" ");
11
+ const fullAddress = [address, cityLine, fmt(p.country, "")].filter(Boolean).join(", ");
12
+ const lines = [
13
+ `**${title}** (ID: ${p.id})`,
14
+ `Type: ${marketingType} / ${rsType}${rsCategory ? ` / ${rsCategory}` : ""}`,
15
+ `Address: ${fullAddress || "none"}`,
16
+ marketingType === "BUY" || p.price ? `Price: ${fmtPrice(p.price)}` : null,
17
+ marketingType === "RENT" || p.base_rent ? `Base rent: ${fmtPrice(p.base_rent)}` : null,
18
+ p.total_rent ? `Total rent: ${fmtPrice(p.total_rent)}` : null,
19
+ `Living space: ${fmtArea(p.living_space)}`,
20
+ p.plot_area ? `Plot area: ${fmtArea(p.plot_area)}` : null,
21
+ `Rooms: ${fmt(p.number_of_rooms)}`,
22
+ p.number_of_bed_rooms ? `Bedrooms: ${fmt(p.number_of_bed_rooms)}` : null,
23
+ p.number_of_bath_rooms ? `Bathrooms: ${fmt(p.number_of_bath_rooms)}` : null,
24
+ p.floor !== undefined && p.floor !== null ? `Floor: ${fmt(p.floor)}` : null,
25
+ p.construction_year ? `Built: ${fmt(p.construction_year)}` : null,
26
+ `Status: ${fmt(p.property_status?.name)}`,
27
+ `Broker: ${fmt(p.broker?.name, "unassigned")}`,
28
+ p.project ? `Project: ${fmt(p.project.name)}` : null,
29
+ p.exposee_id ? `Exposé ID: ${p.exposee_id}` : null,
30
+ ];
31
+ return lines.filter(Boolean).join("\n");
32
+ }
33
+ function formatPropertyRow(p) {
34
+ const addr = [fmt(p.street, ""), fmt(p.house_number, "")].filter(Boolean).join(" ");
35
+ const city = [fmt(p.zip_code, ""), fmt(p.city, "")].filter(Boolean).join(" ");
36
+ const location = [addr, city].filter(Boolean).join(", ") || "—";
37
+ const price = fmtPrice(p.price) !== "none"
38
+ ? fmtPrice(p.price)
39
+ : fmtPrice(p.base_rent) !== "none"
40
+ ? fmtPrice(p.base_rent) + "/mo"
41
+ : "—";
42
+ const size = fmtArea(p.living_space) !== "none" ? fmtArea(p.living_space) : "—";
43
+ const rooms = fmt(p.number_of_rooms) !== "none" ? `${fmt(p.number_of_rooms)}R` : "—";
44
+ const status = fmt(p.property_status?.name, "—");
45
+ const type = [fmt(p.marketing_type, ""), fmt(p.rs_type, "")].filter(Boolean).join("/");
46
+ return `| ${p.id} | ${fmt(p.title, "—")} | ${type} | ${location} | ${price} | ${size} | ${rooms} | ${status} |`;
47
+ }
48
+ // ── Shared enums ─────────────────────────────────────────────────────
49
+ const RS_TYPES = [
50
+ "APARTMENT", "HOUSE", "TRADE_SITE", "GARAGE",
51
+ "SHORT_TERM_ACCOMODATION", "OFFICE", "GASTRONOMY",
52
+ "INDUSTRY", "STORE", "SPECIAL_PURPOSE", "INVESTMENT",
53
+ ];
54
+ const OBJECT_TYPES = ["LIVING", "COMMERCIAL", "INVESTMENT"];
55
+ const SEARCH_SORT_FIELDS = [
56
+ "exposee_id", "construction_year", "unit_id.raw", "floor",
57
+ "created_at", "property_space_value", "plot_area", "base_rent",
58
+ "price", "object_price", "price_per_sqm", "property_status_position",
59
+ "street_number.raw", "sold_date", "total_rent", "number_of_rooms",
60
+ "updated_at",
61
+ ];
62
+ // ── Tool registration ────────────────────────────────────────────────
63
+ export function registerPropertyTools(server, client) {
64
+ // ── search_properties ────────────────────────────────────────────
65
+ server.tool("search_properties", `Search and filter properties (Objekte) in Propstack CRM.
66
+
67
+ Use this tool to:
68
+ - Find properties by address, ID, or exposé ID (use 'q' for fulltext)
69
+ - Filter by status, type, marketing type, or project
70
+ - Find properties in a price/rent range
71
+ - List properties by size, rooms, or construction year
72
+ - Filter by custom fields with cf_ prefix parameters
73
+
74
+ The 'q' parameter searches: unit_id, street, zip code, city, district, exposé ID.
75
+
76
+ Range filter pattern: 11 numeric fields each have _from and _to variants.
77
+ For example, price_from=200000 & price_to=400000 finds properties priced 200–400k.
78
+ Available range fields: price, base_rent, total_rent, property_space_value,
79
+ living_space, plot_area, number_of_rooms, number_of_bed_rooms,
80
+ number_of_bath_rooms, floor, construction_year.
81
+
82
+ Common queries:
83
+ - "Apartments 300–400k in Berlin": q="Berlin", marketing_type=BUY, rs_type=APARTMENT, price_from=300000, price_to=400000
84
+ - "All available rentals": marketing_type=RENT, status=<available_id from get_property_statuses>
85
+ - "Properties on market 90+ days": sort_by=created_at, order=asc
86
+ - "What's in Project X?": project_id=<id>
87
+
88
+ Always returns total count. Use expand=true for custom fields.`, {
89
+ q: z.string().optional()
90
+ .describe("Fulltext search across unit_id, street, zip, city, district, exposé ID"),
91
+ status: z.string().optional()
92
+ .describe("Comma-separated property status IDs (use get_property_statuses to look up)"),
93
+ marketing_type: z.enum(["BUY", "RENT"]).optional()
94
+ .describe("Filter by marketing type: BUY (Kauf) or RENT (Miete)"),
95
+ rs_type: z.enum(RS_TYPES).optional()
96
+ .describe("Property type filter"),
97
+ object_type: z.enum(OBJECT_TYPES).optional()
98
+ .describe("Object category: LIVING (Wohnen), COMMERCIAL (Gewerbe), INVESTMENT (Anlage)"),
99
+ country: z.string().optional()
100
+ .describe("Filter by country code (e.g. 'DE')"),
101
+ project_id: z.number().optional()
102
+ .describe("Filter by project ID"),
103
+ group: z.number().optional()
104
+ .describe("Filter by tag/group ID (Merkmal)"),
105
+ archived: z.string().optional()
106
+ .describe("Archive filter: '-1' = all (including archived), '1' = archived only. Omit for non-archived only (default)."),
107
+ property_ids: z.array(z.number()).optional()
108
+ .describe("Filter to specific property IDs"),
109
+ include_variants: z.boolean().optional()
110
+ .describe("Include property variants"),
111
+ exact: z.boolean().optional()
112
+ .describe("Use exact matching for text search"),
113
+ // Range filters
114
+ price_from: z.number().optional().describe("Minimum purchase price (EUR)"),
115
+ price_to: z.number().optional().describe("Maximum purchase price (EUR)"),
116
+ base_rent_from: z.number().optional().describe("Minimum base rent (EUR/month)"),
117
+ base_rent_to: z.number().optional().describe("Maximum base rent (EUR/month)"),
118
+ total_rent_from: z.number().optional().describe("Minimum total rent (EUR/month)"),
119
+ total_rent_to: z.number().optional().describe("Maximum total rent (EUR/month)"),
120
+ property_space_value_from: z.number().optional().describe("Minimum property space (m²)"),
121
+ property_space_value_to: z.number().optional().describe("Maximum property space (m²)"),
122
+ living_space_from: z.number().optional().describe("Minimum living space (m²)"),
123
+ living_space_to: z.number().optional().describe("Maximum living space (m²)"),
124
+ plot_area_from: z.number().optional().describe("Minimum plot area (m²)"),
125
+ plot_area_to: z.number().optional().describe("Maximum plot area (m²)"),
126
+ number_of_rooms_from: z.number().optional().describe("Minimum number of rooms"),
127
+ number_of_rooms_to: z.number().optional().describe("Maximum number of rooms"),
128
+ number_of_bed_rooms_from: z.number().optional().describe("Minimum bedrooms"),
129
+ number_of_bed_rooms_to: z.number().optional().describe("Maximum bedrooms"),
130
+ number_of_bath_rooms_from: z.number().optional().describe("Minimum bathrooms"),
131
+ number_of_bath_rooms_to: z.number().optional().describe("Maximum bathrooms"),
132
+ floor_from: z.number().optional().describe("Minimum floor"),
133
+ floor_to: z.number().optional().describe("Maximum floor"),
134
+ construction_year_from: z.number().optional().describe("Built after this year"),
135
+ construction_year_to: z.number().optional().describe("Built before this year"),
136
+ // Sorting & pagination
137
+ sort_by: z.enum(SEARCH_SORT_FIELDS).optional()
138
+ .describe("Field to sort results by (default: unit_id)"),
139
+ order: z.enum(["asc", "desc"]).optional()
140
+ .describe("Sort order (default: desc)"),
141
+ expand: z.boolean().optional()
142
+ .describe("Include full details and custom fields"),
143
+ page: z.number().optional()
144
+ .describe("Page number (default: 1)"),
145
+ per_page: z.number().optional()
146
+ .describe("Results per page (default: 25)"),
147
+ }, async (args) => {
148
+ try {
149
+ const params = {
150
+ with_meta: 1,
151
+ ...args,
152
+ };
153
+ const res = await client.get("/units", { params });
154
+ if (!res.data || res.data.length === 0) {
155
+ return textResult("No properties found matching your criteria.");
156
+ }
157
+ const total = res.meta?.total_count;
158
+ const header = total !== undefined
159
+ ? `Found ${total} properties (showing ${res.data.length}):\n\n`
160
+ : `Found ${res.data.length} properties:\n\n`;
161
+ const tableHeader = "| ID | Title | Type | Address | Price | Size | Rooms | Status |\n| --- | --- | --- | --- | --- | --- | --- | --- |";
162
+ const rows = res.data.map(formatPropertyRow).join("\n");
163
+ return textResult(header + tableHeader + "\n" + rows);
164
+ }
165
+ catch (err) {
166
+ return errorResult("Property", err);
167
+ }
168
+ });
169
+ // ── get_property ─────────────────────────────────────────────────
170
+ server.tool("get_property", `Get full details of a single property by ID.
171
+
172
+ Use this tool to:
173
+ - View complete property information for an exposé
174
+ - Check images, floorplans, documents, and links
175
+ - See custom fields, broker assignment, and project
176
+ - Get multilingual texts (use locale parameter)
177
+
178
+ Always fetches with new=1 (extra fields) and expand=1 (custom fields).`, {
179
+ id: z.number()
180
+ .describe("Property ID"),
181
+ include_translations: z.string().optional()
182
+ .describe("Comma-separated language codes for multilingual texts (e.g. 'en,de'). Omit for default language only."),
183
+ }, async (args) => {
184
+ try {
185
+ const params = {
186
+ new: 1,
187
+ expand: 1,
188
+ };
189
+ if (args.include_translations) {
190
+ params["include_translations"] = args.include_translations;
191
+ }
192
+ const property = await client.get(`/units/${args.id}`, { params });
193
+ let result = formatProperty(property);
194
+ // Append description texts if present (unwrap nested {value} from new=1 API)
195
+ const descriptions = [];
196
+ const desc = fmt(property.description_note, "");
197
+ if (desc)
198
+ descriptions.push(`**Description:** ${desc}`);
199
+ const loc = fmt(property.location_note, "");
200
+ if (loc)
201
+ descriptions.push(`**Location:** ${loc}`);
202
+ const furn = fmt(property.furnishing_note, "");
203
+ if (furn)
204
+ descriptions.push(`**Furnishing:** ${furn}`);
205
+ const other = fmt(property.other_note, "");
206
+ if (other)
207
+ descriptions.push(`**Other:** ${other}`);
208
+ if (descriptions.length > 0) {
209
+ result += "\n\n" + descriptions.join("\n\n");
210
+ }
211
+ // Append images summary
212
+ if (property.images && property.images.length > 0) {
213
+ result += `\n\nImages: ${property.images.length} attached`;
214
+ }
215
+ // Append documents summary
216
+ if (property.documents && property.documents.length > 0) {
217
+ result += `\nDocuments: ${property.documents.length} attached`;
218
+ }
219
+ // Append links
220
+ if (property.links && property.links.length > 0) {
221
+ const linkLines = property.links.map((l) => ` - ${fmt(l.title, "Link")}: ${fmt(l.url)}`);
222
+ result += `\nLinks:\n${linkLines.join("\n")}`;
223
+ }
224
+ // Append custom fields summary
225
+ if (property.custom_fields && Object.keys(property.custom_fields).length > 0) {
226
+ const cfEntries = Object.entries(property.custom_fields)
227
+ .map(([k, v]) => ({ k, s: fmt(v, "") }))
228
+ .filter(({ s }) => s && s !== "none")
229
+ .map(({ k, s }) => ` - ${k}: ${s}`);
230
+ if (cfEntries.length > 0) {
231
+ result += `\n\nCustom fields:\n${cfEntries.join("\n")}`;
232
+ }
233
+ }
234
+ return textResult(result);
235
+ }
236
+ catch (err) {
237
+ return errorResult("Property", err);
238
+ }
239
+ });
240
+ // ── create_property ──────────────────────────────────────────────
241
+ server.tool("create_property", `Create a new property (Objekt) in Propstack CRM.
242
+
243
+ Use this tool to:
244
+ - List a new property from an acquisition call
245
+ - Create a listing from an owner inquiry
246
+ - Add a property to a project
247
+
248
+ Use get_property_statuses to look up valid status IDs.
249
+ Use the relationships_attributes array to link an owner contact on creation.
250
+
251
+ rs_type values: APARTMENT, HOUSE, TRADE_SITE, GARAGE, SHORT_TERM_ACCOMODATION,
252
+ OFFICE, GASTRONOMY, INDUSTRY, STORE, SPECIAL_PURPOSE, INVESTMENT.
253
+
254
+ rs_category provides sub-types (e.g. PENTHOUSE, VILLA, MAISONETTE for APARTMENT/HOUSE).`, {
255
+ title: z.string().optional()
256
+ .describe("Property title / headline"),
257
+ marketing_type: z.enum(["BUY", "RENT"]).optional()
258
+ .describe("Marketing type: BUY (Kauf) or RENT (Miete)"),
259
+ object_type: z.enum(OBJECT_TYPES).optional()
260
+ .describe("Object category: LIVING, COMMERCIAL, or INVESTMENT"),
261
+ rs_type: z.enum(RS_TYPES).optional()
262
+ .describe("Property type (e.g. APARTMENT, HOUSE, OFFICE)"),
263
+ rs_category: z.string().optional()
264
+ .describe("Property sub-type (e.g. PENTHOUSE, VILLA, MAISONETTE, SINGLE_FAMILY_HOUSE)"),
265
+ // Address
266
+ street: z.string().optional().describe("Street name"),
267
+ house_number: z.string().optional().describe("House number"),
268
+ zip_code: z.string().optional().describe("Postal code"),
269
+ city: z.string().optional().describe("City"),
270
+ country: z.string().optional().describe("Country code (e.g. 'DE')"),
271
+ lat: z.number().optional().describe("Latitude"),
272
+ lng: z.number().optional().describe("Longitude"),
273
+ // Pricing
274
+ price: z.number().optional().describe("Purchase price (EUR)"),
275
+ base_rent: z.number().optional().describe("Base rent (EUR/month)"),
276
+ total_rent: z.number().optional().describe("Total rent including utilities (EUR/month)"),
277
+ // Dimensions
278
+ living_space: z.number().optional().describe("Living space (m²)"),
279
+ plot_area: z.number().optional().describe("Plot area (m²)"),
280
+ number_of_rooms: z.number().optional().describe("Number of rooms"),
281
+ number_of_bed_rooms: z.number().optional().describe("Number of bedrooms"),
282
+ number_of_bath_rooms: z.number().optional().describe("Number of bathrooms"),
283
+ floor: z.number().optional().describe("Floor number"),
284
+ construction_year: z.number().optional().describe("Year of construction"),
285
+ // Texts
286
+ description_note: z.string().optional().describe("Property description text (HTML allowed)"),
287
+ location_note: z.string().optional().describe("Location description text"),
288
+ furnishing_note: z.string().optional().describe("Furnishing/equipment description text"),
289
+ other_note: z.string().optional().describe("Additional notes text"),
290
+ // Commission
291
+ courtage: z.string().optional().describe("Commission amount or percentage"),
292
+ courtage_note: z.string().optional().describe("Commission details/notes"),
293
+ // Assignment
294
+ broker_id: z.number().optional().describe("Assigned broker ID"),
295
+ project_id: z.number().optional().describe("Project ID this property belongs to"),
296
+ status: z.number().optional().describe("Property status ID (use get_property_statuses to look up)"),
297
+ // Custom fields & relationships
298
+ partial_custom_fields: z.record(z.string(), z.unknown()).optional()
299
+ .describe("Custom field values as key-value pairs"),
300
+ relationships_attributes: z.array(z.object({
301
+ internal_name: z.string().describe('Relationship type (e.g. "owner")'),
302
+ related_client_id: z.number().describe("Contact ID to link"),
303
+ })).optional()
304
+ .describe('Link contacts on creation, e.g. [{internal_name: "owner", related_client_id: 123}]'),
305
+ }, async (args) => {
306
+ try {
307
+ const property = await client.post("/units", { body: { property: stripUndefined(args) } });
308
+ return textResult(`Property created successfully.\n\n${formatProperty(property)}`);
309
+ }
310
+ catch (err) {
311
+ return errorResult("Property", err);
312
+ }
313
+ });
314
+ // ── update_property ──────────────────────────────────────────────
315
+ server.tool("update_property", `Update an existing property in Propstack CRM.
316
+
317
+ Use this tool to:
318
+ - Update the price or rent
319
+ - Change property status (e.g. mark as reserved or sold)
320
+ - Edit description texts
321
+ - Assign to a different broker or project
322
+ - Update custom fields
323
+
324
+ Only provide the fields you want to change.
325
+ Use get_property_statuses to look up valid status IDs.`, {
326
+ id: z.number()
327
+ .describe("Property ID to update"),
328
+ title: z.string().optional().describe("Property title / headline"),
329
+ marketing_type: z.enum(["BUY", "RENT"]).optional().describe("Marketing type: BUY or RENT"),
330
+ object_type: z.enum(OBJECT_TYPES).optional().describe("Object category"),
331
+ rs_type: z.enum(RS_TYPES).optional().describe("Property type"),
332
+ rs_category: z.string().optional().describe("Property sub-type"),
333
+ street: z.string().optional().describe("Street name"),
334
+ house_number: z.string().optional().describe("House number"),
335
+ zip_code: z.string().optional().describe("Postal code"),
336
+ city: z.string().optional().describe("City"),
337
+ country: z.string().optional().describe("Country code"),
338
+ lat: z.number().optional().describe("Latitude"),
339
+ lng: z.number().optional().describe("Longitude"),
340
+ price: z.number().optional().describe("Purchase price (EUR)"),
341
+ base_rent: z.number().optional().describe("Base rent (EUR/month)"),
342
+ total_rent: z.number().optional().describe("Total rent (EUR/month)"),
343
+ living_space: z.number().optional().describe("Living space (m²)"),
344
+ plot_area: z.number().optional().describe("Plot area (m²)"),
345
+ number_of_rooms: z.number().optional().describe("Number of rooms"),
346
+ number_of_bed_rooms: z.number().optional().describe("Number of bedrooms"),
347
+ number_of_bath_rooms: z.number().optional().describe("Number of bathrooms"),
348
+ floor: z.number().optional().describe("Floor number"),
349
+ construction_year: z.number().optional().describe("Year of construction"),
350
+ description_note: z.string().optional().describe("Property description text"),
351
+ location_note: z.string().optional().describe("Location description text"),
352
+ furnishing_note: z.string().optional().describe("Furnishing description text"),
353
+ other_note: z.string().optional().describe("Additional notes text"),
354
+ courtage: z.string().optional().describe("Commission amount or percentage"),
355
+ courtage_note: z.string().optional().describe("Commission details"),
356
+ broker_id: z.number().optional().describe("Assigned broker ID"),
357
+ project_id: z.number().optional().describe("Project ID"),
358
+ status: z.number().optional().describe("Property status ID (use get_property_statuses)"),
359
+ partial_custom_fields: z.record(z.string(), z.unknown()).optional()
360
+ .describe("Custom field values as key-value pairs"),
361
+ }, async (args) => {
362
+ try {
363
+ const { id, ...fields } = args;
364
+ const property = await client.put(`/units/${id}`, { body: { property: stripUndefined(fields) } });
365
+ return textResult(`Property updated successfully.\n\n${formatProperty(property)}`);
366
+ }
367
+ catch (err) {
368
+ return errorResult("Property", err);
369
+ }
370
+ });
371
+ // ── get_property_statuses ────────────────────────────────────────
372
+ server.tool("get_property_statuses", `List all available property statuses in Propstack.
373
+
374
+ Returns statuses like "Verfügbar", "Reserviert", "Verkauft" with their IDs,
375
+ colors, and sort positions.
376
+
377
+ Use this tool to look up valid status IDs before:
378
+ - Filtering properties by status in search_properties
379
+ - Setting a property's status in create_property or update_property`, {}, async () => {
380
+ try {
381
+ const res = await client.get("/property_statuses");
382
+ const statuses = Array.isArray(res) ? res : (res?.data ?? []);
383
+ if (!statuses || statuses.length === 0) {
384
+ return textResult("No property statuses configured.");
385
+ }
386
+ const lines = statuses.map((s) => {
387
+ const nonpublic = s.nonpublic ? " (non-public)" : "";
388
+ return `- **${s.name}** (ID: ${s.id})${nonpublic}`;
389
+ });
390
+ return textResult(`Property statuses:\n\n${lines.join("\n")}`);
391
+ }
392
+ catch (err) {
393
+ return errorResult("Property status", err);
394
+ }
395
+ });
396
+ }
397
+ //# sourceMappingURL=properties.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"properties.js","sourceRoot":"","sources":["../../src/tools/properties.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 registerRelationshipTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=relationships.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/tools/relationships.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAyE1F"}
@@ -0,0 +1,55 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult } from "./helpers.js";
3
+ // ── Tool registration ────────────────────────────────────────────────
4
+ export function registerRelationshipTools(server, client) {
5
+ // ── create_ownership ────────────────────────────────────────────
6
+ server.tool("create_ownership", `Link a contact as the OWNER (Eigentümer) of a property.
7
+
8
+ Use this tool to:
9
+ - Record property ownership ("Herr Müller owns Hauptstraße 12")
10
+ - Set up owner relationships for acquisition properties
11
+ - Link sellers to their properties
12
+
13
+ The ownership appears on both the contact's and the property's record.`, {
14
+ client_id: z.number()
15
+ .describe("Contact ID (the owner)"),
16
+ property_id: z.number()
17
+ .describe("Property ID (the owned property)"),
18
+ }, async (args) => {
19
+ try {
20
+ const rel = await client.post("/ownerships", { body: args });
21
+ return textResult(`Ownership created (ID: ${rel.id}).\n` +
22
+ `Contact ${rel.client_id} is now owner of property ${rel.property_id}.`);
23
+ }
24
+ catch (err) {
25
+ return errorResult("Ownership", err);
26
+ }
27
+ });
28
+ // ── create_partnership ──────────────────────────────────────────
29
+ server.tool("create_partnership", `Link a contact as a PARTNER (buyer, tenant, etc.) to a property.
30
+
31
+ Use this tool to:
32
+ - Link a buyer to a property ("Frau Schmidt is the buyer of Hauptstraße 12")
33
+ - Link a tenant to a rental property
34
+ - Create any named contact↔property relationship
35
+
36
+ The name field describes the role (e.g. "Käufer", "Mieter", "Verwalter").`, {
37
+ client_id: z.number()
38
+ .describe("Contact ID (the partner)"),
39
+ property_id: z.number()
40
+ .describe("Property ID"),
41
+ name: z.string().optional()
42
+ .describe("Role name (e.g. 'Käufer', 'Mieter', 'Verwalter')"),
43
+ }, async (args) => {
44
+ try {
45
+ const rel = await client.post("/partnerships", { body: args });
46
+ const role = rel.name ? ` as "${rel.name}"` : "";
47
+ return textResult(`Partnership created (ID: ${rel.id}).\n` +
48
+ `Contact ${rel.client_id} linked to property ${rel.property_id}${role}.`);
49
+ }
50
+ catch (err) {
51
+ return errorResult("Partnership", err);
52
+ }
53
+ });
54
+ }
55
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/tools/relationships.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEvD,wEAAwE;AAExE,MAAM,UAAU,yBAAyB,CAAC,MAAiB,EAAE,MAAuB;IAClF,mEAAmE;IAEnE,MAAM,CAAC,IAAI,CACT,kBAAkB,EAClB;;;;;;;uEAOmE,EACnE;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;aAClB,QAAQ,CAAC,wBAAwB,CAAC;QACrC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;aACpB,QAAQ,CAAC,kCAAkC,CAAC;KAChD,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAC3B,aAAa,EACb,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;YAEF,OAAO,UAAU,CACf,0BAA0B,GAAG,CAAC,EAAE,MAAM;gBACtC,WAAW,GAAG,CAAC,SAAS,6BAA6B,GAAG,CAAC,WAAW,GAAG,CACxE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CACF,CAAC;IAEF,mEAAmE;IAEnE,MAAM,CAAC,IAAI,CACT,oBAAoB,EACpB;;;;;;;0EAOsE,EACtE;QACE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;aAClB,QAAQ,CAAC,0BAA0B,CAAC;QACvC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;aACpB,QAAQ,CAAC,aAAa,CAAC;QAC1B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;aACxB,QAAQ,CAAC,kDAAkD,CAAC;KAChE,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAC3B,eAAe,EACf,EAAE,IAAI,EAAE,IAAI,EAAE,CACf,CAAC;YAEF,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,OAAO,UAAU,CACf,4BAA4B,GAAG,CAAC,EAAE,MAAM;gBACxC,WAAW,GAAG,CAAC,SAAS,uBAAuB,GAAG,CAAC,WAAW,GAAG,IAAI,GAAG,CACzE,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,WAAW,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QACzC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -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 registerSearchProfileTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=search-profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-profiles.d.ts","sourceRoot":"","sources":["../../src/tools/search-profiles.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAkN9D,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CAuK3F"}