Skip to main content
Glama
README.md
# OfficeRnD MCP Server

A read-only [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that connects AI assistants to the [OfficeRnD](https://www.officernd.com/) coworking and flex-space management platform. Query members, companies, bookings, billing, and more through natural language.

## What it does

This server exposes OfficeRnD data through 5 domain-grouped tools, covering 25+ entity types:

| Tool | Entities | Example queries |
|---|---|---|
| **community** | Members, companies, memberships, check-ins, contracts, visits, visitors, opportunities | "List all active members" / "Show me visits from last week" |
| **space** | Resources, bookings, booking occurrences, floors, assignments, amenities, passes, credits | "What meeting rooms are available?" / "List bookings for today" |
| **billing** | Payments, fees, plans, coin/credit stats | "Show pending payments" / "Get credit balance for March" |
| **collaboration** | Events, tickets, posts | "List open tickets" / "What events are coming up?" |
| **settings** | Locations, resource types, business hours, custom properties | "List all office locations" |

All tools are **read-only** — no data can be created, modified, or deleted.

## Prerequisites

- **Node.js** 18+
- **OfficeRnD API credentials** — client ID, client secret, and organization slug (from your OfficeRnD admin dashboard under Integrations > API)

## Quick start

```bash
git clone https://github.com/MrBoor/officernd-mcp.git
cd officernd-mcp
npm install
npm run build
```

## Configuration

Set three environment variables (via `.env` file or directly):

```env
OFFICERND_CLIENT_ID=your_client_id
OFFICERND_CLIENT_SECRET=your_client_secret
OFFICERND_ORG_SLUG=your_organization_slug
```

The org slug is the identifier in your OfficeRnD URL: `app.officernd.com/.../{your_org_slug}`.

## Usage with Claude Desktop

1. Open **Claude Desktop** > **Settings** > **Developer** > **Edit Config**.
2. Add the server to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "officernd": {
      "command": "node",
      "args": ["/absolute/path/to/officernd-mcp/build/index.js"],
      "env": {
        "OFFICERND_CLIENT_ID": "your_client_id",
        "OFFICERND_CLIENT_SECRET": "your_client_secret",
        "OFFICERND_ORG_SLUG": "your_organization_slug"
      }
    }
  }
}
```

3. Restart Claude Desktop. A hammer icon in the chat input confirms the connection.

## Usage with ChatGPT Desktop

1. Open the **ChatGPT desktop app** and go to **Settings** (`Cmd+,` on macOS / `Ctrl+,` on Windows).
2. Navigate to **Tools** (or **MCP Servers**) and add a new server, or edit the config file directly at `~/.chatgpt/mcp.json`:

```json
{
  "mcpServers": {
    "officernd": {
      "command": "node",
      "args": ["/absolute/path/to/officernd-mcp/build/index.js"],
      "env": {
        "OFFICERND_CLIENT_ID": "your_client_id",
        "OFFICERND_CLIENT_SECRET": "your_client_secret",
        "OFFICERND_ORG_SLUG": "your_organization_slug"
      }
    }
  }
}
```

3. Restart ChatGPT. The server should appear in your tools list.

> **Note:** MCP support requires the ChatGPT desktop app (macOS or Windows) — it is not available in the web version. Requires a Plus, Team, or Enterprise subscription.

## Usage with Claude Code (CLI)

**Option A — CLI command (recommended):**

```bash
claude mcp add officernd \
  -e OFFICERND_CLIENT_ID=your_client_id \
  -e OFFICERND_CLIENT_SECRET=your_client_secret \
  -e OFFICERND_ORG_SLUG=your_org_slug \
  -s user \
  -- node /absolute/path/to/officernd-mcp/build/index.js
