Skip to main content
Glama
NightSquawk

AppFolio MCP Server

by NightSquawk

AppFolio MCP Server

npm version npm downloads OpenSSF Scorecard License: AGPL-3.0 Node

An MCP (Model Context Protocol) server for AppFolio Property Manager, connecting your property management data to AI tools.

Quick start

Claude

Download for Claude Desktop

bash (macOS/Linux):

APPFOLIO_VHOST="yourcompany"
APPFOLIO_CLIENT_ID="your-reports-client-id"
APPFOLIO_CLIENT_SECRET="your-reports-client-secret"
APPFOLIO_DB_DEVELOPER_ID="your-developer-id"
APPFOLIO_DB_CLIENT_ID="your-db-client-id"
APPFOLIO_DB_CLIENT_SECRET="your-db-client-secret"

claude mcp add appfolio \
  --env APPFOLIO_VHOST="$APPFOLIO_VHOST" \
  --env APPFOLIO_CLIENT_ID="$APPFOLIO_CLIENT_ID" \
  --env APPFOLIO_CLIENT_SECRET="$APPFOLIO_CLIENT_SECRET" \
  --env APPFOLIO_DB_DEVELOPER_ID="$APPFOLIO_DB_DEVELOPER_ID" \
  --env APPFOLIO_DB_CLIENT_ID="$APPFOLIO_DB_CLIENT_ID" \
  --env APPFOLIO_DB_CLIENT_SECRET="$APPFOLIO_DB_CLIENT_SECRET" \
  -- npx -y @nightsquawktech/appfolio-mcp-server

PowerShell (Windows):

$APPFOLIO_VHOST = "yourcompany"
$APPFOLIO_CLIENT_ID = "your-reports-client-id"
$APPFOLIO_CLIENT_SECRET = "your-reports-client-secret"
$APPFOLIO_DB_DEVELOPER_ID = "your-developer-id"
$APPFOLIO_DB_CLIENT_ID = "your-db-client-id"
$APPFOLIO_DB_CLIENT_SECRET = "your-db-client-secret"

claude mcp add appfolio `
  --env "APPFOLIO_VHOST=$APPFOLIO_VHOST" `
  --env "APPFOLIO_CLIENT_ID=$APPFOLIO_CLIENT_ID" `
  --env "APPFOLIO_CLIENT_SECRET=$APPFOLIO_CLIENT_SECRET" `
  --env "APPFOLIO_DB_DEVELOPER_ID=$APPFOLIO_DB_DEVELOPER_ID" `
  --env "APPFOLIO_DB_CLIENT_ID=$APPFOLIO_DB_CLIENT_ID" `
  --env "APPFOLIO_DB_CLIENT_SECRET=$APPFOLIO_DB_CLIENT_SECRET" `
  -- npx -y @nightsquawktech/appfolio-mcp-server

Cursor

Add to Cursor

Or put the mcp.json block in .cursor/mcp.json, then verify with:

agent mcp list

(The Cursor CLI manages configured servers but has no mcp add; install is via the button or mcp.json.)

VS Code

Install in VS Code

bash (macOS/Linux):

APPFOLIO_VHOST="yourcompany"
APPFOLIO_CLIENT_ID="your-reports-client-id"
APPFOLIO_CLIENT_SECRET="your-reports-client-secret"
APPFOLIO_DB_DEVELOPER_ID="your-developer-id"
APPFOLIO_DB_CLIENT_ID="your-db-client-id"
APPFOLIO_DB_CLIENT_SECRET="your-db-client-secret"

code --add-mcp '{"name":"appfolio","command":"npx","args":["-y","@nightsquawktech/appfolio-mcp-server"],"env":{"APPFOLIO_VHOST":"'"$APPFOLIO_VHOST"'","APPFOLIO_CLIENT_ID":"'"$APPFOLIO_CLIENT_ID"'","APPFOLIO_CLIENT_SECRET":"'"$APPFOLIO_CLIENT_SECRET"'","APPFOLIO_DB_DEVELOPER_ID":"'"$APPFOLIO_DB_DEVELOPER_ID"'","APPFOLIO_DB_CLIENT_ID":"'"$APPFOLIO_DB_CLIENT_ID"'","APPFOLIO_DB_CLIENT_SECRET":"'"$APPFOLIO_DB_CLIENT_SECRET"'"}}'

PowerShell (Windows):

$APPFOLIO_VHOST = "yourcompany"
$APPFOLIO_CLIENT_ID = "your-reports-client-id"
$APPFOLIO_CLIENT_SECRET = "your-reports-client-secret"
$APPFOLIO_DB_DEVELOPER_ID = "your-developer-id"
$APPFOLIO_DB_CLIENT_ID = "your-db-client-id"
$APPFOLIO_DB_CLIENT_SECRET = "your-db-client-secret"

$config = @{
  name = "appfolio"
  command = "npx"
  args = @("-y", "@nightsquawktech/appfolio-mcp-server")
  env = @{
    APPFOLIO_VHOST = $APPFOLIO_VHOST
    APPFOLIO_CLIENT_ID = $APPFOLIO_CLIENT_ID
    APPFOLIO_CLIENT_SECRET = $APPFOLIO_CLIENT_SECRET
    APPFOLIO_DB_DEVELOPER_ID = $APPFOLIO_DB_DEVELOPER_ID
    APPFOLIO_DB_CLIENT_ID = $APPFOLIO_DB_CLIENT_ID
    APPFOLIO_DB_CLIENT_SECRET = $APPFOLIO_DB_CLIENT_SECRET
  }
} | ConvertTo-Json -Compress

code --add-mcp $config

Codex

bash (macOS/Linux):

APPFOLIO_VHOST="yourcompany"
APPFOLIO_CLIENT_ID="your-reports-client-id"
APPFOLIO_CLIENT_SECRET="your-reports-client-secret"
APPFOLIO_DB_DEVELOPER_ID="your-developer-id"
APPFOLIO_DB_CLIENT_ID="your-db-client-id"
APPFOLIO_DB_CLIENT_SECRET="your-db-client-secret"

codex mcp add appfolio \
  --env APPFOLIO_VHOST="$APPFOLIO_VHOST" \
  --env APPFOLIO_CLIENT_ID="$APPFOLIO_CLIENT_ID" \
  --env APPFOLIO_CLIENT_SECRET="$APPFOLIO_CLIENT_SECRET" \
  --env APPFOLIO_DB_DEVELOPER_ID="$APPFOLIO_DB_DEVELOPER_ID" \
  --env APPFOLIO_DB_CLIENT_ID="$APPFOLIO_DB_CLIENT_ID" \
  --env APPFOLIO_DB_CLIENT_SECRET="$APPFOLIO_DB_CLIENT_SECRET" \
  -- npx -y @nightsquawktech/appfolio-mcp-server

PowerShell (Windows):

$APPFOLIO_VHOST = "yourcompany"
$APPFOLIO_CLIENT_ID = "your-reports-client-id"
$APPFOLIO_CLIENT_SECRET = "your-reports-client-secret"
$APPFOLIO_DB_DEVELOPER_ID = "your-developer-id"
$APPFOLIO_DB_CLIENT_ID = "your-db-client-id"
$APPFOLIO_DB_CLIENT_SECRET = "your-db-client-secret"

codex mcp add appfolio `
  --env "APPFOLIO_VHOST=$APPFOLIO_VHOST" `
  --env "APPFOLIO_CLIENT_ID=$APPFOLIO_CLIENT_ID" `
  --env "APPFOLIO_CLIENT_SECRET=$APPFOLIO_CLIENT_SECRET" `
  --env "APPFOLIO_DB_DEVELOPER_ID=$APPFOLIO_DB_DEVELOPER_ID" `
  --env "APPFOLIO_DB_CLIENT_ID=$APPFOLIO_DB_CLIENT_ID" `
  --env "APPFOLIO_DB_CLIENT_SECRET=$APPFOLIO_DB_CLIENT_SECRET" `
  -- npx -y @nightsquawktech/appfolio-mcp-server

Or add it to ~/.codex/config.toml under [mcp_servers.appfolio].

mcp.json

Every environment variable the server reads, with recommended values:

{
  "mcpServers": {
    "appfolio": {
      "command": "npx",
      "args": ["-y", "@nightsquawktech/appfolio-mcp-server"],
      "env": {
        "APPFOLIO_VHOST": "yourcompany",
        "APPFOLIO_CLIENT_ID": "your-reports-client-id",
        "APPFOLIO_CLIENT_SECRET": "your-reports-client-secret",
        "APPFOLIO_DB_DEVELOPER_ID": "your-developer-id",
        "APPFOLIO_DB_CLIENT_ID": "your-db-client-id",
        "APPFOLIO_DB_CLIENT_SECRET": "your-db-client-secret"
      }
    }
  }
}

File locations: .mcp.json in your project root (Claude Code), claude_desktop_config.json (Claude Desktop), .cursor/mcp.json (Cursor).

Related MCP server: Qobrix CRM MCP Server

Configuration

The server talks to two AppFolio APIs, each with its own credentials. Configure one set or both: each API's tools only need their own variables, and the other API's tools return an error at call time if their variables are unset.

Variable

Required

Default

Purpose

APPFOLIO_VHOST

for Reports API tools

Your AppFolio database name, the subdomain in {vhost}.appfolio.com

APPFOLIO_CLIENT_ID

for Reports API tools

Reports API Client ID (Account Settings > Manage API Settings > Reports API Credentials)

APPFOLIO_CLIENT_SECRET

for Reports API tools

Reports API Client Secret

APPFOLIO_DB_DEVELOPER_ID

for Database API tools

Your AppFolio Developer ID (Admin > Developer ID)

APPFOLIO_DB_CLIENT_ID

for Database API tools

Database API Basic Auth Client ID (API Credentials > Basic Auth)

APPFOLIO_DB_CLIENT_SECRET

for Database API tools

Database API Basic Auth Client Secret

Security & write safety

AppFolio credentials: create dedicated API credentials for this server. Reports API credentials come from Account Settings > Manage API Settings > Reports API Credentials; Database API credentials are a Developer ID plus Basic Auth Client ID and Secret from API Credentials > Basic Auth.

  • The Reports API tools (list_reports, describe_report, run_report) are read-only: reports return data and never modify anything.

  • The Database API tool call_endpoint executes reads and writes. Of the 156 endpoints, 58 are GET reads and 98 are write operations (55 POST, 33 PATCH, 4 PUT, 6 DELETE) that execute live against your AppFolio database. There is no environment write gate in this version.

  • For a read-only posture, configure only the Reports API variables: without APPFOLIO_DB_* credentials, every call_endpoint request fails before reaching AppFolio.

  • Every request is validated against the local catalog first (known operation, required path params, required report filters), and the client enforces AppFolio's documented rate limits (7 requests per 15 seconds on the Reports API, all three Database API windows).

  • All requests go directly from your machine to {vhost}.appfolio.com and api.appfolio.com; nothing passes through third parties.

