# AetherDesk Connector

AetherDesk exposes a ChatGPT/LLM-friendly MCP endpoint at:

```text
http://127.0.0.1:5717/mcp
```

When deployed behind HTTPS, use the public URL:

```text
https://<your-host>/mcp
```

## Onboarding (first-run)

Use this exact sequence for first use:

1. Start AetherDesk connector server.
2. Probe auth and tool surface.
3. Configure client in token mode when you move off localhost.
4. Re-run probe until green.

```powershell
cd C:\Users\issda\AetherDesk
npm run start:react

# one-shot local onboarding report (JSON)
npm run connector:onboard -- --json
```

Output includes:

- `mode` (`disabled` or `token`)
- `checks.mcp_ok` and `checks.connector_ok`
- `tools` + `tool_count`
- `bearer_header` (example auth header to paste for cloud clients)

In token mode, capture:

```powershell
Set-Item Env:AETHERDESK_CONNECTOR_AUTH_MODE token
Set-Item Env:AETHERDESK_CONNECTOR_AUTH_TOKEN "set_a_random_token_here"
npm run connector:onboard
```

If `checks.*` are failing, stop and fix host/base URL before sharing this URL with any LLM client.

## Repeatable onboarding (local and hosted)

Run this every time you add a new client or move the service endpoint:

```powershell
# 1) local/offline onboarding
npm run connector:onboard -- --base "http://127.0.0.1:5717" --json

# 2) hosted/token onboarding
$env:AETHERDESK_CONNECTOR_AUTH_MODE = "token"
$env:AETHERDESK_CONNECTOR_AUTH_TOKEN = "<random>"
npm run connector:onboard -- --base "https://<your-host>" --json

# 3) one-shot verification
curl -X POST "https://<your-host>/mcp" `
  -H "Authorization: Bearer <random>" `
  -H "content-type: application/json" `
  -d '{ "jsonrpc":"2.0", "id":1, "method":"tools/call", "params": { "name":"aetherdesk_health", "arguments": {} } }'
```

Pass criteria:
- `checks.mcp_ok === true`
- `checks.connector_ok === true`
- `mode === disabled` only for localhost/private environments
- `mode === token` for any externally reachable endpoint
- `tool_count` at least `20`
- auth endpoint missing-token response is `401` + `aetherdesk_connector_auth_required_v0`

### Local (same-machine) setup

1. Start AetherDesk:

```powershell
cd C:\Users\issda\AetherDesk
npm run start:react
```

2. Verify connector path:

- MCP: `http://127.0.0.1:5717/mcp`
- OpenAI-style: `http://127.0.0.1:5717/connector`

3. Run smoke checks:

```powershell
npm run connector:smoke
npm run connector:openai-smoke
```

### Public/Cloud setup

For ChatGPT/LLM services, do not expose bare `127.0.0.1`.

Use HTTPS deployment or tunnel and enable token mode:

```powershell
$env:AETHERDESK_CONNECTOR_AUTH_MODE = "token"
$env:AETHERDESK_CONNECTOR_AUTH_TOKEN = "set_a_random_token_here"
```

Then use:

- `https://<your-host>/mcp` for MCP JSON-RPC
- `https://<your-host>/connector` or `/api/connector` for OpenAI function-call mode

Send one of:

- `Authorization: Bearer <token>`
- `x-aetherdesk-token: <token>`

If token mode is enabled, missing token returns:

- HTTP `401`
- schema `aetherdesk_connector_auth_required_v0`

## Local Run

```powershell
cd C:\Users\issda\AetherDesk
npm run start:react
```

Smoke-test the connector:

```powershell
npm run connector:smoke
```

The smoke test starts an isolated local AetherDesk server, calls `/mcp`, lists tools,
opens the Browser app through `aetherdesk_open_app`, checks the desktop state, and
confirms shell execution is denied by default.

Connector auth smoke path:

```powershell
Set-Item Env:AETHERDESK_CONNECTOR_AUTH_MODE token
Set-Item Env:AETHERDESK_CONNECTOR_AUTH_TOKEN test_token
npm run connector:smoke
```

Unset token mode back to disabled when done:

```powershell
Remove-Item Env:AETHERDESK_CONNECTOR_AUTH_MODE -ErrorAction SilentlyContinue
Remove-Item Env:AETHERDESK_CONNECTOR_AUTH_TOKEN -ErrorAction SilentlyContinue
```

## ChatGPT Connector Shape

Add a custom MCP connector in ChatGPT with the public HTTPS endpoint:

```text
https://<your-host>/mcp
```

The same service also exposes an OpenAI-style function-call surface at:

```text
https://<your-host>/connector
https://<your-host>/api/connector
```

Open these to fetch OpenAI-compatible tool schemas:

```text
GET /connector/tools
GET /connector
GET /api/connector
```

Invoke a tool by POSTing either a plain tool request or an OpenAI tool-call shape:

```bash
curl -X POST http://127.0.0.1:5717/connector/invoke \
  -H "content-type: application/json" \
  -d "{\"name\":\"aetherdesk_health\",\"arguments\":{}}"
```

For local-only development, ChatGPT cloud cannot reach `127.0.0.1`; expose the
local server through a temporary tunnel or deploy the read-only connector wrapper.

Common request:

```json
{
  "name": "aetherdesk_open_app",
  "arguments": { "app": "browser" }
}
```

### ChatGPT / multi-model onboarding note

For any external LLM client:

