Skip to main content
Glama
README.md
# recordcrm

recordcrm is a small client for the Attio CRM: it searches records
with free-text or structured filters, creates records in any object,
reads a single record or an attribute's definition and options,
creates and updates company and deal records, lists workspace lists
and their entries, and looks up workspace members — all through the
Attio API v2.

This package is a clean-room rebuild, and a **labelled core subset**:
it covers 12 of the 19 universal operations plus scoped writes
documented for the original Attio MCP server. The omitted operations
are listed under "Scope" below.

## How it talks to the service

Every tool needs an Attio API token:

```bash
export ATTIO_API_KEY="your token"
# ATTIO_ACCESS_TOKEN is accepted as a fallback when ATTIO_API_KEY is unset.
# Optional override (default: https://api.attio.com/v2)
export ATTIO_API_URL="https://api.attio.com/v2"
```

With no token set, every call fails with an error naming
`ATTIO_API_KEY`, before any request is made.

**Wire-format note:** the original project's README documents the
tools and their purposes; the endpoint shapes here follow the public
Attio API v2 and are documented reconstructions. Records live under
`/v2/objects/{object}/records`; record search posts to the records
query endpoint (`.../records/query`) with a `full_text` query clause
when a query is given, or a `filter` object for advanced search;
writes wrap attribute values as `{ "data": { "values": ... } }`;
attribute options are read from the attribute definition at
`/v2/objects/{object}/attributes/{attribute}`. Responses are parsed
as JSON (an empty success body reads as `{ "status": "ok" }`), and
an upstream HTTP error is reported with its status and body text.

## Install

```bash
npx @reneturcios/recordcrm records_search '{"object":"companies","query":"acme"}'
```

Or run the container image:

```bash
docker run -i ghcr.io/cloudcorprecords/recordcrm
```

The container defaults to the MCP server. Pass CLI arguments to use
it as a CLI instead.

## CLI

The CLI mirrors the tools: one subcommand per tool, taking its
arguments as a single JSON object.

```bash
recordcrm records_search '{"object":"companies","query":"acme","limit":5}'
recordcrm records_search_advanced '{"object":"companies","filters":{"name":{"$contains":"acme"}}}'
recordcrm records_create '{"object":"people","data":{"name":[{"value":"Ada"}]}}'
recordcrm records_get_info '{"object":"people","record_id":"..."}'
recordcrm lists_list '{}'
recordcrm --version
```

Exit codes: `0` on success, `1` on an API or validation error (the
error names the problem), `2` for usage errors.

## MCP server

One bin serves both faces. The `mcp` subcommand starts a stdio MCP
server:

```bash
npx -y @reneturcios/recordcrm mcp
```

MCP client configuration:

```json
{
  "mcpServers": {
    "recordcrm": {
      "command": "npx",
      "args": ["-y", "@reneturcios/recordcrm", "mcp"],
      "env": { "ATTIO_API_KEY": "your token" }
    }
  }
}
```

### Tools

| Tool | Input | What it does |
| --- | --- | --- |
| `records_search` | `object` (required), `query`, `limit` | Search records in an object by free-text query. |
| `records_search_advanced` | `object` (required), `filters` (required), `limit` | Search records in an object with structured filters. |
| `records_create` | `object` (required), `data` (required) | Create a record in an object from attribute values. |
| `records_get_info` | `object` (required), `record_id` (required) | Fetch one record by ID from an object. |
| `records_get_attribute_options` | `object` (required), `attribute` (required) | Get an attribute definition, including its select options. |
| `companies_create` | `data` (required) | Create a company record from attribute values. |
| `companies_update` | `record_id` (required), `data` (required) | Update a company record by ID. |
| `deals_create` | `data` (required) | Create a deal record from attribute values. |
| `deals_update` | `record_id` (required), `data` (required) | Update a deal record by ID. |
| `lists_list` | — | List all lists in the workspace. |
| `list_entries_list` | `list` (required), `limit` | List entries in a list. |
| `workspace_members_get` | `workspace_member_id` (required) | Fetch one workspace member by ID. |

## Scope

Omitted from this core subset: `records_search_by_relationship`,
`records_get_interactions`, `records_batch`, the universal
`records_update` / `records_delete` operations, `lists_create`,
`lists_update_configuration`, `list_entries_filter`,
`list_entries_manage`, `records_get_list_memberships`,
`diagnostics_get`, and the universal notes/tasks operations. The
original's field-mapping configuration is also not reproduced: this
subset passes attribute values and filters through in Attio API
shape directly. Search results, record contents, and list data are
produced by the upstream Attio service; this package reproduces the
tool surface and the request/response handling, not that service's
data.

## Development

```bash
npm install
npm run build   # tsc -> dist/
npm test        # node test runner over test/*.test.ts, fake fetch only, no network
npm run dev     # run the CLI from source via tsx
```

## License

MIT — see `LICENSE`.