IMPORTANT

The tool surface is a guardrail, not a security boundary. The env vars in your MCP config are real AppFolio credentials, and an AI agent with shell access can bypass the MCP tools and call the AppFolio API directly with them. If you need hard read-only, enforce it at the source: scope the API credentials themselves, or only issue the read-oriented Reports API credentials and leave the Database API credentials out of the config.

Tools

Both APIs are catalog-backed: instead of one MCP tool per report or endpoint, each API exposes a list/describe/call triple built on mcp-core. list_* discovers what exists (137 reports, 156 endpoints), describe_* returns the full parameter spec for one entry from a local catalog, and the execute tool (run_report / call_endpoint) validates the request against that spec before calling AppFolio. Six tools cover 293 operations without flooding your client's tool list.

list_reports         List the 137 AppFolio reports (slug, name, category, required filters)
describe_report      Full parameter spec for one report: filters, types, enums, response columns
run_report           Run a report and return its rows, auto-paginated
list_endpoints       List the 156 Database API endpoints (operationId, method, path, category)
describe_endpoint    Full spec for one endpoint: path params, filters, body schema, response fields
call_endpoint        Call a Database API endpoint after validating it against the catalog

API coverage

293 operations covered: 137 reports (Reports API v2) and 156 endpoints (Database API v0).

Category

Operations

Reports: Association / HOA

16

Reports: Financial

34

Reports: Leasing

16

Reports: Maintenance & Workflow

12

Reports: Other

2

Reports: Owner

6

Reports: Property & Unit

19

Reports: Registers & Transactions

9

Reports: Rent Roll

5

Reports: Tenant

13

Reports: Vendor

5

Database API: Accounting

30

Database API: Community Associations

12

Database API: Corporate Accounting

2

Database API: Custom Fields

1

Database API: Leasing

20

Database API: Maintenance

29

Database API: People

21

Database API: Properties

40

Database API: System

1

Report

ID

Board of Directors

board_of_directors

Dues Roll

dues_roll

Dues Roll (Itemized)

dues_roll_itemized

Eligible Debt Summary

eligible_debt_summary

Fund Balance Sheet

fund_balance_sheet

Fund Balance Sheet - Active Funds

fund_balance_sheet_active_funds

Fund Income Statement

fund_income_statement

Homeowner Delinquency

homeowner_delinquency

Homeowner Delinquency (As Of)

homeowner_delinquency_as_of

Homeowner Directory

homeowner_directory

Homeowner Ledger

homeowner_ledger

Homeowner Prepayment Balance

homeowner_prepayment_balance

Homeowner Resale

homeowner_resale

Homeowner Vehicle Info

homeowner_vehicle_info

Insurance Enforcement

insurance_enforcement

Violation Detail

violation_detail

Report

ID

Account Totals

account_totals

Additional Fees

additional_fees

Aged Payables Summary

aged_payables_summary

Aged Receivable Detail

aged_receivables_detail

Annual Budget - Comparative

annual_budget_comparative

Annual Budget - Forecast

annual_budget_forecast

Balance Sheet

balance_sheet

Balance Sheet - Comparative

balance_sheet_comparative

Balance Sheet - Property Comparison

balance_sheet_comparison

Bank Account Association

bank_account_association

Budget - Comparative

budget_comparative

Budget - Property Comparison

budget_comparison

Cash Flow

cash_flow

Cash Flow - Property Comparison

cash_flow_comparison

Cash Flow Detail

cash_flow_detail

Chart of Accounts

chart_of_accounts

Email Delivery Errors

email_delivery_errors

Expense Distribution

expense_distribution

Fixed Assets

fixed_assets

General Ledger

general_ledger

Import Variances

import_variances

Income Statement

income_statement

Income Statement - Comparative

income_statement_comparative

Income Statement - Property Comparison

income_statement_comparison

Income Statement (Date Range)

income_statement_date_range

Insurance Usage

insurance_usage

Late Fee Policy Comparison

late_fee_policy_comparison

Loans

loans

Trial Balance

trial_balance

Trial Balance by Property

trial_balance_by_property

Trust Account Balance

trust_account_balance

Trust Account Detail

trust_account_balance_detail

Cash Flow - 12 Month

twelve_month_cash_flow

Income Statement - 12 Month

twelve_month_income_statement

Report

ID

Guest Card Inquiries

guest_card_inquiries

Guest Card Interests

guest_cards

Historical Advertised Rent

historical_advertised_rent

Inactive Guest Card Interests

inactive_guest_cards

Lease Expiration Detail By Month

lease_expiration_detail

Lease Expiration Summary By Month

lease_expiration_summary

Lease History

lease_history

Leasing Agent Performance

leasing_agent_performance

Leasing Funnel Performance

leasing_funnel_performance

Leasing Summary

leasing_summary

Prospect Source Tracking

prospect_source_tracking

Renewal Summary

renewal_summary

Rental Applications

rental_applications

Screening Assessments

