# Connect GradientArt to a plugin or MCP client

GradientArt exposes one anonymous remote MCP tool: `prepare_design`.
It validates a complete version-1 design, temporarily stores it, and returns an
editable, unsaved editor link. No account, API key, OAuth, or cookies are needed.

## Connection

- **Server URL:** `https://gra.dient.art/api/mcp`
- **Transport:** Streamable HTTP
- **Authentication:** None
- **Tool:** `prepare_design`

Deploy the endpoint before connecting a hosted client. Localhost is only useful
for local testing; it is not reachable from ChatGPT. This is a stateless
Streamable HTTP endpoint, not a legacy SSE endpoint. It supports POST and does
not issue MCP session IDs. GET, DELETE, and OPTIONS return 405; a client probing
for a standalone GET event stream should continue using POST.

The server handles initialization, tool discovery, and calls through the official
MCP SDK. Responses are JSON rather than long-lived event streams. Clients must
send the standard Streamable HTTP Accept header supporting both
`application/json` and `text/event-stream`.

## Update an existing private ChatGPT plugin

Ask the plugin creator to update the existing plugin, not create or publish a new
one. Preserve its identity, instructions, assets, and private visibility. Add the
server URL above with no authentication, refresh/scan its tools, and connect the
design-generation workflow to `prepare_design`.

Paste this into the plugin creator after deploying:

> Update my existing GradientArt plugin without changing its identity or private
> visibility. Add the remote MCP server https://gra.dient.art/api/mcp using
> Streamable HTTP and no authentication. Discover its prepare_design tool and use
> it for generated artwork instead of trying to execute an unconfigured HTTP
> POST. Pass the complete GradientArt v1 JSON file as the document argument.
> Read https://gra.dient.art/agents/designs.md and its linked schemas first.
> Return the exact editorUrl and expiresAt from successful structuredContent.
> Treat isError as failure; respect retryAfter and never invent a link.
> Explain that the design is temporarily stored, the link expires after one
> hour, anyone with it can access the design, and opening does not save.
> Keep the JSON download/import fallback. Do not publish the plugin or change
> its audience. Verify the connection and report any account-permission blocker.

Connection controls and availability depend on the client/account. Adding this
endpoint does not itself modify or publish a plugin. A **private plugin does not
make this anonymous endpoint private**: anyone can call it, subject to quotas.

## Tool input and result

Tool arguments have one required field, `document`, containing the **entire
versioned file**, not the inner `project.document` metadata:

```json
{
  "document": {
    "format": "gradient-art",
    "version": 1,
    "project": {
      "document": {
        "title": "Blue hour",
        "description": "",
        "keywords": [],
        "width": 500,
        "height": 500
      },
      "backgrounds": [
        {
          "name": "Sky",
          "visible": true,
          "position": [0, 0],
          "size": [500, 500],
          "repeat": [false, false],
          "gradient": {
            "type": "linear",
            "angle": 135,
            "repeat": 1,
            "stops": [
              { "color": [20, 40, 100, 1], "position": 0 },
              { "color": [100, 190, 255, 1], "position": 100 }
            ]
          }
        }
      ],
      "variables": [],
      "cloneSources": {}
    }
  }
}
```

Discovery exposes a compact envelope schema rather than sending every layer
schema with each tool listing. Follow the
[modular schema](https://gra.dient.art/schemas/v1/project.schema.json) or
[bundled schema](https://gra.dient.art/schemas/gradient-art-v1.schema.json) when
authoring. The server enforces the complete schema and semantic relationships.

Success returns `structuredContent` with exactly `editorUrl`, `expiresAt`, and
`saved: false`, plus a text content block containing the same JSON. Present the
returned URL unchanged. Every call creates a new one-hour link; calls are not
idempotent and do not save projects.

The tool uses the **same preparation service** as
`POST /api/v1/designs/prepare`, without a loopback HTTP request. It preserves
validation, trusted-client-IP accounting, global quotas, temporary collections,
and expiry. MCP protocol responses use HTTP 200 for completed tool calls; they
do not use the REST API's HTTP 201 success status.

## Failures and limits

Application failures return `isError: true`, no success `structuredContent`, and
a text JSON object containing `error` and `httpStatus`. `error` preserves the
REST service's code, message, validation paths/issues when present, and
`retryAfter` for quota failures. A completed MCP request is not necessarily a
successful preparation: always check `isError`.

Invalid JSON, unsupported transport headers, oversized envelopes, and disallowed
browser origins fail at the HTTP/protocol layer instead. Do not retry malformed
requests unchanged.

- Designs are limited to 4 MiB of serialized UTF-8 JSON. The MCP request allows
  an additional 16 KiB for its JSON-RPC envelope.
- The tool shares the REST API's preparation quotas: 20/hour per trusted client
  IP and 100/hour globally. Invalid tool input also consumes preparation quota.
- Initialization and discovery do not access storage or consume preparation
  quota. Hosted clients may share an egress IP and therefore a quota.
- Do not automatically retry successful or timed-out submissions; a timeout
  can occur after storage. Explain uncertainty before issuing another request.

No tool reads, saves, updates, or publishes permanent projects. The editor still
requires confirmation before replacing existing work. See the
[authoring guide](https://gra.dient.art/agents/designs.md) for file fallback,
expiry, bearer-link privacy, and retention.

## Deployment and verification

The endpoint runs inside the existing Next.js app, with the same MongoDB,
`NEXTAUTH_URL`, `NEXTAUTH_SECRET`, and trusted-proxy configuration as the
preparation API. Do not copy secrets into the plugin. Configure a trusted IP
header only when the hosting proxy overwrites it, as for the REST endpoints.

Keep the endpoint reachable over public HTTPS. Do not place a login redirect
or deployment-protection page in front of it. Server-to-server clients may omit
Origin; browser origins other than the configured canonical application origin
are rejected. There is no cross-origin browser CORS support.

After deployment, connect with MCP Inspector or a supported client, verify that
only `prepare_design` is listed, submit the minimal example, and open the exact
returned editor URL. Confirm that it is editable and unsaved. Rescan the tools
in the existing plugin and test there too; local SDK tests do not verify an
account's hosted plugin permissions.

Repository checks:

```sh
node --test tests/design-mcp.test.mjs tests/design-handoffs.test.mjs
```
