# StageGrow developer docs > StageGrow is the operating system for US home staging companies. Agents act on it through the MCP server at https://my.designgrow.app/mcp. ## Overview StageGrow (formerly DesignGrow) is the operating system for US home staging companies, from solo stagers to regional operators. It runs projects and schedules, inventory and warehouses, clients and realtors, proposals and contracts, invoicing and collections (AR), and reporting. Every record belongs to one organization; no credential can see another organization's data. StageGrow has no built-in chat assistant. You bring your own agent (Claude, ChatGPT, OpenClaw or anything that speaks MCP) and connect it to your organization. The rule we build by: anything the web app does, an MCP tool does. - **MCP server** (primary agent interface): `https://my.designgrow.app/mcp`. Streamable HTTP, organization-scoped. - **Docs MCP** (public, no credentials): `https://my.designgrow.app/docs/mcp`. - **OpenAPI contract**: [https://my.designgrow.app/openapi.json](https://my.designgrow.app/openapi.json). - **AI Catalog** of everything above: [https://my.designgrow.app/.well-known/ai-catalog.json](https://my.designgrow.app/.well-known/ai-catalog.json). ## Connect an agent (MCP quickstart) The MCP endpoint is `https://my.designgrow.app/mcp` (the older `https://my.designgrow.app/api/mcp` serves the same server). Transport is Streamable HTTP; replies are plain JSON, so clients that cannot read an SSE stream work too. **Claude Code, OpenClaw, scripts (API key).** An organization owner creates a key in **Settings → Developers** and picks its scopes. Then: ```bash claude mcp add --transport http stagegrow https://my.designgrow.app/mcp --header "Authorization: Bearer mcp_YOUR_KEY" ``` Or in a JSON client config: ```json { "mcpServers": { "stagegrow": { "type": "http", "url": "https://my.designgrow.app/mcp", "headers": { "Authorization": "Bearer mcp_YOUR_KEY" } } } } ``` **claude.ai and ChatGPT (OAuth).** Add a custom connector with the URL `https://my.designgrow.app/mcp`. The client discovers the authorization server from the 401 response, registers itself, and sends an organization owner to a consent screen. See [Authentication](#auth). **Status:** new OAuth connections are not enabled yet. Until they are, connect with an MCP API key from a client that can send headers (Claude Code, Claude Desktop, OpenClaw). **Check the connection** with two JSON-RPC calls: ```bash curl -s https://my.designgrow.app/mcp \ -H "Authorization: Bearer mcp_YOUR_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' curl -s https://my.designgrow.app/mcp \ -H "Authorization: Bearer mcp_YOUR_KEY" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' ``` `tools/list` returns only the tools your credential's scopes allow, so a read-only key sees a short list. Start with `get_workflow` and `search`/`fetch`; agent role instructions come from `list_agent_profiles` and `get_agent_profile` when your organization publishes them. ## Authentication Two credential types reach the MCP server. Both are pinned to one organization. | Credential | Format | Who creates it | Use it for | | --- | --- | --- | --- | | MCP API key | `Authorization: Bearer mcp_<48 hex>` | An organization owner, in Settings → Developers | Claude Code, Claude Desktop, OpenClaw, scripts | | OAuth 2.0 access token | `Authorization: Bearer `, 1 hour | An organization owner approves the consent screen | claude.ai and ChatGPT connectors | **OAuth details.** Authorization code grant with PKCE; only `S256` is accepted. Redirect URIs must match a registered URI exactly. Clients register with RFC 7591 dynamic client registration. Access tokens last one hour. Refresh tokens rotate on every use and stop after 30 days without use. Revoking the connector in Settings → Developers ends the refresh token and every access token at once. Only an organization owner can approve a connector, and the grant is pinned to that owner's organization. **Status:** new OAuth connections are not enabled yet. Until they are, connect with an MCP API key from a client that can send headers (Claude Code, Claude Desktop, OpenClaw). - Protected-resource metadata (RFC 9728): [https://my.designgrow.app/.well-known/oauth-protected-resource/mcp](https://my.designgrow.app/.well-known/oauth-protected-resource/mcp) - Authorization-server metadata (RFC 8414): [https://my.designgrow.app/.well-known/oauth-authorization-server](https://my.designgrow.app/.well-known/oauth-authorization-server) - Registration: `POST https://my.designgrow.app/api/oauth/register`; authorize: `https://my.designgrow.app/oauth/authorize`; token: `POST https://my.designgrow.app/api/oauth/token` An unauthenticated MCP request gets `401` with a challenge that names the metadata document: ```http HTTP/1.1 401 Unauthorized WWW-Authenticate: Bearer resource_metadata="https://my.designgrow.app/.well-known/oauth-protected-resource/mcp" ``` Shop keys (scope `shop`) are a separate credential for the Superb shop MCP and are refused by `/mcp`. ## Scopes | Scope | Grants | | --- | --- | | `read` | List, get, search and report tools. | | `write` | Create, update and delete operational records: projects, clients, inventory, proposals, workspace content. | | `finance` | AR, invoices, payments, billing and financial reports. | A credential sees only the tools its scopes allow. Pick the smallest set the agent needs: a reporting bot needs `read`, a collections bot `read` + `finance`. There is no unrestricted scope for new keys or connectors. ## REST API Base URL: `https://my.designgrow.app/api/v1` (every path also answers unversioned at `/api`). The full contract, with parameters, error responses and security schemes, is [https://my.designgrow.app/openapi.json](https://my.designgrow.app/openapi.json). These endpoints serve the StageGrow web app and authenticate with a signed-in session; webhook subscriptions use the Zapier OAuth token. For agents, the MCP server covers the same operations and more. | Area | Endpoint | What it does | | --- | --- | --- | | Projects | `GET /api/v1/projects` | List all projects in your organization | | Projects | `POST /api/v1/projects` | Create a new project | | Projects | `GET /api/v1/projects/{id}` | Get a specific project by ID | | Projects | `PUT /api/v1/projects/{id}` | Update a project | | Projects | `DELETE /api/v1/projects/{id}` | Delete a project | | Inventory | `GET /api/v1/inventory` | List all inventory items | | Inventory | `POST /api/v1/inventory` | Create a new inventory item | | Inventory | `GET /api/v1/inventory/{id}` | Get a specific inventory item | | Inventory | `PUT /api/v1/inventory/{id}` | Update an inventory item | | Inventory | `DELETE /api/v1/inventory/{id}` | Delete an inventory item | | Clients | `GET /api/v1/contacts` | The contact directory — every party, once | | Clients | `GET /api/v1/clients` | List all clients | | Clients | `POST /api/v1/clients` | Create a new client | | Clients | `GET /api/v1/clients/{id}` | Get a specific client | | Clients | `GET /api/v1/clients/{id}/roles` | List a contact's roles | | Clients | `POST /api/v1/clients/{id}/roles` | Give a contact a role | | Clients | `DELETE /api/v1/clients/{id}/roles` | End a contact's role | | Clients | `GET /api/v1/clients/{id}/relationships` | List a contact's relationships | | Clients | `POST /api/v1/clients/{id}/relationships` | Open a relationship from this contact | | Clients | `DELETE /api/v1/clients/{id}/relationships` | End a relationship | | Clients | `GET /api/v1/clients/{id}/identifiers` | List a contact's identifiers | | Clients | `POST /api/v1/clients/{id}/identifiers` | Record an identifier | | Clients | `DELETE /api/v1/clients/{id}/identifiers` | Remove an identifier | | Clients | `GET /api/v1/realtors` | List realtors | | Clients | `GET /api/v1/realtors/{id}` | Get a realtor | | Clients | `POST /api/v1/realtors/{id}/affiliation` | Set a realtor's brokerage | | Clients | `GET /api/v1/brokerages` | List brokerages | | Clients | `GET /api/v1/brokerages/{id}` | Get a brokerage | | Clients | `PUT /api/v1/projects/{id}/listing-agent` | Set a project's listing agent | | Webhooks | `GET /api/v1/webhooks/subscribe` | List active webhook subscriptions | | Webhooks | `POST /api/v1/webhooks/subscribe` | Subscribe to webhook events | | Webhooks | `DELETE /api/v1/webhooks/subscribe` | Unsubscribe from webhook events | | Services | `GET /api/v1/services` | List all services | | Services | `POST /api/v1/services` | Create a new service | ## Webhooks Subscribe with `POST /api/v1/webhooks/subscribe` (`event_type`, `target_url`, optional `secret`), authenticated with a Zapier OAuth access token. Events: | Event | When | | --- | --- | | `project.created` | A new project was created | | `project.updated` | A project was updated | | `project.status_changed` | A project status changed | | `project.deleted` | A project was deleted | | `client.created` | A new client was added | | `client.updated` | A client was updated | | `client.deleted` | A client was deleted | | `inventory.created` | A new inventory item was added | | `inventory.updated` | An inventory item was updated | | `inventory.status_changed` | An inventory item status changed | | `inventory.deleted` | An inventory item was deleted | | `service.created` | A new service was created | | `service.updated` | A service was updated | | `service.deleted` | A service was deleted | ## Errors and rate limits | Status | Meaning | | --- | --- | | `400` | Malformed or invalid request. | | `401` | Missing or invalid credential. MCP responses include a `WWW-Authenticate` challenge. | | `403` | Valid credential, but the role, plan or scope does not allow the action. | | `404` | No such resource in your organization, or no such path. | | `429` | Rate limited. Wait the number of seconds in `Retry-After`, then retry. | | `5xx` | Server error; safe to retry idempotent reads with backoff. | Error bodies are JSON with an `error` field (OAuth endpoints add `error_description`, per RFC 6749): ```json { "error": "Too many requests. Please try again later." } ``` Burst limits apply per IP on expensive and abuse-prone endpoints, for example OAuth client registration (10 per minute) and public form endpoints (5 to 10 per minute). ## Pricing Every paid plan has a 14-day free trial and a 90-day money-back guarantee. Annual billing saves 20%. Full details: [https://my.designgrow.app/pricing](https://my.designgrow.app/pricing). | Plan | Price | Users | Projects | | --- | --- | --- | --- | | Free | Free forever | 1 user | 5 projects per month | | Starter | $29.95/month, or $24.95/month billed annually | 1 user | Unlimited projects | | Professional | $59.95/month, or $49.95/month billed annually | 5 users | Unlimited projects | | Studio | $99.95/month, or $83.29/month billed annually | 10 users | Unlimited projects | | Enterprise | Custom (contact enterprise@designgrow.app) | Unlimited users | Multi-location operations | Inventory management is an add-on available on every plan: | Inventory tier | Items | Price | | --- | --- | --- | | Free Inventory | 100 items | $0 | | Starter Inventory | 1,000 items | $20.00/month, or $16.00/month billed annually | | Scale Inventory | 10,000 items | $50.00/month, or $40.00/month billed annually | | Unlimited Inventory | Unlimited items | $100.00/month, or $80.00/month billed annually | ## Discovery files | File | What it is | | --- | --- | | [/.well-known/ai-catalog.json](https://my.designgrow.app/.well-known/ai-catalog.json) | AI Catalog listing the resources below | | [/mcp/server-card](https://my.designgrow.app/mcp/server-card) | MCP server card (SEP-2127) | | [/docs/mcp/server-card](https://my.designgrow.app/docs/mcp/server-card) | Server card for the public docs MCP | | [/server.json](https://my.designgrow.app/server.json) | MCP Registry entry | | [/openapi.json](https://my.designgrow.app/openapi.json) | OpenAPI 3.1 contract | | [/llms.txt](https://my.designgrow.app/llms.txt) | Index of key pages for language models | | [/llms-full.txt](https://my.designgrow.app/llms-full.txt) | These docs in one text file | | [/docs.md](https://my.designgrow.app/docs.md) | These docs as Markdown | Need help? Email support@designgrow.app.