screening_assessments

Screening Usage

screening_usage

Showings

showings

Report

ID

Association Work Order

association_work_order

Cancelled Workflows

cancelled_processes

Completed Workflows

completed_processes

Realm-X Flows Assigned Tasks

flows_assigned_tasks

In-Progress Workflows

in_progress_workflows

Inspection Detail

inspection_detail

Project Budget Detail

project_budget_detail

Project Directory

project_directory

Unit Inspection

unit_inspection

Activities Summary

upcoming_activities

Work Order

work_order

Work Order Labor Summary

work_order_labor_summary

Report

ID

Receivables Activity

receivables_activity

Survey Responses

surveys_summary

Report

ID

Owner Custom Fields

owner_custom_fields

Owner Directory

owner_directory

Owner Leasing

owner_leasing

Owner Withholdings

owner_withholdings

Owner 1099 Summary

owner1099

Owner 1099 Detail

owner1099_detail

Report

ID

Amenities By Property

amenities_by_property

AppFolio Stackâ„¢ Usage

appfolio_stack_usage

Inventory Status

inventory_status

Inventory Usage

inventory_usage

Keys Detail

keys_detail

Occupancy Custom Fields

occupancy_custom_fields

Occupancy Summary

occupancy_summary

Premium Listing Billing Detail

premium_leads_billing_detail

Property Budget

property_budget

Property Custom Fields

property_custom_fields

Property Directory

property_directory

Property Group Directory

property_group_directory

Property Performance

property_performance

Property Staff Assignments

property_staff_assignments

Rentable Items

rentable_items

Unit Custom Fields

unit_custom_fields

Unit Directory

unit_directory

Unit Turn Detail

unit_turn_detail

Unit Vacancy Detail

unit_vacancy

Report

ID

Bill Detail

bill_detail

Charge Detail

charge_detail

Check Register

check_register

Check Register Detail (Enhanced)

check_register_detail

Deposit Register

deposit_register

Expense Register

expense_register

Income Register

income_register

Payment Plans

payment_plans

Purchase Order

purchase_order

Report

ID

Gross Potential Rent

gross_potential_rent_enhanced

Rent Roll

rent_roll

Rent Roll (Commercial)

rent_roll_commercial

Rent Roll (Itemized)

rent_roll_itemized

Rent Roll (By Bed)

student_housing_rent_roll_by_bed

Report

ID

Delinquency

delinquency

Delinquency (As Of)

delinquency_as_of

Renter Directory

renter_directory

Resident Financial Activity

resident_financial_activity

Security Deposit Funds Detail

security_deposit_funds_detail

Debt Collections Status

tenant_debt_collections_status

Tenant Directory

tenant_directory

Tenant Ledger

tenant_ledger

Tenant Tickler

tenant_tickler

Tenant Transactions Summary

tenant_transactions_summary

Tenant Unpaid Charges Summary

tenant_unpaid_charges_summary

Tenant Vehicle Info

tenant_vehicle_info

Unpaid Balances by Month

unpaid_balances_by_month

Report

ID

Vendor Custom Fields

vendor_custom_fields

Vendor Directory

vendor_directory

Vendor Ledger

vendor_ledger

Vendor Ledger (Enhanced)

vendor_ledger_enhanced

Vendor 1099 Summary

vendor1099

Method

Path

Operation ID

GET

/bank_accounts

get_bank_accounts

POST

/bank_accounts/bulk

post_bank_accounts_bulk

GET

/bills

get_bills

POST

/bills

post_bills

PATCH

/bills/{billId}

patch_bills_billid

POST

/bills/{BillId}/attachments

post_bills_billid_attachments

POST

/bills/bulk

post_bills_bulk

POST

/bills/bulk/async

post_bills_bulk_async

GET

/charges

get_charges

POST

/charges

post_charges

POST

/charges/{ChargeId}/attachments

post_charges_chargeid_attachments

POST

/charges/bulk

post_charges_bulk

POST

/charges/bulk/async

post_charges_bulk_async

GET

/delinquent_charges

get_delinquent_charges

GET

/gl_accounts

get_gl_accounts

POST

/gl_accounts/bulk

post_gl_accounts_bulk

GET

/gl_details

get_gl_details

GET

/journal_entries

get_journal_entries

POST

/journal_entries

post_journal_entries

PATCH

/journal_entries/{JournalEntryId}

patch_journal_entries_journalentryid

POST

/journal_entries/{JournalEntryId}/attachments

post_journal_entries_journalentryid_attachments

POST

/journal_entries/bulk

post_journal_entries_bulk

GET

/late_fee_policies

get_late_fee_policies

POST

/late_fee_policies/bulk

post_late_fee_policies_bulk

GET

/payables

get_payables

GET

/recurring_charges

get_recurring_charges

POST

/recurring_charges

post_recurring_charges

PATCH

/recurring_charges/{recurringChargeId}

patch_recurring_charges_recurringchargeid

POST

/recurring_charges/bulk

post_recurring_charges_bulk

GET

/tenant_ledgers

get_tenant_ledgers

Method

Path

Operation ID

GET

/ca/associations

get_ca_associations

GET

/ca/bank_balances

get_ca_bank_balances

GET

/ca/board_members

get_ca_board_members

GET

/ca/homeowner_ledgers

get_ca_homeowner_ledgers

GET

/ca/homeowners

get_ca_homeowners