- Prefer `/connector` for function-calling compatibility.
- Prefer `/mcp` for pure MCP JSON-RPC clients.
- In production / demo mode, require token auth; leave it disabled only for local-only LAN testing.
- Onboarding is complete when:
  - `/mcp` responds `200` and endpoint is `/mcp`
  - `/connector` responds `200` with `aetherdesk_connector_openai_manifest_v0`
  - token mode is intentional and documented (`AETHERDESK_CONNECTOR_AUTH_MODE=token`)
  - tool list includes required action names (`aetherdesk_open_app`, `aetherdesk_desktop_state`, etc.)

#### One-page onboarding checklist

- **Local/private endpoint**
  - Endpoint: `http://127.0.0.1:5717` (or LAN equivalent)
  - Auth mode: `disabled`
  - Verify:
    - `npm run connector:onboard -- --base http://127.0.0.1:5717 --json`
    - `checks.mcp_ok == true`
    - `checks.connector_ok == true`

- **Public/shared endpoint**
  - Endpoint: `https://<your-host>`
  - Auth mode: `token`
  - Verify:
    - `Set-Item Env:AETHERDESK_CONNECTOR_AUTH_MODE token`
    - `Set-Item Env:AETHERDESK_CONNECTOR_AUTH_TOKEN <strong-random>`
    - `npm run connector:onboard -- --base https://<your-host> --json`
    - `checks.mcp_ok == true`, `checks.connector_ok == true`, `mode == "token"`
    - one unauth request to each endpoint is `401` + schema `aetherdesk_connector_auth_required_v0`

Minimal client auth examples:

- `Authorization: Bearer <token>`
- `x-aetherdesk-token: <token>`

## Vercel Shape

This repo includes a Vercel-compatible Express function:

```text
api/mcp.js
vercel.json
```

Deploying the repo to Vercel gives the connector an HTTPS endpoint at:

```text
https://<vercel-project>.vercel.app/mcp
```

`vercel.json` rewrites `/mcp` to `/api/mcp`, so ChatGPT and other MCP clients can
use the clean `/mcp` connector URL instead of a Vercel implementation path.

Set `AETHERDESK_CONNECTOR_BASE_URL` only when the hosted connector should bridge to
a reachable AetherDesk desktop server or tunnel. If it is unset, cloud mode still
serves ecosystem, prime-grid, Proton-reference, and connector-info tools, while
desktop tools report that no bridge is configured.

## Tools

Desktop tools:

- `aetherdesk_connector_info`
- `aetherdesk_health`
- `aetherdesk_list_apps`
- `aetherdesk_desktop_state`
- `aetherdesk_open_app`
- `aetherdesk_shell_profiles`
- `aetherdesk_run_shell_profile`
- `aetherdesk_web_audit`
- `aetherdesk_revenue_meter`

Existing ecosystem tools:

- `ecosystem_search`
- `ecosystem_get_entry`
- `ecosystem_list_categories`
- `ecosystem_library_excerpt`
- `ecosystem_path_status`
- `prime_grid_generate`
- `prime_grid_classify`
- `proton_status`
- `proton_pass_reference`
- `proton_drive_reference`
- `proton_vpn_reference`

## Safety Boundary

- The connector never exposes arbitrary shell text.
- Shell profile execution is disabled by default.
- To allow shell profile execution, the server operator must explicitly set:

```powershell
$env:AETHERDESK_CONNECTOR_ALLOW_SHELL = "1"
```

- Even when enabled, it only runs allowlisted profiles from AetherDesk's existing
  `/api/shell/run` gate.
- Proton tools are reference/status only and must not return resolved secret values.
- Public tunnels should be treated as temporary unless they are deliberately
  hardened with auth and monitoring.
- Lightweight auth mode is supported by:
  - `AETHERDESK_CONNECTOR_AUTH_MODE` (`disabled` or `token`)
  - `AETHERDESK_CONNECTOR_AUTH_TOKEN`
- `aetherdesk_connector_info` reports:
  - `auth.mode`: current mode
  - `auth.token_required`: whether callers must supply token

## Web Page Audit

Use `aetherdesk_web_audit` when a model needs to inspect a public site before
suggesting UI, copy, accessibility, responsive-layout, or A/B-test changes.

CLI:

```powershell
npm run web:audit -- --url https://example.com --screenshots --full-page
```

Connector call:

```json
{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "tools/call",
  "params": {
    "name": "aetherdesk_web_audit",
    "arguments": {
      "url": "https://example.com",
      "mobile": true
    }
  }
}
```

By default the audit refuses `localhost`, private LAN hosts, and URL credentials
so a public connector cannot be used as an SSRF probe. For local-only testing:

```powershell
$env:AETHERDESK_WEB_AUDIT_ALLOW_LOCAL = "1"
```

## Terminal Revenue Meter

Use `aetherdesk_revenue_meter` when a model needs to answer "what did the terminal/API usage produce, what should we reserve for API cost,
and what offer tier should this usage map to?"

CLI:

```powershell
npm run revenue:terminal
npm run revenue:terminal -- --summary
```

Connector call:

```json
{
  "jsonrpc": "2.0",
  "id": 8,
  "method": "tools/call",
  "params": {
    "name": "aetherdesk_revenue_meter",
    "arguments": {
      "limit": 500
    }
  }
}
```

The meter returns `aetherdesk_terminal_revenue_v0`: metered events, successful events, gross usage value, API-cost reserve, estimated net,
breakdown by event type, and a recommended offer tier. It does not charge money or call Stripe; it is the local proof and pricing layer that
can feed billing later.

## Direct MCP Calls

Initialize:

```json
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}
```

List tools:

```json
{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}
```

Open Browser:

```json
{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "aetherdesk_open_app",
    "arguments": { "app": "browser" }
  }
}
```
