Public leaderboard

Public assessment

ashev87/propstack-mcp (propstack-mcp-server)

propstack-mcp-server · v1.1.1 · scanned

What changed in the harness

Selection accuracy 94→94, token cost down 1%, unconfirmed writes 0%→0%.

Category breakdown

Where the score comes from.

Earned points across the four signals Gradable measures. Safety and Legibility are scored out of 30; Economics and Discoverability are scored out of 20.

01Safety

0.0 / 30

0.0 out of 30
02Legibility

18.8 / 30

18.8 out of 30
03Economics

7.7 / 20

7.7 out of 20
04Discoverability

11.0 / 20

11.0 out of 20

Highest-impact fix

Estimated gain +30 points

Add explicit identity and permission preflight tools

Expose machine-readable principal/tenant confirmation and a non-mutating permission check so agents can verify both before destructive actions.

Description evidence

Defects and rewrites.

28 defects found across the exposed tool descriptions. Suggested rewrites make purpose, inputs, boundaries, and returns easier for an agent to understand.

Tool Defect types Suggested rewrite
get_contact
no_return_description
Fetch the complete record of a single contact by ID, including all stored contact fields, sub-contacts (e.g. family members at the same address), and any related data requested via 'include' (children, documents, relationships, owned_properties). Use before a call to review the full picture of a contact. Returns the contact object, expanded with the requested related data.
create_contact
params_unexplained no_return_description
Create a new contact in Propstack CRM, or update an existing one if a contact with the same email address or old_crm_id already exists (auto-upsert, so no duplicate is created). Use to register a new lead after a phone call, ingest a web form submission, or add a property owner. Provide first_name and last_name for the person, email (also used for dedup matching), phone for the contact's phone number, and company when the contact represents an organization. Assign a broker with broker_id and look up valid lead sources with get_contact_sources (client_source_id). Returns the created or updated contact record with its ID and persisted fields.
update_contact
params_unexplained
Update an existing contact in Propstack CRM after a call or change — adjust details (first_name/last_name for the person, phone for their phone number, company for the organization they belong to), reassign the broker, update GDPR status, or change rating/status. Tag management: group_ids replaces ALL tags, add_group_ids adds tags without removing existing ones, sub_group_ids removes specific tags. Only provide the fields to change. Returns the updated contact record.
delete_contact
no_return_description
Delete a contact from Propstack CRM via soft delete: the contact is moved to a 30-day recycle bin and can be restored later. Use for GDPR deletion requests (Art. 17 DSGVO), removing duplicate contacts, or cleaning up test data. Returns confirmation that the contact was deleted.
get_property
no_return_description
Fetch the complete record of a single property by ID, including pricing, address, sizes, custom fields (fetched with expand=1), extra fields (fetched with new=1), broker assignment, project, images, floorplans, documents, and links. Use to prepare an exposé or review a listing in full. Pass include_translations with comma-separated language codes (e.g. 'en,de') to also get multilingual texts; omit it for the default language only. Returns the full property object.
create_property
params_unexplained
Create a new property (Objekt) listing in Propstack CRM — e.g. list a property from an acquisition call, create a listing from an owner inquiry, or add a unit to a project. Supply the address (street name, house_number, city, zip_code, country), the property type via rs_type (APARTMENT, HOUSE, OFFICE, ...) and optional rs_category sub-type (e.g. PENTHOUSE, VILLA), plus size/price fields as known: number_of_rooms is the total room count, floor is the level the property sits on, construction_year is when it was built. Look up valid status IDs with get_property_statuses and link an owner contact at creation via relationships_attributes. Returns the created property with its ID.
update_property
params_unexplained
Update an existing property in Propstack CRM — change price or rent, move status (e.g. reserved/sold), edit description texts, reassign to a different broker or project, or update custom fields. Only provide the fields to change: street, house_number, and city are the property's address, number_of_rooms is the total room count, floor is the level it sits on, construction_year is when it was built, and project_id is the project this property belongs to. Look up valid status IDs with get_property_statuses. Returns the updated property record.
create_deal
params_unexplained no_return_description
Create a deal linking an interested contact to a property in Propstack, tracking it through pipeline stages (Anfrage → Besichtigung → Reserviert → Notartermin → Verkauft). Use after a viewing to formalize interest, after a contact inquiry about a property, or to move a lead into the sales pipeline. Requires client_id (the interested contact), property_id (the property the contact is interested in), and deal_stage_id (look these up with list_pipelines or get_pipeline). Returns the created deal with its ID and current pipeline stage.
update_deal
params_unexplained
Update an existing deal in Propstack CRM — move it to the next pipeline stage by changing deal_stage_id, update the expected or agreed price (sold_price), add or change notes, reassign the broker, update the feeling score after a conversation, or record a cancellation reason (reservation_reason_id and category='lost'). Only provide the fields to change: property_id is the property the deal refers to and deal_pipeline_id is the pipeline it belongs to. Returns the updated deal record.
list_search_profiles
no_return_description
List the search profiles (Suchprofile) in Propstack. A search profile captures what a buyer or renter is looking for — cities, price range, room count, features — and belongs to a contact. Use to see what a specific contact is looking for (filter with client = contact ID), to review criteria before matching properties, or to list all active profiles. Returns a paginated list of search profiles with their criteria.
create_search_profile
no_return_description
Create a search profile (Suchprofil) for a contact in Propstack, capturing structured criteria for what the buyer or renter is looking for. Map natural-language requirements to fields: rs_types for property types (e.g. ['APARTMENT']), cities for locations, price/price_to for the budget range, number_of_rooms/number_of_rooms_to for room counts, and feature booleans where 'true' = required, 'false' = excluded, and omitting means don't care (balcony, lift, garden, built_in_kitchen, cellar, rented). Use lat/lng/radius for proximity searches (e.g. within 5 km of a point). Returns the created search profile with its ID.
delete_search_profile
no_return_description
Delete a search profile from Propstack. Use when a contact has found a property and is no longer searching, the profile was created in error, or the contact explicitly asks to stop receiving matching notifications. Returns confirmation that the search profile was deleted.
search_activities
params_unexplained no_return_description
Search the read-only activity feed/timeline in Propstack — the history of everything that happened: emails sent, call notes, tasks, appointments, cancellations, GDPR policy changes, etc. Use to view the full interaction history for a contact (client_id), all activity on a property (property_id), or what a broker has been doing (broker_id), optionally filtered by activity type ('type': message, note, reminder, event, policy, cancelation, decision, sms, letter). Use sort_by to choose the field the results are sorted on and order for asc/desc. Returns a paginated list of activity entries.
list_events
no_return_description
List calendar events (Termine) in Propstack. Returns the calendar events that match the given filters, each with its details such as state (neutral = scheduled, took_place = completed, cancelled), start/end times, and linked broker, contact (client), property, project, tag, and note type. Events are appointments like property viewings, client meetings, and notary appointments. Filter by date range (starts_at_after/starts_at_before, ends_at_after/ends_at_before), state, recurring, broker, client, property, project, tag, or note_type, and paginate with page/per_page.
send_email
no_return_description
Send an email using a Propstack email template (snippet) through a connected broker email account. Pass broker_id (sender broker with a connected email account), snippet_id (email template ID; Propstack fills merge fields such as contact name and property details automatically), to (recipient addresses) and optional cc, and optionally link the email to contacts, properties, or projects (client_ids, property_ids, project_ids) so it appears in the correct CRM activity feeds. Use for sending exposés to interested contacts, follow-ups after viewings, or confirmations/rejections to leads. Returns a confirmation of the send, including the created email's ID and status.
update_email
no_return_description
Update an existing email/message in Propstack by its id. Mark it read or unread (read), archive or unarchive (archived), set its category (message_category_id), or link it to contacts, properties, or projects (client_ids, property_ids, project_ids) so it appears in the correct activity feeds. Only provide the fields you want to change. Returns the updated email/message with its new field values.
list_documents
no_return_description
List documents attached to a property, project, or contact in Propstack. Documents include floor plans (Grundrisse), exposés, contracts, photos, and other uploaded files. Filter by exactly one of property_id, project_id, or client_id, optionally sort (sort, e.g. 'created_at,desc'), and paginate with page/per_page. Returns the matching documents for the given entity, e.g., to find a Grundriss, list a contact's uploads, or check what's already been uploaded before adding more.
upload_document
no_return_description
Upload a document to a property, project, or contact in Propstack. The title and doc fields are required; doc must be a base64 data URI (e.g. 'data:application/pdf;base64,...'), and you must attach to exactly one entity via property_id, project_id, or client_id. Use the boolean flags to classify the document: is_floorplan (Grundriss), is_exposee (exposé), is_private (hide from public/portal views), on_landing_page (show on the property landing page). Returns the created document with its ID, confirming the upload.
create_ownership
no_return_description
Link a contact as the OWNER (Eigentümer) of a property. Pass client_id (the owner contact) and property_id (the owned property) to record property ownership, e.g., to set up owner relationships for acquisition properties or link sellers to their properties; the ownership appears on both the contact's and the property's record. Returns the created ownership link with its ID, confirming the relationship was recorded.
create_partnership
params_unexplained no_return_description
Link a contact as a PARTNER (buyer, tenant, etc.) to a property, creating a named contact to property relationship. Pass client_id (the partner contact), property_id (the property this contact is being linked to as a partner), and name (the role the contact plays on that property, e.g. 'Käufer' (buyer), 'Mieter' (tenant), 'Verwalter' (manager)). Use to link a buyer to a property or a tenant to a rental property. Returns the created partnership record with its ID, confirming the link.
create_tag
no_return_description
Create a new tag/label (Merkmal) in Propstack for categorizing contacts, properties, and activities. Provide name, choose which entity type the tag applies to (entity: for_clients, for_properties, or for_activities), and optionally set super_group_id to place it under a parent super-group (Obermerkmal) for hierarchy. Examples: 'Penthouse-Käufer', 'VIP', 'Kapitalanleger', 'Erstbezug'. Returns the created tag with its ID and details.
list_activity_types
no_return_description
List all activity/task types in Propstack. Returns the activity types matching the optional category filter (message, for_notes, for_reminders, for_events); each type has an id, name, and category. These serve as templates for creating notes, todos (reminders), events, and messages: for_notes maps to note_type_id in create_task, for_reminders to todo_type_id (when is_reminder: true), for_events to event_type_id (when is_event: true), and message to snippet_id for email templates. Categories map to search_activities filters (for_notes to note, for_reminders to reminder, for_events to event, message to message).
list_contact_statuses
no_return_description
List contact statuses (Kontaktstatus) in Propstack. Returns the available statuses with their IDs, e.g. 'Lead', 'Kunde', 'Archiviert'. Use these IDs for search_contacts (status param) and for create_contact/update_contact (client_status_id).
list_reservation_reasons
no_return_description
List deal cancellation reasons (Reservierungsgründe/Absagegründe) in Propstack. Returns the available cancellation reasons with their IDs. Use when creating deal cancellations (create_task with reservation_reason_id) or filtering lost deals (search_deals with reservation_reason_ids).
property_performance_report
no_return_description
Generate a performance report for a property, identified by property_id. Combines 3 API calls in parallel: full property details (with custom fields), all deals/inquiries for the property, and the activity feed (last 50 interactions). Returns a report containing the property's days on market, total inquiries, deals broken down by stage/category, and a recent activity breakdown by type. Use when asked how a property is performing (e.g., 'How is the Friedrichstr property doing?').
pipeline_summary
no_return_description
Produce a pipeline overview for the optional pipeline_id and/or broker_id filters. Fetches all deal pipelines and deals, then aggregates them. Returns a summary with the deal count per stage, the total value per stage (from deal price or property price), and stale deals (no update in 14+ days) that need attention. Use when asked 'How's the pipeline looking?' or for a sales overview.
delete_webhook
no_return_description
Delete a webhook subscription from Propstack. Removes the webhook so Propstack will stop sending events to its URL. Returns a confirmation that the webhook was deleted successfully.
get_contact_favorites
params_unexplained
Get properties that a contact has favorited/bookmarked. The contact_id is the unique Propstack identifier of the contact whose favorites to retrieve. Returns the list of properties the contact has marked as favorites, useful for understanding which listings a buyer is most interested in.