GET

/ca/renters

get_ca_renters

GET

/ca/rules

get_ca_rules

GET

/ca/units

get_ca_units

GET

/ca/violations

get_ca_violations

POST

/ca/violations

post_ca_violations

PATCH

/ca/violations/{violationId}

patch_ca_violations_violationid

POST

/ca/violations/{violationId}/attachments

post_ca_violations_violationid_attachments

Method

Path

Operation ID

GET

/corporate_entities

get_corporate_entities

POST

/corporate/gl_accounts/bulk

post_corporate_gl_accounts_bulk

Method

Path

Operation ID

GET

/custom_fields

get_custom_fields

Method

Path

Operation ID

GET

/leads

get_leads

POST

/leads

post_leads

POST

/leads/{GuestCardId}/notes

post_leads_guestcardid_notes

PATCH

/leads/{GuestCardId}/notes/{Id}

patch_leads_guestcardid_notes_id

PATCH

/leads/{leadId}

patch_leads_leadid

GET

/leads/notes

get_leads_notes

GET

/leases

get_leases

PATCH

/leases/{LeaseId}

patch_leases_leaseid

GET

/leases/renewal_pricings

get_leases_renewal_pricings

PUT

/leases/renewal_pricings/bulk

put_leases_renewal_pricings_bulk

GET

/listings

get_listings

GET

/rental_applications

get_rental_applications

PATCH

/rental_applications/{rentalApplicationId}

patch_rental_applications_rentalapplicationid

POST

/rental_applications/{RentalApplicationId}/attachments

post_rental_applications_rentalapplicationid_attachments

POST

/rental_applications/{RentalApplicationId}/notes

post_rental_applications_rentalapplicationid_notes

PATCH

/rental_applications/{RentalApplicationId}/notes/{Id}

patch_rental_applications_rentalapplicationid_notes_id

GET

/rental_applications/notes

get_rental_applications_notes

GET

/showings

get_showings

POST

/showings

post_showings

PATCH

/showings/{showingId}

patch_showings_showingid

Method

Path

Operation ID

POST

/inspections

post_inspections

DELETE

/inspections/{InspectionId}

delete_inspections_inspectionid

PATCH

/inspections/{InspectionId}

patch_inspections_inspectionid

POST

/inspections/{InspectionId}/attachments

post_inspections_inspectionid_attachments

POST

/inspections/bulk

post_inspections_bulk

GET

/inventories

get_inventories

POST

/inventories

post_inventories

DELETE

/inventories/{Id}

delete_inventories_id

PATCH

/inventories/{Id}

patch_inventories_id

POST

/inventories/bulk

post_inventories_bulk

GET

/inventory_locations

get_inventory_locations

POST

/inventory_locations

post_inventory_locations

PATCH

/inventory_locations/{Id}

patch_inventory_locations_id

POST

/inventory_locations/bulk

post_inventory_locations_bulk

GET

/vendors

get_vendors

POST

/vendors

post_vendors

PATCH

/vendors/{vendorId}

patch_vendors_vendorid

POST

/vendors/{VendorId}/notes

post_vendors_vendorid_notes

PATCH

/vendors/{VendorId}/notes/{Id}

patch_vendors_vendorid_notes_id

POST

/vendors/bulk

post_vendors_bulk

GET

/vendors/notes

get_vendors_notes

GET

/work_orders

get_work_orders

POST

/work_orders

post_work_orders

PATCH

/work_orders/{workOrderId}

patch_work_orders_workorderid

POST

/work_orders/{WorkOrderId}/attachments

post_work_orders_workorderid_attachments

DELETE

/work_orders/{WorkOrderId}/attachments/{AttachmentId}

delete_work_orders_workorderid_attachments_attachmentid

POST

/work_orders/{WorkOrderId}/notes

post_work_orders_workorderid_notes

PATCH

/work_orders/{WorkOrderId}/notes/{Id}

patch_work_orders_workorderid_notes_id

GET

/work_orders/attachments

get_work_orders_attachments

Method

Path

Operation ID

GET

/owner_groups

get_owner_groups

POST

/owner_groups

post_owner_groups

PATCH

/owner_groups/{id}

patch_owner_groups_id

GET

/owners

get_owners

POST

/owners

post_owners

GET

/owners/{ownerId}

get_owners_ownerid

PATCH

/owners/{ownerId}

patch_owners_ownerid

POST

/owners/{OwnerId}/attachments

post_owners_ownerid_attachments

POST

/owners/{OwnerId}/notes

post_owners_ownerid_notes

PATCH

/owners/{OwnerId}/notes/{Id}

patch_owners_ownerid_notes_id

GET

/owners/attachments

get_owners_attachments

POST

/owners/bulk

post_owners_bulk

GET

/owners/notes

get_owners_notes

GET

/tenants

get_tenants

PATCH

/tenants/{tenantId}

patch_tenants_tenantid

POST

/tenants/{TenantId}/notes

post_tenants_tenantid_notes

PATCH

/tenants/{TenantId}/notes/{Id}

patch_tenants_tenantid_notes_id

PATCH

/tenants/bulk

patch_tenants_bulk

POST

/tenants/bulk

post_tenants_bulk

GET

/tenants/notes

get_tenants_notes

GET

/users

get_users

Method

Path

Operation ID

POST

/occupancies/{OccupancyId}/attachments

