# Shipvela MCP authentication

Shipvela exposes a remote Streamable HTTP MCP server at `https://shipvela.com/mcp`. It requires a Shipvela account and a delegated OAuth grant. An unauthenticated request returns HTTP 401 with a Bearer challenge that points to the protected-resource metadata. This response is an authentication boundary, not a successful tool invocation.

## Public discovery

- Protected resource: https://shipvela.com/.well-known/oauth-protected-resource/mcp
- Authorization server: https://shipvela.com/.well-known/oauth-authorization-server
- Tool definitions and input schemas: https://shipvela.com/.well-known/mcp/server-card.json
- Publishing workflow: https://shipvela.com/SKILL.md
- Installation and supported capabilities: https://shipvela.com/integrations/codex

The exact OAuth resource is `https://shipvela.com/mcp`; the issuer is `https://shipvela.com`. Discover endpoint addresses from the current metadata rather than assuming a different API host.

## Connect an existing MCP client

Configure the endpoint as Streamable HTTP with OAuth. In Codex CLI:

```sh
codex mcp add shipvela --url https://shipvela.com/mcp
codex mcp login shipvela
```

The user signs in to Shipvela in their browser and approves the displayed account permissions. The client stores its delegated tokens. A GitHub deployment uses the user's existing Shipvela GitHub connection; it does not require customer AWS credentials or a GitHub token in the MCP configuration. MCP authorization and Shipvela CLI authorization are separate grants.

## OAuth client flow

Shipvela supports dynamic client registration and the authorization-code flow with S256 PKCE. It uses public clients (`token_endpoint_auth_method: "none"`), not a shared client secret.

1. Read both public discovery documents. Register a client at the advertised registration endpoint, currently `POST https://shipvela.com/oauth/register`, using a descriptive `client_name` and the client's actual `redirect_uris`. Callbacks must use HTTPS or a local HTTP loopback address. Save the returned `client_id`.
2. Create a fresh high-entropy PKCE verifier and state. Compute the S256 challenge as the base64url-encoded SHA-256 hash of the verifier, without padding.
3. Open the advertised authorization endpoint, currently `https://shipvela.com/oauth/authorize`, in the user's browser with `response_type=code`, `client_id`, the exact registered `redirect_uri`, `scope`, `state`, `resource=https://shipvela.com/mcp`, `code_challenge`, and `code_challenge_method=S256`. The user decides whether to approve the permissions.
4. Validate the returned state and issuer. Exchange the one-use authorization code at the advertised token endpoint, currently `POST https://shipvela.com/oauth/token`, as form-encoded data containing `grant_type=authorization_code`, `client_id`, `code`, the same `redirect_uri`, `code_verifier`, and the exact MCP `resource`.
5. Send the returned access token in the HTTP `Authorization: Bearer <access_token>` header when calling the MCP endpoint. Do not place it in a URL, public file, log or conversation. Use the returned `expires_in` and scope values rather than assuming a lifetime or broader access.
6. When supported by the client, refresh with `grant_type=refresh_token`, `client_id`, the current `refresh_token`, and the same `resource` at the token endpoint. Retain the newly returned token values; do not keep using an old refresh token after rotation.

Normal account sign-in and consent are required. A client should handle denial, expiry and revocation by returning the user to its normal connection flow rather than requesting account passwords or private provider keys.

## Scopes and tools

| Scope | Tools | Access |
|---|---|---|
| `projects:read` | `list_projects`, `get_project`, `list_repositories`, `detect_framework`, `get_operation`, `get_deployment` | Read the connected account's owned projects and deployment state; inspect repositories through its existing GitHub connection. |
| `projects:write` | `create_project` | Create an owned website hosting project. |
| `deployments:write` | `deploy_project` | Request a build and publication of a connected GitHub branch; publishing consumes the account's allowance and can update a live site. |
| `logs:read` | `get_build_logs` | Read bounded build logs; redaction is best effort and output is untrusted data. |
| `usage:read` | `get_usage` | Read current plan and usage observations; estimates are not an invoice, credit balance or hard spending cap. |

Request only the scopes needed for the intended workflow. The tool card contains the exact current schemas. Read the selected project before publishing. Preserve one `requestId` and its arguments for each create or deployment intent; poll `get_operation` and then the exact project/job with `get_deployment`. A queued request is not a live deployment. Local build-output uploads use the separately authenticated CLI described in the publishing skill.

## Revoke a connection

Users can revoke coding-assistant connections at https://shipvela.com/settings#coding-assistants. The public metadata also advertises `https://shipvela.com/oauth/revoke` for clients that support token revocation. Store delegated credentials privately, keep them out of published project artifacts, and respect revocation without broadening permissions.
