Method CRM MCP by usefulapi

Query Method CRM customers, leads, activities and invoices; create and update records.

¿Debería usar esto?

Calidad y seguridad

A
Calidad de la descripción
100%
Integridad del esquema
88%
Calidad de los nombres
80%
Riesgo de envenenamiento
100%
Coincidencia de permisos
100%
Cumplimiento del protocolo
100%

Basado en el análisis automatizado de las definiciones de herramientas y el cumplimiento del protocolo.

Costo de contexto

~5,181Tokens (definiciones de herramientas)
~2.2 KBTamaño de respuesta típico
Impacto significativo en la atención (4.05% del contexto de 128k)

Este es el número aproximado de tokens que se consumen cada vez que las herramientas del servidor se cargan en el contexto de un modelo. Los recuentos más altos reducen la atención disponible para otras tareas.

Instalar

Instalación con un clic

Agrega esto a tu archivo `claude_desktop_config.json`:

{
  "mcpServers": {
    "method-crm": {
      "url": "https://method-crm.usefulapi.io/mcp"
    }
  }
}

Puntos de conexión remotos

https://method-crm.usefulapi.io/mcpstreamable-http

Qué puede hacer

Inventario de herramientas

Herramientas (16)

🟢 Solo lectura🟡 Escritura🔴 Eliminación⚪ Desconocido
🟢method_get_account

Who the API key acts as: the Method user behind it (id and name; use the id as an assignee). Also a cheap check that the key works. GET /api/v1/me.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_list_tables

List every table on this Method account (standard QuickBooks/Xero/Method tables and custom ones) with its source and whether it can be created, updated or deleted. Tables differ per account: call this before querying a table you are unsure of. GET /api/v1/tables.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_get_table_fields(table)

The exact field names of a table with type, whether required, creatable and mutable, and for dropdowns the table they reference. Use it to pick `select` fields and to name fields in create/update calls (names are case-sensitive and wrong ones are silently ignored). GET /api/v1/tables/{table}/fields.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    }
  },
  "required": [
    "table"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_query_records(table, select, filter, orderby, apply, ...)

Query any table (Customer, Contacts, Activity, Invoice, Estimate, Item, Users, custom tables ...). Always pass `select`. `filter` uses OData-style syntax: strings in single quotes, dates as '2026-05-26T00:00:00Z' with Z or an offset, operators eq ne lt gt le ge and or not, functions contains(Name,'x') startswith() endswith(); e.g. "BalanceRemaining gt 0 and DueDate lt '2026-10-01T00:00:00Z'". `apply` runs server-side aggregation instead of listing rows, e.g. "aggregate(BalanceRemaining with sum as Outstanding)" or "groupby((Customer), aggregate(Amount with sum as Total))". Default order is RecordID ascending (stable paging); page with next_skip. GET /api/v1/tables/{table}.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "filter": {
      "description": "Filter expression, e.g. \"IsLeadStatusOnly eq true and contains(Name,'Smith')\".",
      "type": "string",
      "minLength": 1,
      "maxLength": 1500
    },
    "orderby": {
      "description": "Sort, e.g. \"RecordID desc\" or \"TotalBalance desc,RecordID\".",
      "type": "string",
      "minLength": 1,
      "maxLength": 300,
      "pattern": "^[A-Za-z0-9_, ]+$"
    },
    "apply": {
      "description": "Aggregation, e.g. \"aggregate($count as Total)\"; ignores paging.",
      "type": "string",
      "minLength": 1,
      "maxLength": 1500
    },
    "top": {
      "description": "Rows per page, 1-100 (default 25).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "skip": {
      "description": "Rows to skip (default 0). Pass the previous reply's next_skip.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000000
    }
  },
  "required": [
    "table"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_count_records(table, filter)

How many records a table has, optionally matching a filter (same filter syntax as method_query_records). Cheap: call it before paging through a big table. GET /api/v1/tables/{table}/count.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "filter": {
      "description": "Filter expression.",
      "type": "string",
      "minLength": 1,
      "maxLength": 1500
    }
  },
  "required": [
    "table"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_get_record(table, record_id, select, expand)

One record by RecordID from any table. Pass `select` to limit the columns; `expand` names a related CHILD table whose rows are embedded (e.g. InvoiceLine on Invoice; at most 50 rows); a parent such as a contact's Entity is not expanded: read it with its own RecordID (Entity_RecordID). GET /api/v1/tables/{table}/{recordId}.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "record_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647,
      "description": "The record's RecordID."
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "expand": {
      "description": "A child table to embed (a table with a dropdown field to this one), e.g. InvoiceLine on Invoice. At most 50 child rows.",
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
    }
  },
  "required": [
    "table",
    "record_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_search_customers(text, kind, active_only, select, top, ...)

Find customers and leads (the Customer table: Customers & Leads in Method) by text in the name or email, by lead/customer type, or list them all. Returns RecordID, name, email, phone, lead flag and status; override `select` for other fields (see method_get_table_fields with table Customer). Page with next_skip. GET /api/v1/tables/Customer.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "text": {
      "description": "Matches records whose Name or Email contains this text (case-insensitive).",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "kind": {
      "description": "leads = IsLeadStatusOnly true, customers = false (default all).",
      "type": "string",
      "enum": [
        "all",
        "leads",
        "customers"
      ]
    },
    "active_only": {
      "description": "Only active records (IsActive true).",
      "type": "boolean"
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "top": {
      "description": "Rows per page, 1-100 (default 25).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "skip": {
      "description": "Rows to skip (default 0). Pass the previous reply's next_skip.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_list_contacts(entity_id, text, select, top, skip)

List contacts (people), optionally those of one customer/lead entity (entity_id = the Customer's RecordID) or matching text in name/email/phone. Returns RecordID, name, email, phone, the entity link and active flag. Use a Contact's RecordID (not the Customer's) when linking activities. GET /api/v1/tables/Contacts.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "entity_id": {
      "description": "Only contacts of this entity (the Customer/Vendor RecordID).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "text": {
      "description": "Matches contacts whose Name, Email or Phone contains this text.",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "top": {
      "description": "Rows per page, 1-100 (default 25).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "skip": {
      "description": "Rows to skip (default 0). Pass the previous reply's next_skip.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_list_activities(entity_id, assigned_to_id, due_after, due_before, select, ...)

List activities (calls, emails, to-dos, notes), newest first. Filter by the entity they belong to, the assigned user or a due-date window. The note text is in Comments. Override `select` for other fields (method_get_table_fields with table Activity). GET /api/v1/tables/Activity.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "entity_id": {
      "description": "Only activities of this entity (Customer RecordID).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "assigned_to_id": {
      "description": "Only activities assigned to this user id (method_get_account or the Users table).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "due_after": {
      "type": "string",
      "description": "ISO 8601 date-time WITH a timezone (Z or +hh:mm), e.g. 2026-10-01T00:00:00Z."
    },
    "due_before": {
      "type": "string",
      "description": "ISO 8601 date-time WITH a timezone (Z or +hh:mm), e.g. 2026-10-01T00:00:00Z."
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "top": {
      "description": "Rows per page, 1-100 (default 25).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "skip": {
      "description": "Rows to skip (default 0). Pass the previous reply's next_skip.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_list_invoices(customer_id, unpaid_only, created_since, select, top, ...)

List invoices, newest first, optionally only unpaid ones (BalanceRemaining > 0), one customer's (customer_id = Customer RecordID) or created since a time. Returns reference number, customer, dates, amount and balance; override `select` for other fields. For totals use method_query_records with `apply`. GET /api/v1/tables/Invoice.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "customer_id": {
      "description": "Only invoices of this customer (Customer RecordID).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "unpaid_only": {
      "description": "Only invoices with an outstanding balance.",
      "type": "boolean"
    },
    "created_since": {
      "type": "string",
      "description": "ISO 8601 date-time WITH a timezone (Z or +hh:mm), e.g. 2026-10-01T00:00:00Z."
    },
    "select": {
      "minItems": 1,
      "maxItems": 60,
      "type": "array",
      "items": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "description": "Field names to return (case-sensitive, from method_get_table_fields). Without a select Method returns hundreds of columns per row."
    },
    "top": {
      "description": "Rows per page, 1-100 (default 25).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "skip": {
      "description": "Rows to skip (default 0). Pass the previous reply's next_skip.",
      "type": "integer",
      "minimum": 0,
      "maximum": 10000000
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_list_files(table, record_id)

List the files attached to a record (name, size, who added it, id). Use the id with method_get_file_url. GET /api/v1/files.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "record_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647,
      "description": "The record's RecordID."
    }
  },
  "required": [
    "table",
    "record_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢method_get_file_url(file_id)

A temporary download link (valid 20 minutes) for an attached file, by the file id from method_list_files. The link works without the API key: share it only with someone allowed to see the file. GET /api/v1/files/{id}/url.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "file_id": {
      "type": "string",
      "pattern": "^[A-Za-z0-9-]{8,64}$",
      "description": "File id (a GUID)."
    }
  },
  "required": [
    "file_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴method_create_customer(name, is_lead, first_name, last_name, email, ...)

WRITE: creates a record in Method's Customer table. is_lead true = a Customer Lead (does not sync to the accounting system); is_lead false = a full customer, which Method syncs to QuickBooks/Xero (it appears there too). Method also creates the primary Contact; its RecordID is returned as contact_id when it could be found (use it, not the customer id, to link activities). Name is required (for a person with no company use "First Last"). `extra_fields` sets other fields by their exact names (see method_get_table_fields, table Customer). Not idempotent: calling twice creates two records, so search first (method_search_customers). POST /api/v1/tables/Customer.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "Display name of the customer or lead."
    },
    "is_lead": {
      "type": "boolean",
      "description": "true = lead (not synced to accounting), false = customer (synced to QuickBooks/Xero)."
    },
    "first_name": {
      "type": "string",
      "maxLength": 100
    },
    "last_name": {
      "type": "string",
      "maxLength": 100
    },
    "email": {
      "type": "string",
      "maxLength": 254
    },
    "phone": {
      "type": "string",
      "maxLength": 50
    },
    "lead_status": {
      "description": "Account-defined lead status, e.g. Open (leads only).",
      "type": "string",
      "maxLength": 100
    },
    "assigned_to_id": {
      "description": "Owner: a Method user id (method_get_account, or the Users table).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "extra_fields": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 8000
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ]
      },
      "description": "Field name -> value, exactly as method_get_table_fields names them (case-sensitive; a misspelled name is silently ignored by Method). For a dropdown/linked field send the integer id in its `_RecordID` field (e.g. Customer_RecordID: 1234), not the caption."
    }
  },
  "required": [
    "name",
    "is_lead"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴method_create_activity(entity_id, comments, activity_type_id, activity_type, contact_id, ...)

WRITE: logs an activity (call, email, to-do, note) on a customer/lead. entity_id is the Customer RecordID; contact_id is the Contact RecordID (not the Customer's; method_list_contacts finds it). The text goes in Comments. Prefer activity_type_id (read it from an existing activity of that type) over the caption activity_type: a caption that matches zero or several options is silently dropped. Method requires an assignee on standard accounts. The reply re-reads the activity so you can check the links were stored (field names are account-specific; method_get_table_fields with table Activity shows them). It does not email anyone. Not idempotent. POST /api/v1/tables/Activity.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "entity_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647,
      "description": "The Customer (entity) RecordID the activity belongs to, so it shows in its history."
    },
    "comments": {
      "type": "string",
      "minLength": 1,
      "maxLength": 8000,
      "description": "The note body."
    },
    "activity_type_id": {
      "description": "ActivityType_RecordID from an existing activity of the wanted type.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "activity_type": {
      "description": "Activity type caption, e.g. Call. Use only if you have no id.",
      "type": "string",
      "minLength": 1,
      "maxLength": 100
    },
    "contact_id": {
      "description": "The Contact RecordID.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "assigned_to_id": {
      "description": "Method user id of the owner (method_get_account).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "status_id": {
      "description": "ActivityStatus_RecordID (account-defined, e.g. Not Started / Completed).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647
    },
    "due": {
      "description": "Due/start time, YYYY-MM-DDTHH:mm:ss.",
      "type": "string"
    }
  },
  "required": [
    "entity_id",
    "comments"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴method_create_record(table, fields)

WRITE: creates a record in any table that allows it (method_list_tables shows canCreate), e.g. Estimate, Invoice, Item, Vendor. For customers/leads and activities use the dedicated tools. Field names are case-sensitive and a wrong one is silently ignored: read them with method_get_table_fields first, and send dropdown links as their `_RecordID` integer. Creating accounting records (Invoice, Estimate, Customer ...) makes Method sync them to QuickBooks/Xero. Child lines (InvoiceLine ...) are not supported here. Not idempotent. Returns the new RecordID. POST /api/v1/tables/{table}.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "fields": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 8000
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ]
      },
      "description": "Field name -> value, exactly as method_get_table_fields names them (case-sensitive; a misspelled name is silently ignored by Method). For a dropdown/linked field send the integer id in its `_RecordID` field (e.g. Customer_RecordID: 1234), not the caption."
    }
  },
  "required": [
    "table",
    "fields"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴method_update_record(table, record_id, fields)

WRITE: changes fields on one record (PATCH: only the fields you pass change). Field names are case-sensitive and Method silently ignores wrong or read-only names, so the reply re-reads the record and shows the stored values of the fields you sent: check them. Linked fields are changed through their `_RecordID` integer field. Updating accounting records (Customer, Invoice ...) makes Method sync the change to QuickBooks/Xero; setting IsLeadStatusOnly to false converts a lead into a synced customer. There is no delete tool. PATCH /api/v1/tables/{table}/{recordId}.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "table": {
      "type": "string",
      "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$",
      "description": "Table name exactly as method_list_tables shows it, e.g. Customer, Contacts, Activity, Invoice, Estimate."
    },
    "record_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 2147483647,
      "description": "The record's RecordID."
    },
    "fields": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "pattern": "^[A-Za-z][A-Za-z0-9_]{0,63}$"
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 8000
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          },
          {
            "type": "null"
          }
        ]
      },
      "description": "Field name -> value, exactly as method_get_table_fields names them (case-sensitive; a misspelled name is silently ignored by Method). For a dropdown/linked field send the integer id in its `_RecordID` field (e.g. Customer_RecordID: 1234), not the caption."
    }
  },
  "required": [
    "table",
    "record_id",
    "fields"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Comunidad

Califica este servidor

Evidencia

Observaciones recientes

verificadoversión no registrada16 herramientas