# Connector Guide for AI
This guide is structured as context for an AI coding assistant. It defines the exact files, host values, examples, and guardrails needed to generate a Mado Connector.

Human page: https://madomd.com/connectors
Markdown contract for AI agents: https://madomd.com/connectors.md

## AI Prompt
Use this prompt as the starting point when asking an AI coding assistant to create a connector:

**ai-prompt.txt**

```text
Read https://madomd.com/connectors.md for the current Mado Connector contract.
Create a Mado Connector that publishes the current rendered document to <service>.
Return exactly two files: mado.json and run.js.
Use cfg.endpoint and cfg.token from mado.json.
In run.js, use mado.html, mado.title, mado.fileKey, mado.sourceURL, and fetch.
Do not use Node packages, shell commands, or local filesystem access.
Return { url, message } when the API returns a published URL.
```

## Connector Contract
Ask the AI for one connector folder that publishes the current rendered document to one destination.

The AI should return a small, inspectable connector. It should not create a general plugin platform, a publishing pipeline, or a local automation runtime.

## Host Values
- mado.html: Generated standalone HTML. Use this as the default payload for AI-generated connectors.
- mado.title: The current document title.
- mado.fileKey: A safe filename such as Product-Plan.html.
- mado.sourceURL: The local source file path when available.
- cfg: User-provided config values from mado.json, such as cfg.endpoint and cfg.token.
- fetch: A Mado-provided network API for HTTP requests.
- console: Log output that Mado can show during connector runs.

## Generation Rules
- Generate one connector folder with exactly mado.json and run.js unless the user asks for surrounding docs.
- Handle one export job for the current document. Do not design a plugin system or folder publisher.
- Prefer mado.html when the destination should preserve the rendered reading experience.
- Use config fields for endpoints and tokens. Never hard-code private values.
- Return a URL when the destination creates a readable page, and throw a clear Error when publishing fails.
- Do not invent host APIs. Use only mado, cfg, fetch, and console.
- Do not assume access to the local file system.
- Do not run shell commands.
- Do not publish entire folders.
- Do not require Node, Bun, Deno, npm, or external packages.
- Secrets belong in config fields marked with secret: true.

## Return this folder shape.

The AI should produce a connector folder that can be inspected quickly. Keep the output small so the user can paste it into Mado without build tooling.

- mado.json: Manifest file. It gives Mado a display name, capabilities, and config fields for the user to fill in.
- run.js: Runtime file. It exports the async run() flow that receives mado, cfg, fetch, and console from Mado.

**connector/**

```text
connector/
  mado.json
  run.js
```

## Describe the destination in mado.json.

The manifest is the UI and configuration contract. It tells Mado what to show, which capabilities are supported, and which values the user must provide before publish.

- name: Display name shown in Mado (required).
- description: One line that tells the user where the document will be published.
- icon: Optional SF Symbol name for the connector's icon. Falls back to a default when omitted.
- capabilities: Optional flags: delete means the service can unpublish, update means a later publish can update the same page. Both default to true, so declare false when the API cannot support them.
- config: Fields Mado asks the user to fill in. Mark private values with secret: true.

**mado.json**

```json
{
  "name": "Team Knowledge",
  "description": "Publish rendered Mado documents to Team Knowledge.",
  "icon": "arrow.up.circle",
  "capabilities": { "delete": false, "update": true },
  "config": [
    { "key": "endpoint", "label": "Publish URL", "required": true },
    { "key": "token", "label": "API Token", "secret": true }
  ]
}
```

## Write run.js against the host values.

The run script should be boring and explicit. It receives the current document and user config, performs one network request, checks the response, and returns a useful result.

- mado.html: Generated standalone HTML. Use this as the default payload for AI-generated connectors.
- mado.title: The current document title.
- mado.fileKey: A safe filename such as Product-Plan.html.
- mado.sourceURL: The local source file path when available.
- cfg: User-provided config values from mado.json, such as cfg.endpoint and cfg.token.
- fetch: A Mado-provided network API for HTTP requests.
- console: Log output that Mado can show during connector runs.

### Default AI template: send metadata and HTML

Use this first when the service accepts JSON. It keeps title, file key, source path, and rendered HTML together.

**run.js**

```javascript
async function run() {
  const response = await fetch(cfg.endpoint, {
    method: "POST",
    headers: {
      "Authorization": "Bearer " + cfg.token,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      title: mado.title,
      fileKey: mado.fileKey,
      sourceURL: mado.sourceURL,
      html: mado.html
    })
  });

  if (!response.ok) {
    throw new Error("Publish failed: " + response.status);
  }

  const data = await response.json();
  return {
    url: data.url,
    message: "Published " + mado.title
  };
}
```

## Start from a template before inventing code.

Most AI-generated connectors should be one POST request plus response handling. Pick the closest template, then only adapt headers, body shape, and result parsing.

- Default AI template: send metadata and HTML
- HTML-only endpoint
- Return a published URL

### HTML-only endpoint

Use this when the API wants the rendered document body directly.

**run.js**

```javascript
async function run() {
  const response = await fetch(cfg.endpoint, {
    method: "POST",
    headers: {
      "Authorization": "Bearer " + cfg.token,
      "Content-Type": "text/html"
    },
    body: mado.html
  });

  if (!response.ok) {
    throw new Error("Upload failed: " + response.status);
  }

  return { message: "Uploaded " + mado.fileKey };
}
```

### Return a published URL

Return a URL when the destination creates a page Mado can copy or open.

**run.js**

```javascript
async function run() {
  const response = await fetch(cfg.endpoint, {
    method: "POST",
    headers: {
      "Authorization": "Bearer " + cfg.token,
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      filename: mado.fileKey,
      html: mado.html
    })
  });

  if (!response.ok) {
    throw new Error("Publish failed: " + response.status);
  }

  const data = await response.json();
  return {
    url: data.url,
    message: "Published " + mado.fileKey
  };
}
```

## Constrain the model.

The safest connector is easy to read in one pass. If the AI produces extra files, dependencies, retries, queues, local file access, or multi-document publishing, ask it to simplify.

- Generate one connector folder with exactly mado.json and run.js unless the user asks for surrounding docs.
- Handle one export job for the current document. Do not design a plugin system or folder publisher.
- Prefer mado.html when the destination should preserve the rendered reading experience.
- Use config fields for endpoints and tokens. Never hard-code private values.
- Return a URL when the destination creates a readable page, and throw a clear Error when publishing fails.
- Do not invent host APIs. Use only mado, cfg, fetch, and console.
- Do not assume access to the local file system.
- Do not run shell commands.
- Do not publish entire folders.
- Do not require Node, Bun, Deno, npm, or external packages.
- Secrets belong in config fields marked with secret: true.
