# Register an MCP upstream

Source: https://immiscible.fly.dev/docs/api/post-api-w-wid-mcp-upstreams

`POST /api/w/:wid/mcp-upstreams`

Owners and admins. Immiscible then asks the upstream what it offers (see `discovery` in the response). HTTPS only; private and internal addresses are refused as written and as resolved.

| Field | Description |
|---|---|
| `name` | how people and the proxy URL know it |
| `url` | the upstream's address |
| `transport` | `mcp` (Streamable HTTP) or `http` (a plain API described in `httpTools`) |
| `auth` | `{ kind, secret, name }` with `kind` one of `none`, `bearer`, `header`, `query` |
| `allowedTools` | tool names, or `["*"]`; empty means none |
| `toolMap` | per-tool meaning: `type`, `targetPath`, `amountPath`, `amountUnit`, `currency`, `merchantPath` |

## Authentication

Session cookie. A signed-in person: the console's session cookie. Every state-changing request also carries the header `x-immiscible-csrf: 1`, and the member's role decides what it may do. Bearer tokens are ignored on these routes, so no machine credential can reach them.

## Path parameters

- `wid` (string, required): Workspace id

## Request

curl:

```bash
curl -X POST "https://immiscible.fly.dev/api/w/$IMMISCIBLE_WORKSPACE/mcp-upstreams" \
  -H "cookie: __Host-sid=$IMMISCIBLE_SESSION" \
  -H "x-immiscible-csrf: 1" \
  -H "content-type: application/json" \
  -d '{
    "name": "github",
    "url": "https://api.githubcopilot.com/mcp/",
    "transport": "mcp",
    "auth": {
      "kind": "bearer",
      "secret": "ghp_..."
    },
    "allowedTools": [
      "list_issues",
      "create_pull_request"
    ],
    "toolMap": {}
  }'
```

Node:

```ts
const res = await fetch('https://immiscible.fly.dev/api/w/$IMMISCIBLE_WORKSPACE/mcp-upstreams', {
  method: 'POST',
  headers: {
    cookie: `__Host-sid=${process.env.IMMISCIBLE_SESSION}`,
    'x-immiscible-csrf': '1',
    'content-type': 'application/json',
  },
  body: JSON.stringify({
    name: 'github',
    url: 'https://api.githubcopilot.com/mcp/',
    transport: 'mcp',
    auth: {
      kind: 'bearer',
      secret: 'ghp_...',
    },
    allowedTools: ['list_issues', 'create_pull_request'],
    toolMap: {},
  }),
});
const data = await res.json();
console.log(res.status, data);
```

Python:

```python
import os
import requests

res = requests.post(
    "https://immiscible.fly.dev/api/w/$IMMISCIBLE_WORKSPACE/mcp-upstreams",
    headers={
        "cookie": f"__Host-sid={os.environ['IMMISCIBLE_SESSION']}",
        "x-immiscible-csrf": "1",
        "content-type": "application/json",
    },
    json={
        "name": "github",
        "url": "https://api.githubcopilot.com/mcp/",
        "transport": "mcp",
        "auth": {
            "kind": "bearer",
            "secret": "ghp_...",
        },
        "allowedTools": ["list_issues", "create_pull_request"],
        "toolMap": {},
    },
)
print(res.status_code, res.json())
```