Selection evidence

Confusable tool pairs.

10 pairs where similar names or overlapping descriptions may send an agent toward the wrong tool.

Tool A Tool B Confidence Why they collide
search_contacts search_contacts_by_phone high Both tools answer 'find the contact for this phone number'; search_contacts lists phone_number as a schema parameter, so an agent given a caller-ID or phone-match task could pick the generic search tool instead of the purpose-built search_contacts_by_phone.
get_property get_property_statuses medium A task like 'get the status of this property' is ambiguous: get_property returns the property's own status, while get_property_statuses returns the global list of statuses — an agent can select the wrong one when the user means 'the property's status' vs 'available statuses'.
get_contact get_contact_favorites medium 'Get what properties this contact has' can map to either tool: get_contact exposes owned_properties via include, while get_contact_favorites returns bookmarked properties; a favorites/interests query may send the agent to the wrong endpoint.
get_contact get_contact_sources medium 'Find the lead source for this contact' is ambiguous: get_contact shows the contact's details (including source), whereas get_contact_sources returns the global list of lead sources — an agent may fetch the global list or the single contact's detail for the wrong reason.
create_search_profile update_search_profile medium Capturing a buyer's criteria (rooms, budget, cities) doesn't specify create vs update; without knowing whether a profile already exists, an agent may create a duplicate or fail to refine an existing profile.
get_pipeline pipeline_summary medium 'Show me the pipeline' tasks are ambiguous: get_pipeline returns a single pipeline's stages, while pipeline_summary aggregates deals per stage, totals, and stale deals — an overview request can land on the wrong one.
create_ownership create_partnership medium Both link a contact to a property; only the role differs (owner vs named partner like buyer/tenant). A task like 'link Herr Müller to Hauptstraße 12' or 'record that this client now owns the unit' doesn't clearly select between them.
create_deal create_partnership medium Marking a buyer/tenant interest can be modeled as either a pipeline deal (create_deal) or a named contact-property role (create_partnership, e.g. Käufer/Mieter); a task like 'this client is the buyer of unit 5' is plausibly routed to either.
update_contact update_property low Both are generic 'update existing record' tools accepting broker_id and status fields; a task like 'update the status / reassign the broker' with an underspecified entity could route to the wrong one, though context usually disambiguates.
get_property get_project low Both fetch full details by ID and share generic 'detail/full/single' semantics; a vague request like 'get full details of item 3' or a development-unit question could pick the wrong entity type, but natural language usually specifies property vs project.

Compare the field

One score is useful.
The evidence makes it actionable.

Back to the leaderboard