post_occupancies_occupancyid_attachments

GET

/occupancies/documents

get_occupancies_documents

GET

/portfolios

get_portfolios

PATCH

/portfolios/{portfolioId}

patch_portfolios_portfolioid

GET

/properties

get_properties

PATCH

/properties/{propertyId}

patch_properties_propertyid

POST

/properties/{PropertyId}/attachments

post_properties_propertyid_attachments

POST

/properties/{PropertyId}/marketing_photos

post_properties_propertyid_marketing_photos

DELETE

/properties/{PropertyId}/marketing_photos/{MarketingPhotoId}

delete_properties_propertyid_marketing_photos_marketingphotoid

PATCH

/properties/{PropertyId}/marketing_photos/{MarketingPhotoId}

patch_properties_propertyid_marketing_photos_marketingphotoid

POST

/properties/{PropertyId}/notes

post_properties_propertyid_notes

PATCH

/properties/{PropertyId}/notes/{Id}

patch_properties_propertyid_notes_id

POST

/properties/{PropertyId}/photos

post_properties_propertyid_photos

DELETE

/properties/{PropertyId}/photos/{PhotoId}

delete_properties_propertyid_photos_photoid

PATCH

/properties/{PropertyId}/photos/{PhotoId}

patch_properties_propertyid_photos_photoid

GET

/properties/attachments

get_properties_attachments

POST

/properties/bulk

post_properties_bulk

GET

/properties/marketing_photos

get_properties_marketing_photos

GET

/properties/notes

get_properties_notes

GET

/properties/photos

get_properties_photos

GET

/property_groups

get_property_groups

PATCH

/property_groups/{propertyGroupId}

patch_property_groups_propertygroupid

GET

/unit_types

get_unit_types

PATCH

/unit_types/{unitTypeId}

patch_unit_types_unittypeid

POST

/unit_types/bulk

post_unit_types_bulk

GET

/units

get_units

PATCH

/units/{unitId}

patch_units_unitid

POST

/units/{UnitId}/attachments

post_units_unitid_attachments

POST

/units/{UnitId}/notes

post_units_unitid_notes

PATCH

/units/{UnitId}/notes/{Id}

patch_units_unitid_notes_id

POST

/units/{UnitId}/photos

post_units_unitid_photos

DELETE

/units/{UnitId}/photos/{PhotoId}

delete_units_unitid_photos_photoid

PATCH

/units/{UnitId}/photos/{PhotoId}

patch_units_unitid_photos_photoid

PUT

/units/{UnitId}/pricing_matrices

put_units_unitid_pricing_matrices

GET

/units/attachments

get_units_attachments

POST

/units/bulk

post_units_bulk

GET

/units/notes

get_units_notes

GET

/units/photos

get_units_photos

PUT

/units/pricing_matrices/bulk

put_units_pricing_matrices_bulk

PUT

/units/pricing_matrices/bulk/async

put_units_pricing_matrices_bulk_async

Method

Path

Operation ID

GET

/jobs

get_jobs

Contributing

Contributions and issues are welcome. Please open an issue first before submitting a PR.

License

AGPL-3.0: free for personal and open-source use. Organizations that cannot comply with the AGPL can purchase a commercial license, and hosted/managed versions are available. See COMMERCIAL.md or contact hello@nightsquawk.tech.

For copyright concerns or takedown requests, contact hello@nightsquawk.tech.

Available Tools

6 tools
call_endpointA

Call an AppFolio Database API endpoint and return its JSON response. Validates the operationId and required path params against the catalog before calling AppFolio, then executes (GET reads are auto-paginated; POST/PATCH/PUT/DELETE writes execute live against your AppFolio database). Use describe_endpoint first to learn the exact params and body.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full burden - and it does well: it discloses that GET reads are auto-paginated, that write operations execute live against the database (a significant side-effect disclosure), and that it validates against a catalog before calling. It falls just short of 5 because it doesn't explicitly note result size limits, rate limits, or what happens on validation failure, though the schema's pagination default of 1000 partially fills this gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, zero filler. Front-loaded with the primary purpose, then the payload structure. Every clause earns its place, covering validation, execution mode, pagination, and the prerequisite workflow without redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, generic dispatch tool (no output schema, nested objects, many free-form params), the description explains the overall execution model, safety difference between reads and writes, and the prerequisite (describe_endpoint). It's fairly complete given the inherent genericness of the tool. Slight gap: it doesn't describe error/response format or note limits, but given the tool is inherently generic across many endpoints, the description realistically cannot enumerate every behavior, so 4 is appropriate.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate - and it partially does by explaining the flow of validation and pagination. However, the parameter-level semantics are mostly carried by the schema's own per-field descriptions (filters, paginate_results, body, etc.) which are detailed. The description adds value by explaining the GET-write behavioral distinction and the describe_endpoint prerequisite, but doesn't explain the filters wrapper or pagination fields - those are already in the schema, which does the heavy lifting for parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description states a specific verb+resource ('Call an AppFolio Database API endpoint and return its JSON response') and clearly outlines the execution flow (validates operationId, auto-paginates GET reads, executes live writes). It distinguishes from siblings by explicitly referencing describe_endpoint and list_endpoints as the setup tools, establishing a clear division of labor within the tool family.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives explicit guidance on when to use this tool: 'Use describe_endpoint first to learn the exact params and body.' It also clarifies behavioral differences between GET (auto-paginated) and POST/PATCH/PUT/DELETE (live writes), helping the agent understand when live writes occur versus safe reads. This functional distinction is effectively an implied when-to-use/alternatives guideline given sibling tools are list/describe functions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_endpointA

Get the full specification for a single AppFolio Database API endpoint: HTTP method, path and path params, query filters (GET), request body schema with nested attributes (writes), response fields, and a request sample. Call this before call_endpoint to know exactly which parameters to pass.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. While it accurately describes the tool's behavior (retrieving endpoint specs, not executing them), it doesn't disclose what happens on invalid operation_id, whether the full response fields might be extensive, or potential size/rate implications. However, since this is a fundamentally read-only, low-risk metadata tool, the description is adequate but could note error behavior for invalid operationIds.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense sentence plus one directive sentence. It front-loads the purpose and packs a substantial amount of concrete detail (method, path, params, filters, request body, response fields, sample). The only minor inefficiency is the length of the enumeration, but every element is informative. No wasted words.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a metadata/read tool with just one parameter and no output schema, the description covers the essentials: what it returns (full spec contents), when to use it (before call_endpoint), and how to identify the target (operation_id examples). It could improve by noting the handle for invalid/unknown operation_ids, but overall it's quite complete for a tool of this simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, meaning the schema provides no description for the operation_id parameter. However, the description compensates by explaining operation_id is an 'endpoint operationId' with examples ('get_tenants', 'post_bills') and references list_endpoints as the source. While it doesn't fully explain what an operationId is or its format constraints, the examples plus context are reasonable. The 0% coverage means the description must compensate, and it does partially.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Get' with a clear resource: 'the full specification for a single AppFolio Database API endpoint'. It enumerates exactly what the specification contains (method, path, query filters, request body, response fields, request sample). This clearly distinguishes it from siblings like list_endpoints (which lists endpoints) and call_endpoint (which executes them).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance is provided: 'Call this before call_endpoint to know exactly which parameters to pass.' This gives a clear when-to-use directive and names the specific alternative it pairs with, establishing a workflow. The contrast with call_endpoint makes the usage context unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

describe_reportA

Get the full parameter specification for a single AppFolio report: required and optional filters, types, enums, defaults, nested attributes, and response columns. Call this before run_report to know exactly which parameters to pass.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must convey behavioral traits. It states the tool returns a specification, implying a read-only operation, and details the contents (filters, types, enums, defaults, etc.). However, it does not discuss permissions, error behavior, or side effects, which is a moderate gap given the lack of annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences, front-loaded with the core purpose, and includes a helpful usage tip. Every word adds value—no fluff, no redundancy—making it highly concise and well-structured.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple with one parameter and no output schema. The description adequately explains the purpose and usage but fails to explicitly identify the input parameter or discuss potential errors/auth. Given the simplicity, it is minimally sufficient but not comprehensive.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description does not mention the actual parameter 'report_name' or its type/format, leaving the agent to infer it from the schema. The schema does provide a description and example, but the tool description fails to compensate for the 0% schema description coverage in the text, making the semantics unclear without relying on structured data.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Get the full parameter specification for a single AppFolio report.' The verb 'Get' plus the resource 'parameter specification' make it evident, and it distinguishes itself from siblings like list_reports (which lists reports) and run_report (which executes reports).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly says 'Call this before run_report to know exactly which parameters to pass,' which provides a clear usage context. It does not explicitly mention alternatives or exclusions, but the guidance to call before run_report is actionable and sufficient for choosing this tool over siblings.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_endpointsA

List the available AppFolio Database API endpoints (operationId, method, path, category, description). Optionally filter by category, resource, method, or reads-only. Use this to discover which endpoint to use, then call describe_endpoint for its parameters and call_endpoint to execute it. This is the AppFolio v0 Database API (records/CRUD), distinct from the Reporting API (list_reports/run_report).

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. The description discloses the filter capabilities (category, resource, method, reads-only) and the API version (v0), which is useful, but does not describe pagination behavior, output volume, or whether results are ordered. It does convey listing/discovery semantics effectively, though the scale of results is not addressed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact (three sentences) and front-loaded with the core purpose, followed by the optional filter capabilities, then workflow guidance. Every sentence adds value with zero waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a discovery/listing tool with no output schema, the description covers purpose, filters, workflow linkage to sibling tools, and API/version differentiation. It lacks explicit note on return volume/pagination, which is a minor gap for a listing tool that could return many endpoints. Overall it is well-rounded and sufficient for an agent to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, but the parameters are wrapped in a 'params' object with individual property descriptions in the schema that are reasonably self-explanatory (method, category, resource, reads_only each have filtering descriptions with examples). The description adds workflow context but the parameter meanings are largely conveyed through the schema's property-level descriptions rather than the tool description itself.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states 'List the available AppFolio Database API endpoints' with specific output fields (operationId, method, path, category, description). It distinguishes this discovery tool from siblings by naming describe_endpoint (for params) and call_endpoint (for execution), and explicitly contrasts the Database API with the Reporting API (list_reports/run_report).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit workflow guidance: 'Use this to discover which endpoint to use, then call describe_endpoint for its parameters and call_endpoint to execute it.' It also names the alternative toolset for Reporting API, giving clear when-to-use vs when-not-to-use context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reportsA

