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,177 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult, fmt } from "./helpers.js";
3
+ // ── Response formatting ──────────────────────────────────────────────
4
+ /** Resolve activity type — Propstack API uses conversation_type (event, reminder, note, message, etc). */
5
+ function getActivityType(a) {
6
+ const t = fmt(a.conversation_type ?? a.type, "");
7
+ if (t && t !== "none")
8
+ return t;
9
+ const rec = a;
10
+ const uid = String(rec.unique_id ?? "");
11
+ if (uid.startsWith("event-"))
12
+ return "event";
13
+ if (uid.startsWith("reminder-"))
14
+ return "reminder";
15
+ return "—";
16
+ }
17
+ function formatActivity(a) {
18
+ const lines = [
19
+ `**${fmt(a.title, "Untitled")}** (ID: ${a.id})`,
20
+ `Type: ${getActivityType(a)}`,
21
+ fmt(a.body, "") ? `Body: ${fmt(a.body)}` : null,
22
+ a.broker ? `Broker: ${fmt(a.broker.name)}` : (a.broker_id ? `Broker ID: ${a.broker_id}` : null),
23
+ ];
24
+ if (a.client) {
25
+ const name = fmt(a.client.name) !== "none" ? fmt(a.client.name) : [fmt(a.client.first_name, ""), fmt(a.client.last_name, "")].filter(Boolean).join(" ") || "Unnamed";
26
+ lines.push(`Contact: ${name} (ID: ${a.client.id})`);
27
+ }
28
+ else if (a.client_id) {
29
+ lines.push(`Contact ID: ${a.client_id}`);
30
+ }
31
+ if (a.property) {
32
+ lines.push(`Property: ${fmt(a.property.title, "Untitled")} (ID: ${a.property.id})`);
33
+ }
34
+ else if (a.property_id) {
35
+ lines.push(`Property ID: ${a.property_id}`);
36
+ }
37
+ if (a.project_id)
38
+ lines.push(`Project ID: ${a.project_id}`);
39
+ lines.push(`Date: ${fmt(a.created_at)}`);
40
+ return lines.filter(Boolean).join("\n");
41
+ }
42
+ function formatEvent(e) {
43
+ const lines = [
44
+ `**${fmt(e.title, "Untitled")}** (ID: ${e.id})`,
45
+ `Starts: ${fmt(e.starts_at)}`,
46
+ `Ends: ${fmt(e.ends_at)}`,
47
+ `State: ${fmt(e.state)}`,
48
+ fmt(e.location, "") ? `Location: ${fmt(e.location)}` : null,
49
+ e.all_day ? `All day: yes` : null,
50
+ e.private ? `Private: yes` : null,
51
+ e.recurring ? `Recurring: yes (${fmt(e.rrule)})` : null,
52
+ e.broker_id ? `Broker ID: ${e.broker_id}` : null,
53
+ ];
54
+ if (e.client) {
55
+ const name = fmt(e.client.name) !== "none" ? fmt(e.client.name) : [fmt(e.client.first_name, ""), fmt(e.client.last_name, "")].filter(Boolean).join(" ") || "Unnamed";
56
+ lines.push(`Contact: ${name} (ID: ${e.client.id})`);
57
+ }
58
+ if (e.property) {
59
+ lines.push(`Property: ${fmt(e.property.title, "Untitled")} (ID: ${e.property.id})`);
60
+ }
61
+ if (fmt(e.body, ""))
62
+ lines.push(`Notes: ${fmt(e.body)}`);
63
+ return lines.filter(Boolean).join("\n");
64
+ }
65
+ // ── Tool registration ────────────────────────────────────────────────
66
+ export function registerActivityTools(server, client) {
67
+ // ── search_activities ───────────────────────────────────────────
68
+ server.tool("search_activities", `Search the activity feed/timeline in Propstack.
69
+
70
+ Activities are the read-only feed of everything that happened: emails
71
+ sent, notes logged, tasks created, events scheduled, cancellations,
72
+ GDPR policy changes, etc.
73
+
74
+ Use this tool to:
75
+ - View the full interaction history for a contact (client_id)
76
+ - See all activity on a property (property_id)
77
+ - Track what a broker has been doing (broker_id)
78
+ - Filter by activity type to find specific interactions
79
+ - Answer "what happened with this contact/property this week?"
80
+
81
+ Activity types:
82
+ - message: Emails sent/received
83
+ - note: Call notes, comments
84
+ - reminder: To-do items (Aufgaben)
85
+ - event: Appointments (Termine)
86
+ - policy: GDPR consent changes
87
+ - cancelation: Deal cancellations (Absagen)
88
+ - decision: Deal decisions
89
+ - sms: SMS messages
90
+ - letter: Letters (Briefe)
91
+
92
+ Use list_activity_types to see all valid types for this account.`, {
93
+ type: z.enum(["message", "note", "reminder", "event", "policy", "cancelation", "decision", "sms", "letter"]).optional()
94
+ .describe("Filter by activity type"),
95
+ broker_id: z.number().optional()
96
+ .describe("Filter by broker ID"),
97
+ client_id: z.number().optional()
98
+ .describe("Filter by contact ID — show all activity for this contact"),
99
+ property_id: z.number().optional()
100
+ .describe("Filter by property ID — show all activity for this property"),
101
+ project_id: z.number().optional()
102
+ .describe("Filter by project ID"),
103
+ sort_by: z.string().optional()
104
+ .describe("Field to sort by"),
105
+ order: z.enum(["asc", "desc"]).optional()
106
+ .describe("Sort order (default: desc)"),
107
+ page: z.number().optional()
108
+ .describe("Page number (default: 1)"),
109
+ per: z.number().optional()
110
+ .describe("Results per page (default: 20)"),
111
+ }, async (args) => {
112
+ try {
113
+ const res = await client.get("/activities", { params: args });
114
+ if (!res.data || res.data.length === 0) {
115
+ return textResult("No activities found matching your criteria.");
116
+ }
117
+ const header = res.meta?.total_count !== undefined
118
+ ? `Found ${res.meta.total_count} activities (showing ${res.data.length}):\n\n`
119
+ : `Found ${res.data.length} activities:\n\n`;
120
+ const formatted = res.data.map(formatActivity).join("\n\n---\n\n");
121
+ return textResult(header + formatted);
122
+ }
123
+ catch (err) {
124
+ return errorResult("Activity", err);
125
+ }
126
+ });
127
+ // ── list_events ─────────────────────────────────────────────────
128
+ server.tool("list_events", `List calendar events (Termine) in Propstack.
129
+
130
+ Events are appointments like property viewings, client meetings,
131
+ notary appointments, etc.
132
+
133
+ Use this tool to:
134
+ - See what's scheduled this week (starts_at_from/to)
135
+ - List upcoming viewings for a broker
136
+ - Find cancelled appointments (state="cancelled")
137
+ - Check recurring events
138
+ - Answer "what viewings are scheduled this week?"
139
+
140
+ Event states:
141
+ - neutral: Scheduled, not yet happened
142
+ - took_place: Completed
143
+ - cancelled: Was cancelled`, {
144
+ recurring: z.boolean().optional()
145
+ .describe("Filter for recurring events only"),
146
+ state: z.enum(["neutral", "took_place", "cancelled"]).optional()
147
+ .describe("Event state: neutral (scheduled), took_place, cancelled"),
148
+ group_id: z.number().optional()
149
+ .describe("Filter by tag/group ID"),
150
+ broker_id: z.number().optional()
151
+ .describe("Filter by broker ID"),
152
+ starts_at_from: z.string().optional()
153
+ .describe("Events starting after this date/time (ISO 8601)"),
154
+ starts_at_to: z.string().optional()
155
+ .describe("Events starting before this date/time (ISO 8601)"),
156
+ page: z.number().optional()
157
+ .describe("Page number (default: 1)"),
158
+ per_page: z.number().optional()
159
+ .describe("Results per page (default: 25)"),
160
+ }, async (args) => {
161
+ try {
162
+ const res = await client.get("/events", { params: args });
163
+ if (!res.data || res.data.length === 0) {
164
+ return textResult("No events found matching your criteria.");
165
+ }
166
+ const header = res.meta?.total_count !== undefined
167
+ ? `Found ${res.meta.total_count} events (showing ${res.data.length}):\n\n`
168
+ : `Found ${res.data.length} events:\n\n`;
169
+ const formatted = res.data.map(formatEvent).join("\n\n---\n\n");
170
+ return textResult(header + formatted);
171
+ }
172
+ catch (err) {
173
+ return errorResult("Event", err);
174
+ }
175
+ });
176
+ }
177
+ //# sourceMappingURL=activities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.js","sourceRoot":"","sources":["../../src/tools/activities.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 registerAdminTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA6LnF"}
@@ -0,0 +1,148 @@
1
+ import { z } from "zod";
2
+ import { textResult, errorResult, fmt, fmtPrice } from "./helpers.js";
3
+ // ── Tool registration ────────────────────────────────────────────────
4
+ export function registerAdminTools(server, client) {
5
+ // ── list_webhooks ───────────────────────────────────────────────
6
+ server.tool("list_webhooks", `List all configured webhooks in Propstack.
7
+
8
+ Returns each webhook with its URL, subscribed events, active status,
9
+ and HMAC secret. Use to review existing automation triggers.`, {}, async () => {
10
+ try {
11
+ const hooks = await client.get("/hooks");
12
+ if (!hooks || hooks.length === 0) {
13
+ return textResult("No webhooks configured.");
14
+ }
15
+ const lines = hooks.map((h) => {
16
+ const parts = [
17
+ `**Webhook #${h.id}**`,
18
+ ` URL: ${fmt(h.url)}`,
19
+ ` Events: ${h.events?.join(", ") ?? "none"}`,
20
+ ` Active: ${h.active ? "yes" : "no"}`,
21
+ h.secret ? ` Secret: ${h.secret}` : null,
22
+ ];
23
+ return parts.filter(Boolean).join("\n");
24
+ });
25
+ return textResult(`Webhooks:\n\n${lines.join("\n\n")}`);
26
+ }
27
+ catch (err) {
28
+ return errorResult("Webhook", err);
29
+ }
30
+ });
31
+ // ── create_webhook ──────────────────────────────────────────────
32
+ server.tool("create_webhook", `Create a webhook to subscribe to Propstack CRM events.
33
+
34
+ Propstack will POST a JSON payload to target_url whenever the event
35
+ fires. Use HMAC verification (secret in response) to validate payloads.
36
+
37
+ Common events:
38
+ - CLIENT_CREATED — new contact added
39
+ - CLIENT_UPDATED — contact details changed
40
+ - PROPERTY_UPDATED — property details or status changed
41
+
42
+ Use this to set up automation triggers, e.g.:
43
+ "Notify me when any property status changes"
44
+ "Alert when a new contact is created"`, {
45
+ event: z.string()
46
+ .describe("Event name (e.g. 'CLIENT_CREATED', 'CLIENT_UPDATED', 'PROPERTY_UPDATED')"),
47
+ target_url: z.string()
48
+ .describe("URL that Propstack will POST to when the event fires"),
49
+ }, async (args) => {
50
+ try {
51
+ const hook = await client.post("/hooks", { body: { event: args.event, target_url: args.target_url } });
52
+ const lines = [
53
+ `Webhook created (ID: ${hook.id}).`,
54
+ `URL: ${fmt(hook.url)}`,
55
+ `Events: ${hook.events?.join(", ") ?? args.event}`,
56
+ `Active: ${hook.active ? "yes" : "no"}`,
57
+ hook.secret ? `HMAC Secret: ${hook.secret}` : null,
58
+ ];
59
+ return textResult(lines.filter(Boolean).join("\n"));
60
+ }
61
+ catch (err) {
62
+ return errorResult("Webhook", err);
63
+ }
64
+ });
65
+ // ── delete_webhook ──────────────────────────────────────────────
66
+ server.tool("delete_webhook", `Delete a webhook subscription from Propstack.
67
+
68
+ Removes the webhook so Propstack will stop sending events to its URL.`, {
69
+ id: z.number()
70
+ .describe("Webhook ID to delete"),
71
+ }, async (args) => {
72
+ try {
73
+ await client.delete(`/hooks/${args.id}`);
74
+ return textResult(`Webhook ${args.id} deleted.`);
75
+ }
76
+ catch (err) {
77
+ return errorResult("Webhook", err);
78
+ }
79
+ });
80
+ // ── export_data ─────────────────────────────────────────────────
81
+ server.tool("export_data", `Bulk export an entire data table from Propstack as JSON.
82
+
83
+ Useful for reporting, backup, migration, or analytics. Returns the
84
+ full contents of the selected table.
85
+
86
+ Available tables:
87
+ - Core: contacts, properties, projects, deals, saved_queries
88
+ - Activities: appointments, todos, notes, messages, cancelations
89
+ - Media: documents, images
90
+ - Organization: brokers, teams, departments, commission_splits
91
+ - Config: deal_pipelines, policies, relationships, property_details
92
+ - Lookup: groups, contact_sources, contact_reasons, contact_statuses,
93
+ reservation_reasons, property_statuses`, {
94
+ table: z.enum([
95
+ "appointments", "brokers", "cancelations", "commission_splits",
96
+ "contacts", "deal_pipelines", "deals", "departments",
97
+ "documents", "images", "messages", "notes",
98
+ "policies", "projects", "properties", "property_details",
99
+ "relationships", "saved_queries", "teams", "todos",
100
+ "groups", "contact_sources", "contact_reasons", "contact_statuses",
101
+ "reservation_reasons", "property_statuses",
102
+ ])
103
+ .describe("Table name to export"),
104
+ }, async (args) => {
105
+ try {
106
+ const data = await client.get(`/datadump/${args.table}`);
107
+ if (Array.isArray(data)) {
108
+ return textResult(`Exported ${data.length} rows from "${args.table}".\n\n${JSON.stringify(data, null, 2)}`);
109
+ }
110
+ return textResult(`Export of "${args.table}":\n\n${JSON.stringify(data, null, 2)}`);
111
+ }
112
+ catch (err) {
113
+ return errorResult("Data export", err);
114
+ }
115
+ });
116
+ // ── get_contact_favorites ───────────────────────────────────────
117
+ server.tool("get_contact_favorites", `Get properties that a contact has favorited/bookmarked.
118
+
119
+ Returns the list of properties the contact has marked as favorites
120
+ in Propstack. Use to understand which listings a buyer is most
121
+ interested in.`, {
122
+ contact_id: z.number()
123
+ .describe("Contact ID"),
124
+ }, async (args) => {
125
+ try {
126
+ const favorites = await client.get(`/contacts/${args.contact_id}/favorites`);
127
+ if (!favorites || favorites.length === 0) {
128
+ return textResult(`Contact ${args.contact_id} has no favorited properties.`);
129
+ }
130
+ const lines = favorites.map((p) => {
131
+ const addr = [fmt(p.street, ""), fmt(p.house_number, "")].filter(Boolean).join(" ");
132
+ const city = [fmt(p.zip_code, ""), fmt(p.city, "")].filter(Boolean).join(" ");
133
+ const fullAddr = [addr, city].filter(Boolean).join(", ");
134
+ const price = fmtPrice(p.price) !== "none"
135
+ ? fmtPrice(p.price)
136
+ : fmtPrice(p.base_rent) !== "none"
137
+ ? fmtPrice(p.base_rent) + "/mo"
138
+ : "no price";
139
+ return `- **${fmt(p.title, "Untitled")}** (ID: ${p.id}) — ${fullAddr || "no address"} — ${price}`;
140
+ });
141
+ return textResult(`Favorited properties (${favorites.length}):\n\n${lines.join("\n")}`);
142
+ }
143
+ catch (err) {
144
+ return errorResult("Contact favorites", err);
145
+ }
146
+ });
147
+ }
148
+ //# sourceMappingURL=admin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/tools/admin.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 registerCompositeTools(server: McpServer, client: PropstackClient): void;
4
+ //# sourceMappingURL=composites.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composites.d.ts","sourceRoot":"","sources":["../../src/tools/composites.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAuB9D,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA86BvF"}