realestate-mcp 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 (36) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/index.d.ts +18 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +252 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/tools/create-virtual-tour.d.ts +50 -0
  8. package/dist/tools/create-virtual-tour.d.ts.map +1 -0
  9. package/dist/tools/create-virtual-tour.js +123 -0
  10. package/dist/tools/create-virtual-tour.js.map +1 -0
  11. package/dist/tools/generate-floor-plan.d.ts +23 -0
  12. package/dist/tools/generate-floor-plan.d.ts.map +1 -0
  13. package/dist/tools/generate-floor-plan.js +119 -0
  14. package/dist/tools/generate-floor-plan.js.map +1 -0
  15. package/dist/tools/neighborhood-analysis.d.ts +76 -0
  16. package/dist/tools/neighborhood-analysis.d.ts.map +1 -0
  17. package/dist/tools/neighborhood-analysis.js +147 -0
  18. package/dist/tools/neighborhood-analysis.js.map +1 -0
  19. package/dist/tools/property-description.d.ts +32 -0
  20. package/dist/tools/property-description.d.ts.map +1 -0
  21. package/dist/tools/property-description.js +149 -0
  22. package/dist/tools/property-description.js.map +1 -0
  23. package/dist/tools/render-property-preview.d.ts +37 -0
  24. package/dist/tools/render-property-preview.d.ts.map +1 -0
  25. package/dist/tools/render-property-preview.js +135 -0
  26. package/dist/tools/render-property-preview.js.map +1 -0
  27. package/dist/tools/staging-suggestions.d.ts +41 -0
  28. package/dist/tools/staging-suggestions.d.ts.map +1 -0
  29. package/dist/tools/staging-suggestions.js +181 -0
  30. package/dist/tools/staging-suggestions.js.map +1 -0
  31. package/dist/usage.d.ts +38 -0
  32. package/dist/usage.d.ts.map +1 -0
  33. package/dist/usage.js +81 -0
  34. package/dist/usage.js.map +1 -0
  35. package/package.json +56 -0
  36. package/server.json +53 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomas Gorisse
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # realestate-mcp
2
+
3
+ MCP server for real estate agents — 3D virtual tours, SVG floor plans, AI-optimized property descriptions, staging suggestions, neighborhood analysis, and 3D model previews.
4
+
5
+ ## Tools
6
+
7
+ | Tool | Description |
8
+ |---|---|
9
+ | `generate_floor_plan` | Generate an SVG floor plan from room dimensions and types |
10
+ | `create_virtual_tour` | Create an embeddable 3D virtual tour from room descriptions and photos |
11
+ | `property_description` | Generate optimized listings for MLS, social media, luxury, and investor audiences |
12
+ | `staging_suggestions` | Suggest virtual staging options with furniture, decor, placement, and cost estimates |
13
+ | `neighborhood_analysis` | Comprehensive neighborhood summary — walk score, schools, transit, demographics, safety, market |
14
+ | `render_property_preview` | Generate an embeddable 3D model-viewer HTML snippet with AR support |
15
+
16
+ ## Quick start
17
+
18
+ ### With Claude Desktop
19
+
20
+ Add to your `claude_desktop_config.json`:
21
+
22
+ ```json
23
+ {
24
+ "mcpServers": {
25
+ "realestate-mcp": {
26
+ "command": "npx",
27
+ "args": ["realestate-mcp"]
28
+ }
29
+ }
30
+ }
31
+ ```
32
+
33
+ ### With an API key (optional)
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "realestate-mcp": {
39
+ "command": "npx",
40
+ "args": ["realestate-mcp"],
41
+ "env": {
42
+ "REALESTATE_MCP_API_KEY": "your-api-key"
43
+ }
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## Examples
50
+
51
+ ### Generate a floor plan
52
+
53
+ ```
54
+ Generate a floor plan for a 2-bedroom apartment:
55
+ - Living room: 5m x 4m
56
+ - Kitchen: 3m x 3m
57
+ - Bedroom 1: 4m x 3.5m
58
+ - Bedroom 2: 3.5m x 3m
59
+ - Bathroom: 2.5m x 2m
60
+ ```
61
+
62
+ ### Create a virtual tour
63
+
64
+ ```
65
+ Create a virtual tour for "123 Main Street" with rooms:
66
+ - Living room with hardwood floors and bay window
67
+ - Modern kitchen with island and stainless appliances
68
+ - Master bedroom with walk-in closet
69
+ - Two guest bedrooms
70
+ - Updated bathroom with marble tiles
71
+ ```
72
+
73
+ ### Property description
74
+
75
+ ```
76
+ Write a listing description for a 3BR/2BA house at 456 Oak Ave, Springfield.
77
+ 1,800 sqft, built 1985, renovated condition, asking $350,000.
78
+ Features: hardwood floors, granite counters, fenced backyard.
79
+ ```
80
+
81
+ ### Staging suggestions
82
+
83
+ ```
84
+ What staging would you suggest for an empty living room?
85
+ Modern style, medium budget, targeting young professionals.
86
+ ```
87
+
88
+ ### Neighborhood analysis
89
+
90
+ ```
91
+ What's the neighborhood like around 789 Elm Drive, Portland, OR?
92
+ Focus on schools, transit, and safety.
93
+ ```
94
+
95
+ ### 3D property preview
96
+
97
+ ```
98
+ Create a 3D preview for "Luxury Villa" using the model at
99
+ https://example.com/villa.glb with AR enabled.
100
+ ```
101
+
102
+ ## Pricing
103
+
104
+ | Tier | Requests | Price |
105
+ |---|---|---|
106
+ | Free | 50/month | $0 |
107
+ | Pro | Unlimited | $19/month |
108
+
109
+ ## Development
110
+
111
+ ```bash
112
+ npm install
113
+ npm run build
114
+ npm test
115
+ npm run dev # run with tsx (hot reload)
116
+ ```
117
+
118
+ ## License
119
+
120
+ MIT
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * realestate-mcp — MCP server for real estate agents.
4
+ *
5
+ * Tools:
6
+ * generate_floor_plan — SVG floor plan from room dimensions
7
+ * create_virtual_tour — Embeddable 3D virtual tour
8
+ * property_description — AI-optimized listing descriptions
9
+ * staging_suggestions — Virtual staging recommendations
10
+ * neighborhood_analysis — Neighborhood summary for an address
11
+ * render_property_preview — 3D model-viewer embed
12
+ *
13
+ * Tiers:
14
+ * Free — 50 requests/month
15
+ * Pro — unlimited ($19/month)
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;GAcG"}
package/dist/index.js ADDED
@@ -0,0 +1,252 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * realestate-mcp — MCP server for real estate agents.
4
+ *
5
+ * Tools:
6
+ * generate_floor_plan — SVG floor plan from room dimensions
7
+ * create_virtual_tour — Embeddable 3D virtual tour
8
+ * property_description — AI-optimized listing descriptions
9
+ * staging_suggestions — Virtual staging recommendations
10
+ * neighborhood_analysis — Neighborhood summary for an address
11
+ * render_property_preview — 3D model-viewer embed
12
+ *
13
+ * Tiers:
14
+ * Free — 50 requests/month
15
+ * Pro — unlimited ($19/month)
16
+ */
17
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
18
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
19
+ import { z } from "zod";
20
+ import { trackRequest } from "./usage.js";
21
+ import { generateFloorPlan } from "./tools/generate-floor-plan.js";
22
+ import { createVirtualTour } from "./tools/create-virtual-tour.js";
23
+ import { generatePropertyDescription } from "./tools/property-description.js";
24
+ import { generateStagingSuggestions } from "./tools/staging-suggestions.js";
25
+ import { generateNeighborhoodAnalysis } from "./tools/neighborhood-analysis.js";
26
+ import { renderPropertyPreview } from "./tools/render-property-preview.js";
27
+ // ---------------------------------------------------------------------------
28
+ // Helpers
29
+ // ---------------------------------------------------------------------------
30
+ const API_KEY = process.env.REALESTATE_MCP_API_KEY;
31
+ function checkUsage() {
32
+ const result = trackRequest(API_KEY);
33
+ if (!result.allowed) {
34
+ return { allowed: false, error: result.reason };
35
+ }
36
+ return { allowed: true };
37
+ }
38
+ // ---------------------------------------------------------------------------
39
+ // Server
40
+ // ---------------------------------------------------------------------------
41
+ const server = new McpServer({
42
+ name: "realestate-mcp",
43
+ version: "1.0.0",
44
+ });
45
+ // ---------------------------------------------------------------------------
46
+ // Tool: generate_floor_plan
47
+ // ---------------------------------------------------------------------------
48
+ server.tool("generate_floor_plan", "Generate an SVG floor plan from room dimensions. Returns SVG markup, total area, and room count.", {
49
+ rooms: z.array(z.object({
50
+ name: z.string().describe("Room name, e.g. 'Master Bedroom'"),
51
+ width: z.number().positive().describe("Room width in meters"),
52
+ length: z.number().positive().describe("Room length in meters"),
53
+ type: z
54
+ .enum(["bedroom", "bathroom", "kitchen", "living", "dining", "office", "hallway", "garage", "other"])
55
+ .optional()
56
+ .describe("Room type for color coding"),
57
+ })).min(1).describe("List of rooms with dimensions"),
58
+ title: z.string().optional().describe("Floor plan title"),
59
+ style: z.enum(["modern", "classic", "minimal"]).optional().describe("Visual style (default: modern)"),
60
+ }, async (args) => {
61
+ const usage = checkUsage();
62
+ if (!usage.allowed) {
63
+ return { content: [{ type: "text", text: usage.error }], isError: true };
64
+ }
65
+ const result = generateFloorPlan(args);
66
+ return {
67
+ content: [
68
+ {
69
+ type: "text",
70
+ text: JSON.stringify({ totalArea: result.totalArea, roomCount: result.roomCount }, null, 2),
71
+ },
72
+ { type: "text", text: result.svg },
73
+ ],
74
+ };
75
+ });
76
+ // ---------------------------------------------------------------------------
77
+ // Tool: create_virtual_tour
78
+ // ---------------------------------------------------------------------------
79
+ server.tool("create_virtual_tour", "Create an embeddable 3D virtual tour from room descriptions and photos. Returns HTML, manifest, and share URL.", {
80
+ propertyName: z.string().describe("Property name or address for the tour"),
81
+ address: z.string().optional().describe("Full property address"),
82
+ rooms: z.array(z.object({
83
+ name: z.string().describe("Room name"),
84
+ description: z.string().optional().describe("Room description"),
85
+ photoUrls: z.array(z.string().url()).optional().describe("Photo URLs for this room"),
86
+ features: z.array(z.string()).optional().describe("Notable features"),
87
+ order: z.number().optional().describe("Display order"),
88
+ })).min(1).describe("Rooms in the tour"),
89
+ branding: z.object({
90
+ primaryColor: z.string().optional().describe("Hex color, e.g. #2563EB"),
91
+ logo: z.string().url().optional().describe("Logo URL"),
92
+ agentName: z.string().optional().describe("Agent name to display"),
93
+ agentPhone: z.string().optional().describe("Agent phone number"),
94
+ }).optional().describe("Branding options"),
95
+ }, async (args) => {
96
+ const usage = checkUsage();
97
+ if (!usage.allowed) {
98
+ return { content: [{ type: "text", text: usage.error }], isError: true };
99
+ }
100
+ const result = createVirtualTour(args);
101
+ return {
102
+ content: [
103
+ {
104
+ type: "text",
105
+ text: JSON.stringify({
106
+ tourId: result.tourId,
107
+ shareUrl: result.shareUrl,
108
+ roomCount: result.manifest.rooms.length,
109
+ }, null, 2),
110
+ },
111
+ { type: "text", text: result.embedHtml },
112
+ ],
113
+ };
114
+ });
115
+ // ---------------------------------------------------------------------------
116
+ // Tool: property_description
117
+ // ---------------------------------------------------------------------------
118
+ server.tool("property_description", "Generate optimized property listing descriptions (MLS, social media, luxury, investor). Returns 4 variants plus headline and SEO keywords.", {
119
+ address: z.string().describe("Property address"),
120
+ propertyType: z.enum(["house", "apartment", "condo", "townhouse", "land", "commercial"]).describe("Property type"),
121
+ bedrooms: z.number().int().nonnegative().optional().describe("Number of bedrooms"),
122
+ bathrooms: z.number().nonnegative().optional().describe("Number of bathrooms"),
123
+ squareFootage: z.number().positive().optional().describe("Square footage"),
124
+ lotSize: z.string().optional().describe("Lot size description, e.g. '0.25 acres'"),
125
+ yearBuilt: z.number().int().optional().describe("Year built"),
126
+ price: z.number().positive().optional().describe("Listing price in USD"),
127
+ features: z.array(z.string()).optional().describe("Property features, e.g. ['Hardwood floors', 'Granite counters']"),
128
+ style: z.string().optional().describe("Architectural style, e.g. 'Colonial'"),
129
+ condition: z.enum(["new", "renovated", "good", "needs-work"]).optional().describe("Property condition"),
130
+ neighborhood: z.string().optional().describe("Neighborhood name"),
131
+ highlights: z.array(z.string()).optional().describe("Special highlights to emphasize"),
132
+ }, async (args) => {
133
+ const usage = checkUsage();
134
+ if (!usage.allowed) {
135
+ return { content: [{ type: "text", text: usage.error }], isError: true };
136
+ }
137
+ const result = generatePropertyDescription(args);
138
+ return {
139
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
140
+ };
141
+ });
142
+ // ---------------------------------------------------------------------------
143
+ // Tool: staging_suggestions
144
+ // ---------------------------------------------------------------------------
145
+ server.tool("staging_suggestions", "Suggest virtual staging options for empty rooms — furniture, decor, lighting, textiles, plants, and art with placement instructions.", {
146
+ roomType: z
147
+ .enum(["bedroom", "living-room", "dining-room", "kitchen", "bathroom", "office", "nursery", "outdoor"])
148
+ .describe("Room type to stage"),
149
+ width: z.number().positive().optional().describe("Room width in meters"),
150
+ length: z.number().positive().optional().describe("Room length in meters"),
151
+ style: z
152
+ .enum(["modern", "traditional", "scandinavian", "industrial", "bohemian", "coastal", "farmhouse", "mid-century"])
153
+ .optional()
154
+ .describe("Desired style (default: modern)"),
155
+ budget: z.enum(["low", "medium", "high"]).optional().describe("Budget level (default: medium)"),
156
+ targetBuyer: z
157
+ .enum(["young-professional", "family", "retiree", "investor", "luxury"])
158
+ .optional()
159
+ .describe("Target buyer persona"),
160
+ existingFeatures: z.array(z.string()).optional().describe("Existing features to work with"),
161
+ }, async (args) => {
162
+ const usage = checkUsage();
163
+ if (!usage.allowed) {
164
+ return { content: [{ type: "text", text: usage.error }], isError: true };
165
+ }
166
+ const result = generateStagingSuggestions(args);
167
+ return {
168
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
169
+ };
170
+ });
171
+ // ---------------------------------------------------------------------------
172
+ // Tool: neighborhood_analysis
173
+ // ---------------------------------------------------------------------------
174
+ server.tool("neighborhood_analysis", "Generate a comprehensive neighborhood summary — walk score, schools, transit, amenities, demographics, safety, and market context.", {
175
+ address: z.string().describe("Property address"),
176
+ city: z.string().optional().describe("City name"),
177
+ state: z.string().optional().describe("State abbreviation"),
178
+ zipCode: z.string().optional().describe("ZIP code"),
179
+ radius: z.number().positive().optional().describe("Search radius in miles (default: 1)"),
180
+ focus: z
181
+ .array(z.enum(["schools", "transit", "dining", "safety", "demographics", "parks"]))
182
+ .optional()
183
+ .describe("Focus areas for the analysis"),
184
+ }, async (args) => {
185
+ const usage = checkUsage();
186
+ if (!usage.allowed) {
187
+ return { content: [{ type: "text", text: usage.error }], isError: true };
188
+ }
189
+ const result = generateNeighborhoodAnalysis(args);
190
+ return {
191
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
192
+ };
193
+ });
194
+ // ---------------------------------------------------------------------------
195
+ // Tool: render_property_preview
196
+ // ---------------------------------------------------------------------------
197
+ server.tool("render_property_preview", "Generate an embeddable 3D model-viewer HTML snippet for property visualization. Supports AR on mobile and annotation hotspots.", {
198
+ propertyName: z.string().describe("Property name for the preview"),
199
+ modelUrl: z.string().url().optional().describe("URL to a .glb or .gltf 3D model file"),
200
+ posterUrl: z.string().url().optional().describe("Fallback poster image URL"),
201
+ backgroundColor: z.string().optional().describe("Background color (default: #f5f5f5)"),
202
+ enableAR: z.boolean().optional().describe("Enable AR on mobile (default: true)"),
203
+ autoRotate: z.boolean().optional().describe("Auto-rotate the 3D model (default: true)"),
204
+ cameraOrbit: z.string().optional().describe("Camera orbit, e.g. '45deg 55deg 2.5m'"),
205
+ annotations: z
206
+ .array(z.object({
207
+ label: z.string().describe("Annotation label"),
208
+ position: z.string().describe("3D position 'x y z'"),
209
+ normal: z.string().optional().describe("Surface normal 'x y z'"),
210
+ }))
211
+ .optional()
212
+ .describe("Annotation hotspots on the model"),
213
+ dimensions: z
214
+ .object({
215
+ width: z.number().positive().describe("Width in meters"),
216
+ depth: z.number().positive().describe("Depth in meters"),
217
+ height: z.number().positive().describe("Height in meters"),
218
+ })
219
+ .optional()
220
+ .describe("Property dimensions for the placeholder"),
221
+ }, async (args) => {
222
+ const usage = checkUsage();
223
+ if (!usage.allowed) {
224
+ return { content: [{ type: "text", text: usage.error }], isError: true };
225
+ }
226
+ const result = renderPropertyPreview(args);
227
+ return {
228
+ content: [
229
+ {
230
+ type: "text",
231
+ text: JSON.stringify({
232
+ embedUrl: result.embedUrl,
233
+ modelViewerVersion: result.modelViewerVersion,
234
+ features: result.features,
235
+ }, null, 2),
236
+ },
237
+ { type: "text", text: result.embedHtml },
238
+ ],
239
+ };
240
+ });
241
+ // ---------------------------------------------------------------------------
242
+ // Start
243
+ // ---------------------------------------------------------------------------
244
+ async function main() {
245
+ const transport = new StdioServerTransport();
246
+ await server.connect(transport);
247
+ }
248
+ main().catch((err) => {
249
+ console.error("Fatal error:", err);
250
+ process.exit(1);
251
+ });
252
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * create_virtual_tour — Create an embeddable 3D virtual tour configuration
3
+ * from photos or text descriptions of property rooms.
4
+ *
5
+ * In production, this would integrate with a 3D tour platform (Matterport, etc.).
6
+ * This scaffold generates a tour manifest and a self-contained HTML viewer.
7
+ */
8
+ export interface VirtualTourInput {
9
+ propertyName: string;
10
+ address?: string;
11
+ rooms: TourRoom[];
12
+ branding?: {
13
+ primaryColor?: string;
14
+ logo?: string;
15
+ agentName?: string;
16
+ agentPhone?: string;
17
+ };
18
+ }
19
+ export interface TourRoom {
20
+ name: string;
21
+ description?: string;
22
+ photoUrls?: string[];
23
+ features?: string[];
24
+ order?: number;
25
+ }
26
+ export interface VirtualTourOutput {
27
+ tourId: string;
28
+ embedHtml: string;
29
+ manifest: TourManifest;
30
+ shareUrl: string;
31
+ }
32
+ interface TourManifest {
33
+ id: string;
34
+ propertyName: string;
35
+ address?: string;
36
+ createdAt: string;
37
+ rooms: TourManifestRoom[];
38
+ branding: NonNullable<VirtualTourInput["branding"]>;
39
+ }
40
+ interface TourManifestRoom {
41
+ id: string;
42
+ name: string;
43
+ description: string;
44
+ photoUrls: string[];
45
+ features: string[];
46
+ order: number;
47
+ }
48
+ export declare function createVirtualTour(input: VirtualTourInput): VirtualTourOutput;
49
+ export {};
50
+ //# sourceMappingURL=create-virtual-tour.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-virtual-tour.d.ts","sourceRoot":"","sources":["../../src/tools/create-virtual-tour.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,CAAC,EAAE;QACT,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,QAAQ,EAAE,WAAW,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;CACrD;AAED,UAAU,gBAAgB;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAUD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,gBAAgB,GAAG,iBAAiB,CAuH5E"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * create_virtual_tour — Create an embeddable 3D virtual tour configuration
3
+ * from photos or text descriptions of property rooms.
4
+ *
5
+ * In production, this would integrate with a 3D tour platform (Matterport, etc.).
6
+ * This scaffold generates a tour manifest and a self-contained HTML viewer.
7
+ */
8
+ function generateId() {
9
+ return `tour_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`;
10
+ }
11
+ function slugify(text) {
12
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
13
+ }
14
+ export function createVirtualTour(input) {
15
+ const tourId = generateId();
16
+ const primaryColor = input.branding?.primaryColor ?? "#2563EB";
17
+ const rooms = input.rooms.map((room, idx) => ({
18
+ id: slugify(room.name) || `room-${idx}`,
19
+ name: room.name,
20
+ description: room.description ?? `View of the ${room.name.toLowerCase()}`,
21
+ photoUrls: room.photoUrls ?? [],
22
+ features: room.features ?? [],
23
+ order: room.order ?? idx,
24
+ }));
25
+ rooms.sort((a, b) => a.order - b.order);
26
+ const manifest = {
27
+ id: tourId,
28
+ propertyName: input.propertyName,
29
+ address: input.address,
30
+ createdAt: new Date().toISOString(),
31
+ rooms,
32
+ branding: {
33
+ primaryColor,
34
+ logo: input.branding?.logo,
35
+ agentName: input.branding?.agentName,
36
+ agentPhone: input.branding?.agentPhone,
37
+ },
38
+ };
39
+ const roomNavItems = rooms
40
+ .map((r, i) => `<button onclick="showRoom(${i})" class="nav-btn" id="nav-${i}">${r.name}</button>`)
41
+ .join("\n ");
42
+ const roomDataJson = JSON.stringify(rooms, null, 2);
43
+ const embedHtml = `<!DOCTYPE html>
44
+ <html lang="en">
45
+ <head>
46
+ <meta charset="UTF-8">
47
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
48
+ <title>${input.propertyName} — Virtual Tour</title>
49
+ <style>
50
+ * { margin: 0; padding: 0; box-sizing: border-box; }
51
+ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #111; color: #fff; }
52
+ .tour-container { max-width: 1200px; margin: 0 auto; min-height: 100vh; display: flex; flex-direction: column; }
53
+ .header { padding: 16px 24px; background: ${primaryColor}; display: flex; justify-content: space-between; align-items: center; }
54
+ .header h1 { font-size: 20px; }
55
+ .header .agent { font-size: 14px; opacity: 0.9; }
56
+ .viewer { flex: 1; display: flex; align-items: center; justify-content: center; background: #1a1a1a; position: relative; min-height: 500px; }
57
+ .room-info { padding: 20px; text-align: center; }
58
+ .room-info h2 { font-size: 28px; margin-bottom: 8px; }
59
+ .room-info p { font-size: 16px; color: #aaa; max-width: 600px; margin: 0 auto 16px; }
60
+ .features { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap; }
61
+ .feature { background: rgba(255,255,255,0.1); padding: 4px 12px; border-radius: 16px; font-size: 13px; }
62
+ .nav { padding: 12px 24px; background: #222; display: flex; gap: 8px; overflow-x: auto; }
63
+ .nav-btn { background: #333; color: #fff; border: 2px solid transparent; padding: 8px 16px;
64
+ border-radius: 8px; cursor: pointer; font-size: 14px; white-space: nowrap; }
65
+ .nav-btn:hover { background: #444; }
66
+ .nav-btn.active { border-color: ${primaryColor}; background: rgba(37,99,235,0.2); }
67
+ .photo-placeholder { width: 100%; height: 100%; display: flex; align-items: center;
68
+ justify-content: center; font-size: 48px; color: #444; }
69
+ .counter { position: absolute; bottom: 16px; right: 16px; background: rgba(0,0,0,0.7);
70
+ padding: 4px 12px; border-radius: 4px; font-size: 13px; }
71
+ </style>
72
+ </head>
73
+ <body>
74
+ <div class="tour-container">
75
+ <div class="header">
76
+ <h1>${input.propertyName}</h1>
77
+ <div class="agent">
78
+ ${input.branding?.agentName ? `${input.branding.agentName}` : ""}
79
+ ${input.branding?.agentPhone ? ` | ${input.branding.agentPhone}` : ""}
80
+ </div>
81
+ </div>
82
+ <div class="viewer" id="viewer">
83
+ <div class="room-info" id="room-info"></div>
84
+ <div class="counter" id="counter"></div>
85
+ </div>
86
+ <div class="nav" id="nav">
87
+ ${roomNavItems}
88
+ </div>
89
+ </div>
90
+ <script>
91
+ const rooms = ${roomDataJson};
92
+ let current = 0;
93
+ function showRoom(idx) {
94
+ current = idx;
95
+ const room = rooms[idx];
96
+ document.getElementById('room-info').innerHTML =
97
+ '<h2>' + room.name + '</h2>' +
98
+ '<p>' + room.description + '</p>' +
99
+ '<div class="features">' +
100
+ room.features.map(f => '<span class="feature">' + f + '</span>').join('') +
101
+ '</div>';
102
+ document.getElementById('counter').textContent = (idx + 1) + ' / ' + rooms.length;
103
+ document.querySelectorAll('.nav-btn').forEach((btn, i) => {
104
+ btn.classList.toggle('active', i === idx);
105
+ });
106
+ }
107
+ showRoom(0);
108
+ document.addEventListener('keydown', (e) => {
109
+ if (e.key === 'ArrowRight') showRoom(Math.min(current + 1, rooms.length - 1));
110
+ if (e.key === 'ArrowLeft') showRoom(Math.max(current - 1, 0));
111
+ });
112
+ </script>
113
+ </body>
114
+ </html>`;
115
+ const shareUrl = `https://tour.realestate-mcp.com/${tourId}`;
116
+ return {
117
+ tourId,
118
+ embedHtml,
119
+ manifest,
120
+ shareUrl,
121
+ };
122
+ }
123
+ //# sourceMappingURL=create-virtual-tour.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-virtual-tour.js","sourceRoot":"","sources":["../../src/tools/create-virtual-tour.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * generate_floor_plan — Generate an SVG floor plan from room dimensions.
3
+ *
4
+ * Input: text description of rooms with dimensions
5
+ * Output: SVG markup of a 2D floor plan
6
+ */
7
+ export interface FloorPlanInput {
8
+ rooms: RoomSpec[];
9
+ title?: string;
10
+ style?: "modern" | "classic" | "minimal";
11
+ }
12
+ export interface RoomSpec {
13
+ name: string;
14
+ width: number;
15
+ length: number;
16
+ type?: "bedroom" | "bathroom" | "kitchen" | "living" | "dining" | "office" | "hallway" | "garage" | "other";
17
+ }
18
+ export declare function generateFloorPlan(input: FloorPlanInput): {
19
+ svg: string;
20
+ totalArea: number;
21
+ roomCount: number;
22
+ };
23
+ //# sourceMappingURL=generate-floor-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-floor-plan.d.ts","sourceRoot":"","sources":["../../src/tools/generate-floor-plan.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CAC1C;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;CAC7G;AAoGD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB,CAwCA"}