{"id":"aa2043f9-4eb5-4455-bb25-a98997a22e3a","entityType":"agent","slug":"clawhub-chrischall-ioffice-mcp","name":"ioffice-mcp","canonicalUrl":"https://www.xpersona.co/agent/clawhub-chrischall-ioffice-mcp","canonicalPath":"/agent/clawhub-chrischall-ioffice-mcp","generatedAt":"2026-10-10T00:57:16.974Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":null},"description":"Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).","descriptionLabel":"Source description","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 2K downloads reported by the source. Last updated 10/9/2026.","installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:ioffice-mcp","sourceUrl":"https://clawhub.ai/chrischall/ioffice-mcp","homepage":"https://clawhub.ai/chrischall/skills/ioffice-mcp","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/chrischall/ioffice-mcp","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/chrischall/skills/ioffice-mcp","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":66,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"ioffice-mcp technical dossier on Xpersona with agent coverage, OPENCLEW support, and live trust metadata."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":null},"stars":null,"forks":null,"downloads":2011,"packageName":null,"latestVersion":"3.2.4","tractionLabel":"2K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":null},"lastUpdatedAt":"2026-10-09T20:47:04.404Z","lastCrawledAt":"2026-10-09T20:47:04.404Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-10T20:47:04.404Z","lastVerifiedAt":null,"highlights":[{"version":"3.2.4","createdAt":"2026-10-07T13:37:44.274Z","changelog":"- Removed the file: skill-card.md - No functional changes to the skill itself. - Documentation and available tools remain unchanged.","fileCount":3,"zipByteSize":6753},{"version":"3.2.3","createdAt":"2026-10-05T02:51:17.827Z","changelog":"- Removed the skill-card.md file. - No functional or user-facing changes; documentation only.","fileCount":3,"zipByteSize":6676},{"version":"3.2.2","createdAt":"2026-10-03T01:43:33.342Z","changelog":"- Removed the skill-card.md file from the project. - No changes to functionality or usage; all tools and documentation remain unchanged.","fileCount":3,"zipByteSize":6613},{"version":"3.2.1","createdAt":"2026-09-25T15:56:45.380Z","changelog":"# ioffice-mcp 3.2.1 Changelog - Removed the file: skill-card.md - No changes to core skill functionality or documentation.","fileCount":3,"zipByteSize":6637},{"version":"3.2.0","createdAt":"2026-09-24T15:11:20.754Z","changelog":"- skill-card.md file removed. - SKILL.md updated; main documentation and tool listings remain the same. - No changes to the interface or available tools. - No breaking changes; existing integrations remain unaffected.","fileCount":3,"zipByteSize":6775},{"version":"3.1.2","createdAt":"2026-09-23T21:40:22.703Z","changelog":"- Removed the file: skill-card.md - No changes to API, features, or functionality - Documentation and configuration remain unchanged","fileCount":3,"zipByteSize":6912},{"version":"3.1.1","createdAt":"2026-09-23T15:42:07.117Z","changelog":"- Removed the file skill-card.md. - No other changes; functionality and setup remain the same.","fileCount":3,"zipByteSize":6846},{"version":"3.1.0","createdAt":"2026-09-20T02:51:18.050Z","changelog":"## ioffice-mcp 3.1.0 - Removed the skill-card.md file. - No other changes to features, tools, or functionality.","fileCount":3,"zipByteSize":6859}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:ioffice-mcp","setupComplexity":"low","setupSteps":["Install using `clawhub skill install s17cjx1a349nz5apaqp02vgz4h85728z:ioffice-mcp` in an isolated environment before connecting it to live workloads.","No published capability contract is available yet, so validate auth and request/response behavior manually.","Review the upstream CLAWHUB listing at https://clawhub.ai/chrischall/ioffice-mcp before using production credentials."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-10T00:57:16.970Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-chrischall-ioffice-mcp/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":null},"readme":"Skill: ioffice-mcp\n\nOwner: chrischall\n\nSummary: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n\nTags: latest:3.2.4\n\nVersion history:\n\nv3.2.4 | 2026-10-07T13:37:44.274Z | auto\n\n- Removed the file: skill-card.md\n- No functional changes to the skill itself.\n- Documentation and available tools remain unchanged.\n\nv3.2.3 | 2026-10-05T02:51:17.827Z | auto\n\n- Removed the skill-card.md file.\n- No functional or user-facing changes; documentation only.\n\nv3.2.2 | 2026-10-03T01:43:33.342Z | auto\n\n- Removed the skill-card.md file from the project.\n- No changes to functionality or usage; all tools and documentation remain unchanged.\n\nv3.2.1 | 2026-09-25T15:56:45.380Z | auto\n\n# ioffice-mcp 3.2.1 Changelog\n\n- Removed the file: skill-card.md\n- No changes to core skill functionality or documentation.\n\nv3.2.0 | 2026-09-24T15:11:20.754Z | auto\n\n- skill-card.md file removed.\n- SKILL.md updated; main documentation and tool listings remain the same.  \n- No changes to the interface or available tools.  \n- No breaking changes; existing integrations remain unaffected.\n\nv3.1.2 | 2026-09-23T21:40:22.703Z | auto\n\n- Removed the file: skill-card.md\n- No changes to API, features, or functionality\n- Documentation and configuration remain unchanged\n\nv3.1.1 | 2026-09-23T15:42:07.117Z | auto\n\n- Removed the file skill-card.md.\n- No other changes; functionality and setup remain the same.\n\nv3.1.0 | 2026-09-20T02:51:18.050Z | auto\n\n## ioffice-mcp 3.1.0\n\n- Removed the skill-card.md file.\n- No other changes to features, tools, or functionality.\n\nv3.0.0 | 2026-09-17T23:38:17.546Z | auto\n\nioffice-mcp 3.0.0\n\n- Removed the file: skill-card.md\n- No changes to skill functionality or setup.\n- No impact to users expected.\n\nv2.3.2 | 2026-09-10T17:49:34.541Z | auto\n\n- Removed the skill-card.md file.\n- No other user-facing changes.\n\nv2.3.1 | 2026-09-05T00:51:06.131Z | auto\n\n- All read tools (`io_list_*` and `io_get_*`) now support an optional `view` parameter (`\"compact\"` or `\"full\"`) to control response shape; `compact` is the new default and strips out media fields and image URLs.\n- Added detailed documentation of the new `view` parameter, including the stripping rules for compact responses.\n- Updated tool signatures in documentation to reflect the new `view?` parameter.\n- Removed the `skill-card.md` file from the project.\n\nv2.3.0 | 2026-09-04T22:22:05.907Z | auto\n\n- Removed the skill-card.md file.\n- No other changes to functionality or other documentation.\n\nv2.2.0 | 2026-09-02T00:16:46.152Z | auto\n\n- Added new health check tool: `io_healthcheck()` for troubleshooting authentication and connector status.\n- Updated documentation to include the health check tool and guidance on diagnosing connectivity/authentication issues.\n- Removed the redundant file: `skill-card.md`.\n\nv2.1.10 | 2026-08-28T21:07:21.467Z | auto\n\n- Removed the \"skill-card.md\" file from the project.\n- No user-facing functionality or tool changes in this version.\n\nv2.1.9 | 2026-07-19T12:46:43.497Z | auto\n\n- Removed the file skill-card.md.\n- No functional or documentation changes in this version.\n\nv2.1.8 | 2026-07-14T10:40:55.834Z | auto\n\n- Removed the file skill-card.md.\n- No changes to features, tools, or documentation in SKILL.md.\n\nv2.1.7 | 2026-07-07T23:42:05.396Z | auto\n\n- Removed the file skill-card.md from the project.\n- No changes to functionality or documentation in this release.\n\nv2.1.6 | 2026-07-05T22:59:43.048Z | auto\n\n- Removed the \"skill-card.md\" file from the project.\n- No functional or user-facing changes in this release.\n\nv2.1.5 | 2026-06-13T00:54:55.839Z | auto\n\n- Removed the file: skill-card.md\n- No user-facing functionality changes.\n\nv2.1.4 | 2026-05-29T21:35:50.395Z | auto\n\n- Removed the skill-card.md file.\n- No functional changes; documentation and usage remain the same.\n\nv2.1.3 | 2026-05-26T17:09:52.101Z | auto\n\n- Expanded SKILL.md with detailed usage instructions, setup options, and authentication methods.\n- Comprehensive documentation of all available tools for managing buildings, floors, spaces, users, reservations, visitors, maintenance requests, moves, and mail.\n- Added typical workflow examples for common iOffice workplace management tasks.\n- Clarified environment variable setup and supported authentication options.\n- Provided important usage notes and terms of service acknowledgment.\n\nArchive index:\n\nArchive v3.2.4: 3 files, 6753 bytes\n\nFiles: skill-card.md (2069b), SKILL.md (13891b), _meta.json (130b)\n\nFile v3.2.4:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or,\n  on a client that cannot show a confirmation prompt, with a preview and a\n  `confirmToken` on the first call (nothing is sent until the call is repeated\n  with that token). There is nothing to strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.2.4:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.4\",\n  \"publishedAt\": 1791380264274\n}\n\nFile v3.2.4:skill-card.md\n\n## Description:\n\nConnects an agent to iOffice workplace data and actions for space, reservation, visitor, maintenance, move, and mail workflows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAuthorized employees use the skill to find workplace resources and manage room reservations, visitors, maintenance requests, moves, and mail in their iOffice tenant.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The available actions can modify or delete workplace, directory, visitor, mail, move, reservation, and maintenance data beyond personal bookings.\n\nMitigation: Use only with tenant authorization and a credential restricted to the minimum necessary permissions; review the target and effect before confirming changes.\n\nRisk: Workplace records may contain sensitive employee or visitor information, and automation may be subject to employer policies.\n\nMitigation: Limit access to authorized users and tasks, and check employer policies before connecting the tenant.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [ioffice-mcp npm package](https://www.npmjs.com/package/ioffice-mcp)\n- [Project repository listed in skill documentation](https://github.com/chrischall/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Configuration instructions, Shell commands]\n\n**Output Format:** [Markdown with JSON configuration and shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Agent responses may include workplace records, write-action receipts, or confirmation previews.]\n\n## Skill Version(s):\n\n3.2.4 (source: server-resolved release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.3: 3 files, 6676 bytes\n\nFiles: skill-card.md (1899b), SKILL.md (13891b), _meta.json (130b)\n\nFile v3.2.3:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or,\n  on a client that cannot show a confirmation prompt, with a preview and a\n  `confirmToken` on the first call (nothing is sent until the call is repeated\n  with that token). There is nothing to strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.2.3:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.3\",\n  \"publishedAt\": 1791168677827\n}\n\nFile v3.2.3:skill-card.md\n\n## Description:\n\nConnects an agent to iOffice to manage workplace spaces, reservations, visitors, maintenance, moves, and mail.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAuthorized employees and facilities teams use this skill to query and update their organization's iOffice workplace records, including room bookings, visitors, maintenance requests, moves, and mail.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Unauthorized automation or access to workplace data may violate employer policy.\n\nMitigation: Confirm employer approval before installing or using the connector.\n\nRisk: Exposed or overprivileged credentials could grant access to tenant data.\n\nMitigation: Use least-privilege credentials, keep secrets in project-local configuration or a secrets manager, and rotate tokens periodically.\n\nRisk: Write and delete actions can change or remove workplace records.\n\nMitigation: Review the target and intended changes before confirming each action.\n\n## Reference(s):\n\n- [ClawHub skill listing](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [iOffice MCP package](https://www.npmjs.com/package/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Configuration instructions, Guidance]\n\n**Output Format:** [Markdown and text responses from iOffice tools]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Requires an authenticated iOffice tenant connection.]\n\n## Skill Version(s):\n\n3.2.3 (source: server-resolved ClawHub release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.2: 3 files, 6613 bytes\n\nFiles: skill-card.md (1709b), SKILL.md (13891b), _meta.json (130b)\n\nFile v3.2.2:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or,\n  on a client that cannot show a confirmation prompt, with a preview and a\n  `confirmToken` on the first call (nothing is sent until the call is repeated\n  with that token). There is nothing to strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.2.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.2\",\n  \"publishedAt\": 1790991813342\n}\n\nFile v3.2.2:skill-card.md\n\n## Description:\n\nHelps authorized employees access and manage iOffice workplace and facility records through an MCP server.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAuthorized employees use this skill to look up workspace information and manage reservations, visitors, maintenance requests, moves, and mail in their employer's iOffice tenant.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: An external package handles credentials for workplace data.\n\nMitigation: Install only if you trust the package and use a least-privilege token where possible.\n\nRisk: Administrative or state-changing actions can alter workplace records.\n\nMitigation: Confirm workplace authorization and review create, update, delete, approval, delivery, check-in, and checkout actions before execution.\n\n## Reference(s):\n\n- [ClawHub skill listing](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [ioffice-mcp npm package](https://www.npmjs.com/package/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Guidance, Configuration instructions]\n\n**Output Format:** [Markdown and MCP tool results]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Results depend on the configured tenant and account permissions.]\n\n## Skill Version(s):\n\n3.2.2 (source: server-resolved release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.1: 3 files, 6637 bytes\n\nFiles: skill-card.md (1765b), SKILL.md (13891b), _meta.json (130b)\n\nFile v3.2.1:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or,\n  on a client that cannot show a confirmation prompt, with a preview and a\n  `confirmToken` on the first call (nothing is sent until the call is repeated\n  with that token). There is nothing to strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.2.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.1\",\n  \"publishedAt\": 1790351805380\n}\n\nFile v3.2.1:skill-card.md\n\n## Description:\n\nConnects an agent to iOffice workplace data and tools for managing spaces, reservations, visitors, maintenance requests, moves, and mail.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nEmployees with authorized iOffice access can find workplace information and manage room bookings, visitors, maintenance requests, moves, and mail.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The connector offers tenant-wide administrative create, update, and delete actions beyond its personal-use framing.\n\nMitigation: Use a least-privileged account; enable administrative actions only when expressly intended and controlled.\n\nRisk: Workplace automation may be unauthorized under an employer's policies.\n\nMitigation: Confirm employer approval before connecting an iOffice account or performing workplace actions.\n\n## Reference(s):\n\n- [ioffice-mcp ClawHub listing](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [ioffice-mcp npm package](https://www.npmjs.com/package/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Guidance]\n\n**Output Format:** [Markdown guidance and iOffice tool responses]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Read results may omit image media by default; request the full view when needed.]\n\n## Skill Version(s):\n\n3.2.1 (source: server-resolved release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.2.0: 3 files, 6775 bytes\n\nFiles: skill-card.md (2147b), SKILL.md (13891b), _meta.json (130b)\n\nFile v3.2.0:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or,\n  on a client that cannot show a confirmation prompt, with a preview and a\n  `confirmToken` on the first call (nothing is sent until the call is repeated\n  with that token). There is nothing to strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.2.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.0\",\n  \"publishedAt\": 1790262680754\n}\n\nFile v3.2.0:skill-card.md\n\n## Description:\n\nAccess iOffice workspace and facility data through MCP for buildings, floors, spaces, reservations, visitors, maintenance requests, moves, and mail.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nEmployees, workplace operations teams, and developers use this skill to connect an agent to an authorized iOffice/Eptura tenant for room booking, visitor workflows, maintenance requests, moves, mail, and facility data lookup.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: Unauthorized automation against an organization's iOffice/Eptura tenant may violate employer or service policies.\n\nMitigation: Install only when authorized to automate the tenant and follow employer IT and acceptable-use requirements.\n\nRisk: The skill exposes broad workplace administration abilities, including user, delete, and facility-management actions.\n\nMitigation: Use a least-privilege token or account and review high-impact actions before enabling the server.\n\nRisk: Enabling the skill depends on a third-party npm/source package.\n\nMitigation: Review the npm/source package before enabling it and pin versions when your environment requires reproducibility.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [npm package](https://www.npmjs.com/package/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, configuration, shell commands]\n\n**Output Format:** [Markdown with JSON and shell command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Agent-facing instructions for configuring and using an iOffice MCP server; tool calls require an authorized tenant and credentials.]\n\n## Skill Version(s):\n\n3.2.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.2: 3 files, 6912 bytes\n\nFiles: skill-card.md (2573b), SKILL.md (13775b), _meta.json (130b)\n\nFile v3.1.2:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or\n  with a dry-run preview when `confirm: true` is absent. There is nothing to\n  strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.1.2\",\n  \"publishedAt\": 1790199622703\n}\n\nFile v3.1.2:skill-card.md\n\n## Description:\n\nAccess iOffice workspace and facility data via MCP for buildings, floors, spaces, reservations, visitors, maintenance requests, moves, and mail.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and authorized workplace operations users use this skill to connect an agent to an organization's iOffice or Eptura Workplace tenant for room booking, visitor handling, maintenance requests, moves, mail workflows, and related facility data lookups.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill exposes tenant-level workplace and user administration tools, including update, delete, and state-changing actions.\n\nMitigation: Install only for authorized iOffice or Eptura tenants, use least-privilege credentials, and require explicit confirmation before any write or state-changing operation.\n\nRisk: The artifact frames the connector for personal, single-employee use while exposing data and actions that may be governed by employer policy.\n\nMitigation: Confirm employer IT and security authorization before use, and do not bulk-extract directories, floor plans, visitor records, or other workplace data.\n\nRisk: Full responses can include media or sensitive facility and user details that compact responses omit.\n\nMitigation: Use compact views by default, request full views only when the additional data is necessary, and protect iOffice tokens or passwords as tenant credentials.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [npm package](https://www.npmjs.com/package/ioffice-mcp)\n- [Eptura Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/)\n\n## Skill Output:\n\n**Output Type(s):** [text, API calls, shell commands, configuration, guidance]\n\n**Output Format:** [Markdown text with MCP tool calls, JSON configuration examples, and shell commands]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Read tools can return compact or full iOffice payloads; write and state-changing tools should be treated as administrative actions requiring explicit confirmation.]\n\n## Skill Version(s):\n\n3.1.2 (source: server release evidence)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.1: 3 files, 6846 bytes\n\nFiles: skill-card.md (2382b), SKILL.md (13775b), _meta.json (130b)\n\nFile v3.1.1:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or\n  with a dry-run preview when `confirm: true` is absent. There is nothing to\n  strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.1.1\",\n  \"publishedAt\": 1790178127117\n}\n\nFile v3.1.1:skill-card.md\n\n## Description:\n\nAccess iOffice workspace and facility data through an MCP server for buildings, floors, spaces, users, reservations, visitors, maintenance requests, moves, and mail.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and workplace operations teams use this skill to connect an agent to an authorized iOffice tenant for facility lookup and administrative workflows such as reservations, visitor handling, maintenance, moves, and mail.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can perform administrative actions against iOffice workplace data, including account, building, floor, space, reservation, visitor, maintenance, move, and mail workflows.\n\nMitigation: Install and use it only with authorization for the target tenant, use least-privileged credentials, and require explicit confirmation before write, delete, approval, cancellation, check-in/out, delivery, or return actions.\n\nRisk: Password-based authentication can expose broader account access than a scoped token.\n\nMitigation: Prefer IOFFICE_TOKEN over username and password credentials, and avoid storing passwords when a scoped token is available.\n\nRisk: npx-based setup executes a package fetched from the package registry.\n\nMitigation: Verify the npm package or source repository before using npx-based setup in an agent environment.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [npm package](https://www.npmjs.com/package/ioffice-mcp)\n- [GitHub link listed in skill](https://github.com/chrischall/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Guidance, Configuration, Shell commands, API calls, Text]\n\n**Output Format:** [Markdown with JSON and shell command snippets]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [MCP tool calls may return compact or full iOffice records depending on the requested view.]\n\n## Skill Version(s):\n\n3.1.1 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.1.0: 3 files, 6859 bytes\n\nFiles: skill-card.md (2438b), SKILL.md (13775b), _meta.json (130b)\n\nFile v3.1.0:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or\n  with a dry-run preview when `confirm: true` is absent. There is nothing to\n  strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic device to retrieve, index, \"scrape,\" \"data mine\" or otherwise gather Service content.\n\nAnd: customers must \"identify and authenticate all Users,\" may not resell or sublicense, must \"promptly deactivate access to terminated personnel.\"\n\nYou are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.\n\n**3. Eptura's contract is with your employer, not you.** iOffice / Eptura Workplace is typically licensed by an organization, not by individual employees. Your use of this server is *also* subject to your employer's separate IT/security/acceptable-use policies, which may restrict automation in ways the Eptura AUP doesn't. **Check with your employer's IT before using this server.** Using it without authorization may violate your employment agreement even if Eptura itself doesn't notice.\n\n**4. Personal, single-employee use only.** This project is not affiliated with, endorsed by, sponsored by, or in partnership with Eptura, Inc. It is a personal automation tool for an individual authenticated user to drive their own workplace bookings (reservations, visitors, work orders). Do not use it to bulk-extract floor plans, employee directories, or other workspace data, and do not build a competing workplace product on top of it.\n\n**5. You accept full responsibility** for any consequences of using this server in connection with your iOffice account — rate limiting, session revocation, tenant suspension, your employer's IT calling you, or any other enforcement action. If Eptura or your employer objects to your use, stop using this server.\n\nThis section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Eptura's actual AUP, Master Subscription Agreement, or your employer's policies.\n\nFile v3.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.1.0\",\n  \"publishedAt\": 1789872678050\n}\n\nFile v3.1.0:skill-card.md\n\n## Description:\n\nioffice-mcp helps agents access iOffice workspace and facility data through an MCP server for buildings, floors, spaces, reservations, visitors, maintenance requests, moves, mail, and health checks.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nEmployees, facilities teams, workplace operations staff, and developers use this skill to query and manage iOffice workplace resources through an MCP server using their own authorized tenant credentials.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The skill can access sensitive workplace data such as users, visitors, reservations, spaces, floor plans, maintenance requests, moves, and mail records.\n\nMitigation: Install and use it only with employer authorization, scoped tenant credentials, and least-privilege access.\n\nRisk: Write and action tools can create, update, delete, check in or out, approve, deliver, return, or otherwise change workplace records.\n\nMitigation: Require explicit confirmation before create, update, delete, check-in/out, approval, delivery, return, and related state-changing actions.\n\nRisk: Bulk extraction of employee directories, floor plans, or workspace data may violate workplace or service policies.\n\nMitigation: Avoid bulk extraction and follow employer IT, security, acceptable-use, and Eptura/iOffice tenant policies.\n\n## Reference(s):\n\n- [ioffice-mcp npm package](https://www.npmjs.com/package/ioffice-mcp)\n- [ioffice-mcp source link declared in artifact](https://github.com/chrischall/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [guidance, markdown, code, shell commands, configuration, API calls]\n\n**Output Format:** [Markdown with JSON and shell command snippets; MCP tools return structured iOffice data, previews, receipts, and health-check guidance.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Read tools support compact and full views; compact is the default and strips media fields and image URLs.]\n\n## Skill Version(s):\n\n3.1.0 (source: server release metadata)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v3.0.0: 3 files, 6678 bytes\n\nFiles: skill-card.md (2014b), SKILL.md (13775b), _meta.json (130b)\n\nFile v3.0.0:SKILL.md\n\n---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` | Delete a space |\n\n### Users\n| Tool | Description |\n|------|-------------|\n| `io_list_users(search?, view?)` | List users with optional search |\n| `io_get_user(id, view?)` | Get a single user by ID |\n| `io_create_user(firstName, lastName, email, ...)` | Create a new user |\n| `io_update_user(id, ...)` | Update a user |\n| `io_delete_user(id)` | Delete a user |\n\n### Reservations\n| Tool | Description |\n|------|-------------|\n| `io_list_reservations(spaceId?, userId?, startDate?, endDate?, view?)` | List reservations with optional filters |\n| `io_get_reservation(id, view?)` | Get a single reservation by ID |\n| `io_create_reservation(title, spaceId, startDate, endDate, ...)` | Reserve a space |\n| `io_update_reservation(id, ...)` | Update a reservation |\n| `io_delete_reservation(id)` | Cancel/delete a reservation |\n| `io_checkin_reservation(id)` | Check in to a reservation, confirming room usage |\n| `io_checkout_reservation(id)` | Check out early, releasing the room |\n\n### Visitors\n| Tool | Description |\n|------|-------------|\n| `io_list_visitors(buildingId?, startDate?, endDate?, view?)` | List visitors with optional filters |\n| `io_get_visitor(id, view?)` | Get a single visitor record by ID |\n| `io_create_visitor(firstName, lastName, hostId?, expectedArrival?, ...)` | Pre-register a visitor |\n| `io_update_visitor(id, ...)` | Update a visitor record |\n| `io_checkin_visitor(id)` | Check in a visitor upon arrival |\n| `io_checkout_visitor(id)` | Check out a visitor upon departure |\n\n### Maintenance Requests\n| Tool | Description |\n|------|-------------|\n| `io_list_maintenance_requests(status?, spaceId?, buildingId?, view?)` | List maintenance requests |\n| `io_get_maintenance_request(id, view?)` | Get a single maintenance request |\n| `io_create_maintenance_request(title, spaceId?, buildingId?, ...)` | File a new maintenance request |\n| `io_update_maintenance_request(id, ...)` | Update a maintenance request |\n| `io_accept_maintenance_request(id)` | Accept a pending request (pending → accepted) |\n| `io_start_maintenance_request(id)` | Start work (accepted → in-progress) |\n| `io_complete_maintenance_request(id, resolution?)` | Mark as complete |\n| `io_archive_maintenance_request(id)` | Archive a completed request |\n\n### Moves\n| Tool | Description |\n|------|-------------|\n| `io_list_moves(status?, buildingId?, view?)` | List move requests |\n| `io_get_move(id, view?)` | Get a single move request |\n| `io_create_move(name, fromSpaceId?, toSpaceId?, scheduledDate?, ...)` | Create a move request |\n| `io_update_move(id, ...)` | Update a move request |\n| `io_approve_move(id, notes?)` | Approve a move request |\n| `io_cancel_move(id, reason?)` | Cancel a move request |\n\n### Mail\n| Tool | Description |\n|------|-------------|\n| `io_list_mail(status?, recipientId?, buildingId?, view?)` | List mail items (packages and letters) |\n| `io_get_mail(id, view?)` | Get a single mail item |\n| `io_create_mail(recipientId, buildingId, carrier?, trackingNumber?, ...)` | Log a received mail item |\n| `io_deliver_mail(id, deliveredDate?, signature?)` | Mark a mail item as delivered |\n| `io_return_mail(id, reason?)` | Mark a mail item as returned to sender |\n\n### Health\n\n| Tool | Purpose |\n|---|---|\n| `io_healthcheck()` | Is this connector working? Reports which credential resolved, whether iOffice accepted it, and what to fix. Start here when any other tool fails — an empty result from a list tool can mean \"no data\" or \"never authenticated\", and this separates them. |\n\n## Response shape (`view`)\n\nThe 18 read tools — every `io_list_*` and `io_get_*` across the nine resource\ngroups — take `view: \"compact\" | \"full\"`, and **`compact` is the default**: the\nparameter is optional, and omitting it gives you the slim shape without asking\nfor it.\n\n**Compact strips media; it does not project fields.** No hand-written field\nlist exists here, deliberately. Every read tool hands back iOffice's payload\nverbatim, and the repo has no schema, no captured fixture and no live tenant —\nso nothing in it could honestly say which of iOffice's fields matter. Stripping\nis subtractive and cannot lose a field nobody knew about; an invented field list\nwould return records with holes in them that read like a verified answer.\n\nTwo rules do the stripping, and the second one is the one that will catch you\nout:\n\n- **A media-named key goes, whatever it holds** — `avatar`, `picture`, `photo`,\n  `thumbnail`, `image`, `icon`, `banner`, `logo`, with an optional qualifier\n  (`primary_photo_url`, `coverImage`), an optional `Url`/`Uri`/`Link`/`Src`\n  suffix, and plurals. The match is anchored at the *start* of the key, so\n  `hasThumbnail: false` and `thumbnailWidth: 200` survive — they are facts about\n  a record, not the picture.\n- **Any value that is an image URL goes, whatever the key is called** — an\n  `http(s)` URL whose *path* ends in `.png`, `.jpg`, `.gif`, `.webp`, `.svg`,\n  `.avif`, `.bmp` or `.ico`.\n\n**The surprise, and it matters most on exactly this server: whether your floor\nplan survives compact is decided by the file extension, not by the field name.**\n`floorPlanUrl` is not a media key, so rule one leaves it alone — but a plan\nserved as `…/plans/3.png` is dropped by rule two, while the same plan as\n`…/plans/3.pdf`, or behind a signed extension-less URL, comes back. The same\ngoes for `attachmentUrl` and `documentUrl`. If a read comes back without the\nimage you expected, that is why — ask for `full`.\n\nThe strip removes the **key**, recursing through nested objects and arrays, so\non compact `\"imageUrl\" in space` is `false` rather than null. Everything it does\nnot remove is byte-identical to `full`.\n\nPass `view: \"full\"` when you want the pictures themselves — a visitor badge\nphoto, a user avatar, a space's floor plan image.\n\nThere is **no `raw` rung**: `full` already *is* iOffice's payload untouched, so a\nthird value could only silently alias one of the other two. `view: \"raw\"` is a\nschema validation error, not a quiet downgrade to compact.\n\nThe other 35 tools take no `view`, for two different reasons:\n\n- **The 34 write and action tools** — `io_create_*`, `io_update_*`,\n  `io_delete_*`, and the state transitions (check in/out, accept/start/\n  complete/archive, approve/cancel, deliver/return) — answer with a receipt, or\n  with a dry-run preview when `confirm: true` is absent. There is nothing to\n  strip and every field is load-bearing.\n- **`io_healthcheck`** is read-only, but its output is its own verdict — which\n  credential resolved, whether iOffice accepted it, what to fix — rather than an\n  iOffice record.\n\n## Workflows\n\n**Book a meeting room:**\n```\nio_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)\n```\n\n**Pre-register a visitor:**\n```\nio_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave\n```\n\n**File and resolve a maintenance request:**\n```\nio_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")\n```\n\n**Log and deliver a package:**\n```\nio_list_users(search: \"recipient name\") → find recipientId\nio_create_mail(recipientId, buildingId, carrier: \"FedEx\", trackingNumber: \"...\")\nio_deliver_mail(id) → when delivered to recipient\n```\n\n**Schedule and approve a move:**\n```\nio_list_spaces → find fromSpaceId and toSpaceId\nio_create_move(name, fromSpaceId, toSpaceId, scheduledDate)\nio_approve_move(id, notes: \"Approved\")\n```\n\n## Notes\n\n- All dates use ISO 8601 format (e.g. `2026-03-21T09:00:00`)\n- All list tools support `search`, `limit` (default 50, max 100), `startAt`, `orderBy`, and `orderByType`\n- All `io_list_*` and `io_get_*` tools accept `view` — see [Response shape](#response-shape-view)\n- `io_list_floors(buildingId)` and `io_list_spaces(floorId)` use nested API paths when an ID is provided\n- Building → Floor → Space is the physical location hierarchy\n\n## Acknowledgement of Terms\n\nBy using this MCP server, you acknowledge and agree to the following:\n\n**1. This server accesses your own iOffice / Eptura Workplace tenant.** Auth happens via your own credentials, scoped to the tenant your employer has provisioned for you. It does not — and cannot — access anyone else's organization's data.\n\n**2. [Eptura's Acceptable Use Policy](https://eptura.com/terms/acceptable-use-policy/) governs your use of this server**, just as it governs your direct use of iOffice. (iOffice rebranded to Eptura Workplace in 2023.) The clauses most relevant here:\n\n> Customers may not use any robot, spider, site search/retrieval application or other manual or automatic\n\nArchive v2.3.2: 3 files, 6950 bytes\n\nFiles: skill-card.md (2609b), SKILL.md (13775b), _meta.json (130b)","readmeExcerpt":"Skill: ioffice-mcp Owner: chrischall Summary: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in ","codeSnippets":[],"executableExamples":[{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}"},{"language":"bash","snippet":"git clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build"},{"language":"json","snippet":"{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}"},{"language":"text","snippet":"io_list_buildings → find building ID\nio_list_floors(buildingId) → find floor ID\nio_list_spaces(floorId) → pick a room\nio_create_reservation(title, spaceId, startDate, endDate)"},{"language":"text","snippet":"io_list_users(search: \"host name\") → find hostId\nio_create_visitor(firstName, lastName, hostId, buildingId, expectedArrival)\nio_checkin_visitor(id) → when they arrive\nio_checkout_visitor(id) → when they leave"},{"language":"text","snippet":"io_list_spaces(search: \"room name\") → find spaceId\nio_create_maintenance_request(title, spaceId, buildingId)\nio_accept_maintenance_request(id)\nio_start_maintenance_request(id)\nio_complete_maintenance_request(id, resolution: \"Fixed the issue\")"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: ioffice-mcp\ndescription: Access iOffice workspace and facility data via MCP. Use when the user asks about iOffice buildings, floors, spaces, reservations, visitors, maintenance requests, moves, or mail. Triggers on phrases like \"book a room in iOffice\", \"check who's visiting today\", \"file a maintenance request\", \"log a package\", \"schedule a move\", or any request involving workplace management in iOffice. Requires ioffice-mcp installed and the ioffice server registered (see Setup below).\n---\n\n# ioffice-mcp\n\nMCP server for iOffice — natural-language workspace and facility management via the iOffice API.\n\n- **npm:** [npmjs.com/package/ioffice-mcp](https://www.npmjs.com/package/ioffice-mcp)\n- **Source:** [github.com/chrischall/ioffice-mcp](https://github.com/chrischall/ioffice-mcp)\n\n## Setup\n\n### Option A — npx (recommended)\n\nAdd to `.mcp.json` in your project or `~/.claude/mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"ioffice-mcp\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\n### Option B — from source\n\n```bash\ngit clone https://github.com/chrischall/ioffice-mcp\ncd ioffice-mcp\nnpm install && npm run build\n```\n\nThen add to `.mcp.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"ioffice\": {\n      \"command\": \"node\",\n      \"args\": [\"/path/to/ioffice-mcp/dist/index.js\"],\n      \"env\": {\n        \"IOFFICE_HOST\": \"your-tenant.ioffice.com\",\n        \"IOFFICE_TOKEN\": \"your-token-here\"\n      }\n    }\n  }\n}\n```\n\nOr use a `.env` file in the project directory with `IOFFICE_HOST` and `IOFFICE_TOKEN`.\n\n## Authentication\n\nToken auth (preferred) — set `IOFFICE_TOKEN`. Alternatively, set `IOFFICE_USERNAME` + `IOFFICE_PASSWORD`. If both are present, the token takes precedence.\n\n## Tools\n\n### Buildings\n| Tool | Description |\n|------|-------------|\n| `io_list_buildings(view?)` | List buildings with optional search, pagination, and sorting |\n| `io_get_building(id, view?)` | Get a single building by ID |\n| `io_create_building(name, address1?, city?, ...)` | Create a new building |\n| `io_update_building(id, ...)` | Update a building — only provide fields to change |\n| `io_delete_building(id)` | Delete a building |\n\n### Floors\n| Tool | Description |\n|------|-------------|\n| `io_list_floors(buildingId?, view?)` | List floors, optionally filtered by building |\n| `io_get_floor(id, view?)` | Get a single floor by ID |\n| `io_create_floor(name, buildingId, ...)` | Create a floor within a building |\n| `io_update_floor(id, ...)` | Update a floor |\n| `io_delete_floor(id)` | Delete a floor |\n\n### Spaces\n| Tool | Description |\n|------|-------------|\n| `io_list_spaces(floorId?, view?)` | List spaces/rooms, optionally filtered by floor |\n| `io_get_space(id, view?)` | Get a single space by ID |\n| `io_create_space(name, floorId, capacity?, ...)` | Create a space on a floor |\n| `io_update_space(id, ...)` | Update a space |\n| `io_delete_space(id)` |"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn700jq4sjtf2anb0rk3ft4p7n856872\",\n  \"slug\": \"ioffice-mcp\",\n  \"version\": \"3.2.4\",\n  \"publishedAt\": 1791380264274\n}"},{"path":"skill-card.md","content":"## Description:\n\nConnects an agent to iOffice workplace data and actions for space, reservation, visitor, maintenance, move, and mail workflows.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[chrischall](https://clawhub.ai/user/chrischall)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nAuthorized employees use the skill to find workplace resources and manage room reservations, visitors, maintenance requests, moves, and mail in their iOffice tenant.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The available actions can modify or delete workplace, directory, visitor, mail, move, reservation, and maintenance data beyond personal bookings.\n\nMitigation: Use only with tenant authorization and a credential restricted to the minimum necessary permissions; review the target and effect before confirming changes.\n\nRisk: Workplace records may contain sensitive employee or visitor information, and automation may be subject to employer policies.\n\nMitigation: Limit access to authorized users and tasks, and check employer policies before connecting the tenant.\n\n## Reference(s):\n\n- [ClawHub skill release](https://clawhub.ai/chrischall/skills/ioffice-mcp)\n- [ioffice-mcp npm package](https://www.npmjs.com/package/ioffice-mcp)\n- [Project repository listed in skill documentation](https://github.com/chrischall/ioffice-mcp)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, Configuration instructions, Shell commands]\n\n**Output Format:** [Markdown with JSON configuration and shell command examples]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Agent responses may include workplace records, write-action receipts, or confirmation previews.]\n\n## Skill Version(s):\n\n3.2.4 (source: server-resolved release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":null,"editorialQuality":{"score":100,"threshold":65,"status":"thin","wordCount":1127,"uniquenessScore":44,"reasons":["uniqueness-below-45"]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-09T20:47:04.404Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-10T00:57:16.974Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}