Skip to content

Calling it four ways

Tutorial 4 of 12 imports Leaseline's rent roll and calls the same lease Verbs through the API, SDK, CLI and MCP.

Every Verb has one name and one JSON input on every Interface. Leaseline declares a Lease Noun, and its records arrive by import, then answer the same call four ways.

What you build

You map a property manager's rent roll into Lease records, then list and renew leases through the API, the SDK, the CLI and MCP. Each call returns one Action.

Steps

Terminal5 steps
  1. To import a rent roll, map its columns onto the Noun:

    mappings/rent-roll.ts
    import { mapping } from 'startup-builder'
    
    export default mapping({
      from: 'csv',
      to: 'Lease',
      fields: {
        unit: 'Unit',
        endsOn: (row) => new Date(row['Lease End']).toISOString().slice(0, 10),
        rent: (row) => ({ amount: Number(row['Monthly Rent']), currency: 'USD' }),
      },
    })
  2. To list the leases up for renewal, call the API:

    curl "https://api.sb/leaseline.app/leases?where=status%20%3D%20renewing" \-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
  3. To do the same in code, use the SDK:

    TypeScript
    import { $ } from 'startup-builder'
    
    const due = await $.Lease.list({ where: 'status = renewing', sort: 'endsOn', limit: 50 })
  4. To renew one from a terminal or CI, use the CLI:

    npx startup-builder do Lease.renew --json '{"lease":"lease_4loEed1JG4","months":12}'
  5. To let an agent do it, give it the MCP server. Its do tool runs the same SDK line as one Action:

    JSON
    {
      "name": "do",
      "arguments": { "code": "return await $.Lease.renew({ lease: 'lease_4loEed1JG4', months: 12 })" }
    }

Result

The rent roll became Lease records, and one Verb answered four Interfaces with the same name, input and Action. The parity matrix sets every operation side by side. Checkpoint leaseline@ch04 (status planned) adds mappings/rent-roll.ts.

Next steps