> ## Documentation Index
> Fetch the complete documentation index at: https://developer.lofty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Connect an MCP client to the Lofty CRM API and make your first search → describe → invoke round trip.

This guide walks through connecting to the Lofty MCP server and calling your first operation. By the end you'll have made a full `search_apis` → `describe_api` → `invoke_api` round trip and retrieved real lead data.

<Steps>
  <Step title="Get a credential">
    You need an [API key](/authentication/api-keys) or an [OAuth 2.0](/authentication/oauth2) access token — the same credentials used for the direct REST API. If you don't have one yet, follow the [API Quickstart](/quickstart) to get one.

    <Note>
      Over MCP, always send your credential as `Authorization: Bearer <token>` — even an API key, which normally uses the `token` prefix on the direct REST API. See [Authentication](/mcp/authentication) for why.
    </Note>
  </Step>

  <Step title="Connect your MCP client">
    Point any [Streamable HTTP](https://modelcontextprotocol.io) MCP client at:

    ```
    https://mcp.lofty.com/mcp
    ```

    <CodeGroup>
      ```bash Claude Code theme={null}
      claude mcp add --transport http lofty https://mcp.lofty.com/mcp \
        --header "Authorization: Bearer YOUR_TOKEN"
      ```

      ```json Claude Desktop / JSON config theme={null}
      {
        "mcpServers": {
          "lofty": {
            "type": "http",
            "url": "https://mcp.lofty.com/mcp",
            "headers": {
              "Authorization": "Bearer YOUR_TOKEN"
            }
          }
        }
      }
      ```

      ```bash curl (no client) theme={null}
      curl https://mcp.lofty.com/mcp \
        -H "Content-Type: application/json" \
        -H "Accept: application/json, text/event-stream" \
        -d '{
          "jsonrpc": "2.0", "id": 1, "method": "initialize",
          "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "quickstart", "version": "0.1"}}
        }'
      ```
    </CodeGroup>

    Any client that speaks Streamable HTTP works the same way — consult your client's docs for its equivalent of "add a remote MCP server with a custom header." A successful `initialize` call includes `serverInfo` and an `instructions` field describing the four tools and how to use them together.
  </Step>

  <Step title="Search for an operation">
    Describe what you want to do in plain words with [`search_apis`](/mcp/tools-reference#search_apis) rather than guessing an `operationId` — ids are stable but not derivable from the resource name (deleting a lead, for example, is `lead_trash`, not `lead_delete`).

    ```bash theme={null}
    curl https://mcp.lofty.com/mcp \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -d '{
        "jsonrpc": "2.0", "id": 2, "method": "tools/call",
        "params": {"name": "search_apis", "arguments": {"query": "get a lead by id"}}
      }'
    ```

    The response includes `lead_get` among the candidates, each with its `operationId`, HTTP method, path, and a one-line summary.
  </Step>

  <Step title="Describe the operation">
    Call [`describe_api`](/mcp/tools-reference#describe_api) with the `operationId` to get its full parameter schema before calling it.

    ```bash theme={null}
    curl https://mcp.lofty.com/mcp \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -d '{
        "jsonrpc": "2.0", "id": 3, "method": "tools/call",
        "params": {"name": "describe_api", "arguments": {"operationId": "lead_get"}}
      }'
    ```

    The response's `inputSchema` shows `lead_get` takes a required `leadId` (integer) and an optional `withTrash` (boolean).
  </Step>

  <Step title="Invoke it">
    Call [`invoke_api`](/mcp/tools-reference#invoke_api) with the arguments `describe_api` described.

    ```bash theme={null}
    curl https://mcp.lofty.com/mcp \
      -H "Content-Type: application/json" \
      -H "Accept: application/json, text/event-stream" \
      -H "Authorization: Bearer YOUR_TOKEN" \
      -d '{
        "jsonrpc": "2.0", "id": 4, "method": "tools/call",
        "params": {"name": "invoke_api", "arguments": {"operationId": "lead_get", "arguments": {"leadId": 100001}}}
      }'
    ```

    A successful call returns the same JSON body the direct REST API would — wrapped under `content[0].text` (a string, for any MCP client) and mirrored in `structuredContent` (already-parsed JSON, for clients that support it).

    <Warning>
      Lead, task, and other entity IDs are 64-bit integers. If you're consuming `structuredContent` from JavaScript or TypeScript, read the [JS/TS Integration Guide](/javascript-integration) first — `JSON.parse()` silently corrupts IDs above `2^53 - 1`.
    </Warning>
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Tools Reference" icon="book" href="/mcp/tools-reference">
    Full input schema for all four tools.
  </Card>

  <Card title="Troubleshooting" icon="wrench" href="/mcp/troubleshooting">
    What to do when search comes up empty or a call is rejected.
  </Card>
</CardGroup>