List the available AppFolio reports (slug, name, category, required filters). Optionally filter by category. Use this to discover which report to run, then call describe_report for its parameters and run_report to execute it.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A4.3/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses that filtering is optional and that it returns a listing rather than data. However, it doesn't disclose pagination, response volume, or whether 'required filters' are full or abbreviated. For a read-only listing tool, the disclosure is adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences that are dense with information - return fields, filtering behavior, workflow guidance, and sibling-tool routing. No filler. Slightly longer than strictly minimal, but each clause earns its place by aiding agent selection and next steps.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a discovery/list tool with one optional parameter and no output schema, the description is quite complete. It covers purpose, output contents, filtering, and next-step routing. The main omission is lacking detail on the structure of the returned list (e.g., whether required filters come as a list or string), but this is modest for a discovery tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0% for the single category parameter, but the description compensates well by explaining what category does, providing examples ('Financial', 'Leasing', 'Tenant'), noting it's optional, and advising to omit it initially to see all categories. This adds meaningful usage insight beyond the raw schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource ('List the available AppFolio reports') and enumerates the return fields (slug, name, category, required filters), which clearly distinguishes it from siblings like run_report, describe_report, and call_endpoint. It also explains the tool's role in the discovery workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use ('to discover which report to run') and how it fits with alternatives ('then call describe_report for its parameters and run_report to execute it'), naming sibling tools directly. It also explains the category filtering use case and suggests 'call without args first to see all categories'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_reportA

Run an AppFolio report and return its rows. Validates the report name, required filters, and parameter names against the report catalog before calling AppFolio. Use describe_report first to learn the exact filter keys for the report.

ParametersJSON Schema
NameRequiredDescriptionDefault
paramsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. It discloses that the tool validates against a report catalog before calling AppFolio, implying pre-flight checks. It mentions required filters must be included or the request is rejected, which is a useful behavioral constraint. However, it doesn't disclose potential rate limits, error behaviors beyond validation, or what happens on partial failures; still, the validation disclosure is substantive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences that each earn their place: the first states the primary action and validates, the second gives critical usage guidance (use describe_report first). No filler, no redundancy with the schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has nested objects (params > report_name required, filters as arbitrary JSON object), no output schema, and no annotations. The description handles this well by pointing to describe_report for filter keys and stating the validation behavior, which collectively inform the agent how to construct a valid call. It covers the critical unknowns (required filters, parameter naming), though paginate_results behavior is left to the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must compensate. It references describe_report for filter keys, which directs the agent to the authoritative source for parameter semantics. It explains that filters must match parameter names from describe_report. However, the description itself doesn't detail individual parameter formats beyond pointing to describe_report, so the agent must do a follow-up lookup; still, this is a reasonable delegation given the report-specific nature of filters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states the tool's function: 'Run an AppFolio report and return its rows.' It names the specific verb (run), resource (AppFolio report), and outcome (return rows). It distinguishes from siblings: list_reports lists available reports while this executes them, and call_endpoint/describe_endpoint target endpoints rather than reports.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit guidance provided: 'Use describe_report first to learn the exact filter keys for the report.' This clearly instructs the agent on the prerequisite step before invocation. The description also clarifies validation behavior (validates report name, required filters, parameter names against the catalog), setting expectations that malformed calls will be rejected.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 6 tool updatesv0.1.0
    • First observedcall_endpoint
    • First observeddescribe_endpoint
    • First observeddescribe_report
    • First observedlist_endpoints
    • First observedlist_reports
    • First observedrun_report

TDQS

A4.4/5.0
Disambiguation5/5

The tools clearly separate into two distinct domains: reporting (list_reports, describe_report, run_report) and database API (list_endpoints, describe_endpoint, call_endpoint). Within each domain, the list/describe/execute functions have unambiguous roles, making misselection highly unlikely.

Naming Consistency5/5

All tool names follow a consistent lowercase verb_noun pattern (list_, describe_, run_, call_). The naming clearly indicates both the action and the target resource, with no mixing of conventions or vague verbs.

Tool Count5/5

With exactly 6 tools, the server is well-scoped. It covers two complementary API surfaces (reports and database endpoints) with a discover-describe-execute pattern for each, and every tool serves a distinct and necessary role.

Completeness5/5

The toolset fully covers the intended workflow for both reports and database endpoints: discover available options, inspect detailed parameters, and execute the operation. There are no obvious missing operations or dead ends, as call_endpoint handles all HTTP methods and reports are predefined resources.

Maintenance

ActivitySlowing
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    C
    maintenance
    A read-only MCP server for AppDynamics that exposes 12 task-oriented tools to query applications, topology, metrics, snapshots, health rules, anomalies, events, alerting config, analytics events, and dependency maps via OAuth API-client credentials.
    12
    1
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A read-only MCP server providing 56 tools to query Qobrix real-estate CRM data, covering listings, leads, viewings, offers, contracts, analytics, and more, with RESO Data Dictionary alignment and caching support.
    64
    3
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Unified MCP server for ArcGIS Online and Enterprise providing tools for user/group management, item management, geoprocessing, feature layer queries/editing, and server administration.
    2
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol (MCP) server that wraps AppFolio's REST API so Claude can call it natively in any conversation. 38 tools covering portfolio structure, leasing, financials, maintenance, and admin.
    1
    -

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NightSquawk/appfolio-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server