search_properties
Find rental and sale properties by filtering location, bedrooms, bathrooms, property type, and other key criteria to match specific housing requirements.
Instructions
Search for properties with basic property information (default: 15, max: 50 for free tier) including city, state, bedrooms, bathrooms, square footage, lot size, and year built. Note: Price data may not be available for all properties.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bathrooms | No | Number of bathrooms (e.g., 1, 1.5, 2) | |
| bedrooms | No | Number of bedrooms (e.g., 1, 2, 3) | |
| city | No | City name for property search (e.g., 'Austin', 'New York') | |
| limit | No | Maximum number of properties to return (default: 15, max: 50 for free tier) | |
| propertyType | No | Property type (e.g., 'Single Family', 'Condo', 'Townhouse') | |
| state | No | State abbreviation (e.g., 'TX', 'CA', 'NY') | |
| zipCode | No | ZIP code for location-based search (e.g., '78705', '90210') |
Implementation Reference
- src/index.ts:333-362 (handler)MCP tool handler for 'search_properties': builds search params, calls Rentcast API searchProperties, processes results, formats output using formatPropertyInfo, and returns formatted text response.async (params) => { try { const searchParams = buildPropertySearchParams(params); const result = await rentcastAPI.searchProperties(searchParams); if (!result.success) { return createErrorResponse("Error searching properties", result.error); } const properties = result.data as any[]; const summary = `Found ${properties.length} properties`; // Process each property individually based on actual API structure const propertyDetails = properties.slice(0, 10).map(prop => { return formatPropertyInfo(prop); }).join('\n\n'); const resultText = `${summary}\n\n${propertyDetails}${properties.length > 10 ? '\n\n... and more properties available' : ''}`; return createSuccessResponse(resultText); } catch (error) { return createErrorResponse("Failed to search properties", error instanceof Error ? error.message : 'Unknown error'); } }
- src/types/index.ts:192-215 (schema)Zod schema defining input validation for search_properties tool parameters including city, state, zipCode, bedrooms, bathrooms, propertyType, and limit.export const PropertySearchSchema = z.object({ city: z.string().optional().describe("City name for property search (e.g., 'Austin', 'New York')"), state: z.string().optional().describe("State abbreviation (e.g., 'TX', 'CA', 'NY')"), zipCode: z.string().optional().describe("ZIP code for location-based search (e.g., '78705', '90210')"), bedrooms: z.number().min(0).max(10).optional().describe("Number of bedrooms (e.g., 1, 2, 3)"), bathrooms: z .number() .min(0) .max(10) .optional() .describe("Number of bathrooms (e.g., 1, 1.5, 2)"), propertyType: z .string() .optional() .describe("Property type (e.g., 'Single Family', 'Condo', 'Townhouse')"), limit: z .number() .min(1) .max(50) .default(15) .describe( "Maximum number of properties to return (default: 15, max: 50 for free tier)", ), });
- src/index.ts:329-363 (registration)MCP server.tool registration for 'search_properties' tool, specifying name, description, input schema, and handler function.server.tool( "search_properties", "Search for properties with basic property information (default: 15, max: 50 for free tier) including city, state, bedrooms, bathrooms, square footage, lot size, and year built. Note: Price data may not be available for all properties.", PropertySearchSchema.shape, async (params) => { try { const searchParams = buildPropertySearchParams(params); const result = await rentcastAPI.searchProperties(searchParams); if (!result.success) { return createErrorResponse("Error searching properties", result.error); } const properties = result.data as any[]; const summary = `Found ${properties.length} properties`; // Process each property individually based on actual API structure const propertyDetails = properties.slice(0, 10).map(prop => { return formatPropertyInfo(prop); }).join('\n\n'); const resultText = `${summary}\n\n${propertyDetails}${properties.length > 10 ? '\n\n... and more properties available' : ''}`; return createSuccessResponse(resultText); } catch (error) { return createErrorResponse("Failed to search properties", error instanceof Error ? error.message : 'Unknown error'); } } );
- src/index.ts:209-224 (helper)Helper function to construct search parameters from MCP tool input params for use with Rentcast API.function buildPropertySearchParams(params: any, includeLimit: boolean = true): any { const searchParams: any = {}; if (includeLimit && params.limit) { searchParams.limit = params.limit; } if (params.city) searchParams.city = params.city; if (params.state) searchParams.state = params.state; if (params.zipCode) searchParams.zipCode = params.zipCode; if (params.bedrooms) searchParams.bedrooms = params.bedrooms; if (params.bathrooms) searchParams.bathrooms = params.bathrooms; if (params.propertyType) searchParams.propertyType = params.propertyType; return searchParams; }
- src/services/rentcast-api.ts:211-228 (helper)Rentcast API service method implementing the HTTP request to '/properties' endpoint for property search.async searchProperties( params: { city?: string; state?: string; zipCode?: string; bedrooms?: number; bathrooms?: number; propertyType?: string; priceRange?: string; limit?: number; } = {}, ): Promise<ApiCallResult> { const result = await this.makeRequest<RentcastProperty[]>("/properties", { ...params, limit: params.limit || 15, // Default to 15 for free tier optimization }); return result; }