---
summary: "Register a hosted MCP server, watch its tools appear in the catalog, invoke\
  \ one \u2014 five minutes end-to-end."
title: Quickstart
path: quickstart
status: published
---

In five minutes you'll register a cloud MCP server with ScaiGrid, see its tools auto-discovered, and invoke one. This path uses the cloud registry rather than the desktop bridge because it needs nothing on your machine but a terminal.

You need:

- A ScaiGrid API key with `scailink:remote.manage_own` (tenant admins have it by default).
- The URL of a reachable MCP server speaking `streamable_http` or `sse`. A public test server, your own deployment, or a third party.
- The credential the server needs — bearer token, API key headers, or nothing for an open server.

```bash
export SCAIGRID_HOST="https://scaigrid.scailabs.ai"
export SCAIGRID_API_KEY="sgk_..."
```

## 1. Register the server

```bash
curl -X POST "$SCAIGRID_HOST/v1/modules/scailink/remote-servers" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My GitHub MCP",
    "endpoint_url": "https://mcp.example.com/mcp",
    "auth_type": "bearer",
    "credentials": {"authorization": "ghp_..."},
    "is_tenant_shared": false,
    "transport": "streamable_http"
  }'
```

```python
import httpx, os
server = httpx.post(
    f"{os.environ['SCAIGRID_HOST']}/v1/modules/scailink/remote-servers",
    headers={"Authorization": f"Bearer {os.environ['SCAIGRID_API_KEY']}"},
    json={
        "name": "My GitHub MCP",
        "endpoint_url": "https://mcp.example.com/mcp",
        "auth_type": "bearer",
        "credentials": {"authorization": "ghp_..."},
        "is_tenant_shared": False,
        "transport": "streamable_http",
    },
).json()["data"]
print(server["id"], server["slug"], server["status"])
```

```javascript
const res = await fetch(`${process.env.SCAIGRID_HOST}/v1/modules/scailink/remote-servers`, {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCAIGRID_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "My GitHub MCP",
    endpoint_url: "https://mcp.example.com/mcp",
    auth_type: "bearer",
    credentials: { authorization: "ghp_..." },
    is_tenant_shared: false,
    transport: "streamable_http",
  }),
});
const { data: server } = await res.json();
console.log(server.id, server.slug, server.status);
```

Registration triggers an immediate discovery handshake against the endpoint. If the server is reachable, `status` is `active` and tool rows are populated. If unreachable, the registration still saves with `status: "error"` — fix the network or credentials and call `refresh` rather than re-registering.

## 2. List discovered capabilities

```bash
SERVER_ID="..."  # from step 1
curl "$SCAIGRID_HOST/v1/modules/scailink/remote-servers/$SERVER_ID" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY"
```

The detail response includes `capabilities`, `credential_fields`, `credential_oldest_days`, and `consecutive_failures`. Capabilities is the list of tools, resources, and prompts that the server advertised during discovery.

## 3. Re-discover on demand

If you've changed something on the server side and want fresh capability rows immediately rather than waiting for the 15-minute cron:

```bash
curl -X POST "$SCAIGRID_HOST/v1/modules/scailink/remote-servers/$SERVER_ID/refresh" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY"
```

This re-runs the handshake, upserts capability rows, and resets the failure streak on success.

## 4. Invoke a tool through ScaiMCP

Once registered, the server's tools appear in the ScaiMCP catalog under `remote.{user_id}.{slug}.{tool_name}` for personal scope, or `remote.tenant.{slug}.{tool_name}` for tenant-shared scope. Any ScaiGrid surface that consumes MCP (agents, chat, ScaiCore runs) sees them.

```bash
curl -X POST "$SCAIGRID_HOST/v1/modules/scaimcp/tools/$TOOL_NAME/call" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"arguments": {"repo": "owner/name"}}'
```

ScaiLink resolves the namespaced name back to the registered server, fetches its credentials, opens (or reuses) a session, and forwards the call.

## 5. Rotate a credential

When the upstream credential needs replacing — token expired, rotated by your security policy — rotate it in place. The server keeps its id; capability rows and namespaced tool names don't churn.

```bash
curl -X PUT "$SCAIGRID_HOST/v1/modules/scailink/remote-servers/$SERVER_ID/credentials/authorization" \
  -H "Authorization: Bearer $SCAIGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"value": "ghp_new..."}'
```

The PUT is idempotent on `(server, field)` — overwriting an existing credential overwrites both ciphertext and DEK.

## What just happened

- A row landed in `mod_scailink_remote_server` for your server; credentials went to `mod_scailink_remote_credential` encrypted with the platform KEK.
- ScaiLink opened the server, called `tools/list` / `resources/list` / `prompts/list`, and wrote one capability row per item.
- The discovery cron now refreshes you on its 15-minute cadence, with a per-tenant budget of 10 servers per tick.
- Your tool names are namespaced so they can't collide with another tenant's registration of the same display name.

## Next

- [Cloud MCP registry](./concepts/cloud-mcp-registry) — scope, namespacing, credentials, health, session pool, rotation hygiene.
- [Architecture](./concepts/architecture) — how the bridge and the registry fit into the agent runtime.
- [Run a desktop session](./tutorials/run-a-desktop-session) — bridge a local MCP server instead of a hosted one.
- [Register a cloud MCP server](./tutorials/register-a-cloud-mcp-server) — tenant-shared scope, multi-header auth, `forward_user_id`, custom `consent_tier`.