```

Use `-s project` instead of `-s user` to scope to the current project only.

**Option B — Project config file:**

A `.mcp.json` is included in the repo. Fill in your credentials:

```json
{
  "mcpServers": {
    "officernd": {
      "type": "stdio",
      "command": "node",
      "args": ["build/index.js"],
      "env": {
        "OFFICERND_CLIENT_ID": "your_client_id",
        "OFFICERND_CLIENT_SECRET": "your_client_secret",
        "OFFICERND_ORG_SLUG": "your_organization_slug"
      }
    }
  }
}
```

**Verify:** Run `/mcp` inside Claude Code to check the server status.

## Tool reference

Each tool accepts an `action` (`list`, `get`, or a special action), an `entity` type, and optional filters. All support cursor-based pagination via `cursorNext` (max 50 results per page).

### community

Query community/people data.

| Entity | Actions | Filters |
|---|---|---|
| `members` | list, get | `status`, `email`, `name`, `company`, `location` |
| `companies` | list, get | `name`, `status`, `location` |
| `memberships` | list, get | `member`, `company`, `status` |
| `checkins` | list, get | `member`, `location`, `startAfter`, `startBefore` |
| `contracts` | list, get | `member`, `company`, `status` |
| `visits` | list, get | `location`, `startAfter`, `startBefore` |
| `visitors` | list | _(pagination only)_ |
| `opportunities` | list, get | `status`, `member`, `company` |
| `opportunity_statuses` | list | _(pagination only)_ |

### space

Query space/resource data.

| Entity | Actions | Filters |
|---|---|---|
| `resources` | list, get, status | `type`, `name`, `location` |
| `bookings` | list, get | `resourceId`, `member`, `company`, `location`, `startAfter`, `startBefore` |
| `booking_occurrences` | list | `seriesStart` (required), `seriesEnd` (required), `resourceId`, `member`, `location` |
| `floors` | list, get | `location`, `name` |
| `assignments` | list | `resourceId`, `membershipId` |
| `amenities` | list, get | `title` |
| `passes` | list, get | `member`, `company` |
| `credits` | list, get | `member`, `company` |

Resource types for the `type` filter: `meeting_room`, `team_room`, `desk`, `hotdesk`, `desk_tr`, `desk_na`.

### billing

Query billing/financial data.

| Entity | Actions | Filters |
|---|---|---|
| `payments` | list, get | `status`, `member`, `company`, `documentType`, `dateFrom`, `dateTo`, `sort` |
| `fees` | list | _(pagination only)_ |
| `plans` | list, get | `sort` |

Special action — `coin_stats`: Get coin/credit balance for a member or company in a given month. Parameters: `member`, `company`, `month` (e.g., `2026-03`).

### collaboration

Query collaboration data.

| Entity | Actions | Filters |
|---|---|---|
| `events` | list, get | `location`, `startAfter`, `startBefore` |
| `tickets` | list, get | `status`, `member`, `location` |
| `posts` | list, get | _(pagination only)_ |

### settings

Query organization configuration.

| Entity | Actions | Filters |
|---|---|---|
| `locations` | list, get | `name` |
| `resource_types` | list | _(pagination only)_ |
| `business_hours` | list | `location` |
| `custom_properties` | list | _(pagination only)_ |

## Development

```bash
npm run dev         # Watch mode — recompiles on changes
npm run inspect     # Launch with MCP Inspector for debugging
```

### Architecture

```
src/
  index.ts          # Entry point — env validation, tool registration, stdio transport
  auth.ts           # OAuth 2.0 client-credentials flow with token caching
  client.ts         # API client — GET helper, pagination, base URL
  tools/
    community.ts    # Members, companies, memberships, check-ins, contracts, visits
    space.ts        # Resources, bookings, floors, assignments, amenities
    billing.ts      # Payments, fees, plans, coin stats
    collaboration.ts # Events, tickets, posts
    settings.ts     # Locations, resource types, business hours, custom properties
```

**Request flow:** AI assistant → MCP stdio → tool handler → OAuth token (cached) → HTTP GET → OfficeRnD API → formatted response.

## API rate limits

OfficeRnD API v2 enforces rate limits per integration per organization:

| Operation | Per Minute | Per Day |
|---|---|---|
| Read (GET) | 400 | 20,000 |
| Token generation | 5 | — |

This server only performs read operations. OAuth tokens are cached in memory and reused until expiry (with a 60-second buffer), keeping token requests well under the 5/min limit.

If you receive HTTP `429 Too Many Requests`, implement exponential backoff and spread requests out rather than bursting. Contact OfficeRnD support for rate limit exceptions if needed.

## Security

- **Read-only** — Only GET requests; no data modification possible
- **OAuth 2.0 client credentials** — Tokens cached in memory, auto-refreshed before expiry
- **No secrets in code** — Credentials are passed via environment variables
- **Scoped access** — Only requests the minimum read permissions needed

## Notes

- Date/time output is converted to Eastern Time (ET)
- Name filters (where noted) require exact full name match (e.g., "Jane Smith" not "Jane")
- Pagination is capped at 50 items per page (both default and maximum)
- The `$in` filter operator is capped at 50 values

## License

[MIT](LICENSE)

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation3/5

While the five tools map to distinct business domains (billing, collaboration, community, settings, space), there is conceptual overlap—e.g., 'credits' appear in both billing and space tools, and member-related data is scattered across community, billing, and space. The broad 'mega-tool' approach requires agents to infer which domain bucket contains specific entities.

Naming Consistency4/5

All tool names follow a consistent pattern of single lowercase nouns representing functional domains (billing, collaboration, community, settings, space). Although they lack action verbs (e.g., 'get_billing'), the naming convention is uniform and predictable.

Tool Count4/5

Five tools is a reasonable count for the OfficeRnD domain, falling within the ideal 3-15 range. However, each tool is a heavy aggregate covering multiple entities (e.g., community covers 9+ entity types), suggesting the surface could benefit from finer granularity despite the appropriate total count.

Completeness2/5

The tool set is strictly read-only (limited to list, get, status, and coin_stats actions) for a management platform that fundamentally requires write operations. Critical gaps include inability to create/update bookings, members, or invoices, which will prevent agents from completing core coworking management workflows like checking in visitors or reserving rooms.

Maintenance

ActivityInactive
ResponsivenessNo issues