Skip to main content
Glama

Import contacts or companies from a CSV

import_csv
Idempotent

Import contacts or companies from a CSV file: send its text as csv, or an https link to it as url (a public Google Sheets CSV link works). Columns are matched by their header names in any case or spelling: email, name, first name, last name, phone or mobile, company or organization, domain, website, title or job title, notes, address, city or country (joined into location), lifecycle stage, timezone, language; for companies: name, domain, website, industry, employees, lifecycle stage, notes. The result lists the columns it mapped and the ones it ignored. Contacts match existing ones by email, companies by domain and then by name, so importing the same file again updates instead of duplicating. Up to 5,000 rows a call: a longer file returns next_cursor to continue. Unchanged records are free, and 1,000 imported records cost $1. max_records x $0.001 is reserved while it runs and only what was imported is charged; lower max_records if your balance is smaller. Costs $0.001 per record imported (created or updated); nothing if none are found.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "import_csv"
  }
}

Input Schema

NameRequiredDescriptionDefault
csvNoThe CSV text, column names in the first row (up to about 2 MB; use url for more).
urlNoAn https link to the CSV file, instead of csv. At most 20 MB.
kindNoWhat each row is.contacts
max_recordsNoThe most rows to read in this call (5,000 at most).
next_cursorNoThe next_cursor a previous run of this import returned, to continue where it stopped.

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already declare idempotentHint=true and destructiveHint=false, and the description supplies the reason: contacts match by email, companies by domain then name, so re-importing updates instead of duplicating. It goes further with the row cap, next_cursor paging, the return value (mapped vs ignored columns), and an unusually explicit cost model including the max_records x $0.001 hold and the 'unchanged records are free' rule.

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?

Front-loaded with the action and the two input modes before moving to column semantics, matching, limits, and cost, so an agent gets the essentials in the first sentence. The cost story is restated three separate ways ($0.001 per record, 1,000 records = $1, and the max_records reservation), which is the main redundancy in an otherwise dense description.

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

Completeness5/5

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

There is no output schema, and the description compensates by stating what comes back (mapped and ignored columns, next_cursor for paging). Combined with the matching/upsert rules, row cap, and billing behavior, an agent has everything needed to call this correctly and interpret the result.

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 coverage is 100%, so the baseline is 3, but the description adds real meaning beyond the schema: how header names are matched case- and spelling-insensitively, the specific accepted column aliases and that address/city/country are joined into location, and the financial consequence of max_records. It stops short of documenting next_cursor's lifetime or url size limits beyond what the schema states.

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?

States a specific verb and resource ("Import contacts or companies from a CSV file") and immediately distinguishes the two input modes and the two record kinds. An agent can tell this apart from siblings such as import_from_hubspot, tables_import, or inventory_import without opening the schema.

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?

Gives concrete selection criteria: send text as csv or an https/most-public-Google-Sheets link as url, and advises lowering max_records if the balance is smaller than the reservation. It also explains cursor continuation for files over 5,000 rows. It does not explicitly name sibling import tools or say when not to use this one, which keeps it at 4 rather than 5.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources