> ## Documentation Index
> Fetch the complete documentation index at: https://docs.auto.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Sentry first-install setup

> Connect Sentry once for scoped issue investigation and issue events, then manage this project's selection.

Use one Public App approval to connect Sentry for read-only issue investigation and issue events. This guide covers the project Connections workflow, installation and project-selection APIs, and scoped agent tools. Connecting does not install the [issue-triage managed template](/reference/managed-templates#sentry-issue-triage) or configure [runtime Sentry telemetry](/guides/sentry-observability).

<Warning>
  An existing installation can be reused by projects in the same auto organization. Independent cross-organization linking remains unsupported. Merged implementation is not proof of App publication, deployed migrations, tenant installation, webhook delivery, or automation activation. Operator setup and live verification require separate authorization.
</Warning>

## Operator prerequisites

The platform operator configures the public App and the server, rather than asking customers to create an App or copy its credentials:

| Configuration                                                                  | Requirement                                                                                                                                                         |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `AUTO_WEB_BASE_URL`                                                            | The canonical deployment origin used to construct the callback URL.                                                                                                 |
| `AUTO_PROVIDER_SENTRY_APP_UUID`, `AUTO_PROVIDER_SENTRY_APP_SLUG`               | The exact public App identity.                                                                                                                                      |
| `AUTO_PROVIDER_SENTRY_APP_CLIENT_ID`, `AUTO_PROVIDER_SENTRY_APP_CLIENT_SECRET` | Server-side App credentials.                                                                                                                                        |
| `AUTO_PROVIDER_SENTRY_APP_VERIFY_INSTALL`                                      | The literal string `true`, paired with Verify Install enabled on the App.                                                                                           |
| `AUTO_PROVIDER_SENTRY_APP_REDIRECT_URI`                                        | Exactly `/api/v1/connections/sentry/installations/callback` resolved against the canonical deployment origin. Configure that same absolute callback URL on the App. |
| App permissions                                                                | Exactly `org:read`, `project:read`, and `event:read`. Missing or broader token scopes are rejected.                                                                 |

The server also needs its existing envelope-encryption key. App credentials and that key do not belong in tenant request bodies or sessions. Issue webhooks use the central [shared intake](/reference/managed-templates#shared-issue-intake-and-delivery) endpoint, not a tenant-specific webhook URL.

Missing or inconsistent configuration fails closed. A local Verify Install flag or redirect setting does not prove that the corresponding remote App setting is correct: initial authorization requires a fresh installation readback with status `pending`. Reusing an existing local connection uses project selection instead of replaying first-install authorization. Deploy migration `0300_sentry_connection_discovery` before using organization and region discovery; a source merge does not apply it.

## Set up in the web interface

In the initiating project's **Connections** page, use the ordinary Sentry row. Connection setup and project selection require an active organization administrator. The current auto project supplies the destination; changing accounts or projects does not transfer an attempt. There is no separate Sentry settings page.

<Steps>
  <Step title="Connect and approve">
    Choose **Connect** and approve the Public App in Sentry. Return with the same auto account. auto discovers and verifies the Sentry organization, region and visible projects instead of asking you to enter them. Supported regions are United States (`us`) and Germany (`de`).

    If an available installation already exists in this auto organization, Connect reuses it without another approval. An already connected project reports that state instead of starting another installation.
  </Step>

  <Step title="Choose Sentry projects when needed">
    One visible Sentry project and one destination complete automatically. Otherwise, **Choose Sentry projects** opens as a modal over Connections. Select up to 100 source projects and choose **Connect**; at least one is required in the chooser. With multiple existing connections, choose the Sentry organization first.

    These projects determine both investigation access and issue-event subscriptions for this auto project. Visible projects are not all selected automatically in a multi-project chooser. Closing or choosing **Cancel** dismisses the modal; it does not cancel the server-side attempt or uninstall the App.
  </Step>

  <Step title="Check the connection state">
    Completion closes the modal and refreshes the row to **Connected**. This means locally authorized access, not a tested webhook, an installed automation, or a successful agent run. Configure the consuming agent and verify live behavior separately.
  </Step>
</Steps>

### Disconnect and reconnect

Use the row's **Disconnect** action and its confirmation dialog to remove Sentry access from this auto project. It clears this project's allocations and disables its subscriptions across the row's connected grants, without revoking the shared organization grant, remotely uninstalling the App, or disconnecting other auto projects. The row returns to **Not connected**.

Connect again to reuse the existing installation and choose projects from its recorded provider visibility. Newly created Sentry projects are not automatically authorized. Unchanged selected subscriptions keep their identity; disconnecting and recreating a subscription cannot authorize old queued deliveries.

### Browser callback and pending work

HTML callbacks return HTTP 303 with `Cache-Control: no-store` and `Referrer-Policy: no-referrer` to the initiating project's Connections page. Pending work uses `?sentryAttempt={attemptId}`; completed, registered setup uses `?connectionOAuth=success&provider=sentry`. Neither return URL contains authorization codes, state or installation credentials. Caller-supplied redirect destinations are ignored. Malformed or unauthorized callbacks return to the fixed, query-free `/connections/sentry/error` page.

Old `/{organizationSlug}/{projectSlug}/connections/sentry` bookmarks redirect to Connections; a valid legacy `attempt` UUID becomes `sentryAttempt`. Reopening a callback that is no longer awaiting authorization does not exchange its code again.

Connect can resume the initiating administrator's unexpired `awaiting_selection`, `exchanging` or `completing` attempt. While an attempt is exchanging, completing or has an uncertain confirmation response, the open modal polls status every two seconds without overlapping reads or replaying mutations. Closing it stops those reads. Browser setup API requests time out after two minutes; timeout does not prove that a provider operation was undone. Failed or expired operations need operator reconciliation, not replay, reinstall or uninstall as a workaround.

### Existing MCP-only connections

Existing MCP-only grants keep their identities, project allocations and original OAuth path. They are not silently converted into Public App grants. If `sentry` is already taken, the default first-install name becomes `sentry-` plus the attempt UUID's first eight characters. Reference the resulting connection name, not an assumed name. An old MCP token does not authorize Public App installation; the new connection requires its own App approval. Copying another tenant's installation ID does not establish consent.

## CLI workflow

Run `auto connect sentry --allow <project>` to use the same connection flow. Without `--allow`, the active project is used; a project must be selected. The connection-start response can be `connected` with a provider and message, or `authorization_required` with the consent or project-selection URL. Sentry replacement requests return `not_implemented` guidance rather than replacing the shared installation.

During authorization waiting, the CLI recognizes an existing grant becoming connected to the project through `sentryConnection.connected`; a new grant ID is not required. A listed but unconnected Sentry grant does not count as success. For an installation-backed grant, `auto allow sentry <project> --connection <name>` allocates all projects in its recorded visibility. Use the chooser or project-selection API when you need a narrower selection. Use the web row's project-scoped Disconnect rather than treating organization-wide connection removal as equivalent.

## Authenticated setup sequence

The caller must be an authenticated, active organization administrator with `provider_grants:write` and `provider_grants:use` access in the initiating project. An agent or service-account principal cannot substitute for that user. Start checks that all intended destinations are active projects in the same organization; selection and publication recheck administrator authority for the selected recipients.

All paths below are relative to `/api/v1/connections/sentry/installations`. The `{attemptId}` path value is the setup attempt's UUID, not the provider installation UUID.

| Method and path       | Operation                                                                                                                        |
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `POST /`              | Start an attempt; return status plus `authorizationUrl` with HTTP 201.                                                           |
| `GET /callback`       | For JSON API calls, authenticate the initiating user and exchange the provider callback's `state`, `installationId`, and `code`. |
| `PUT /{attemptId}`    | Confirm explicitly selected recipients and publish the local grant and subscriptions.                                            |
| `GET /{attemptId}`    | Read authenticated, credential-free setup status.                                                                                |
| `DELETE /{attemptId}` | Cancel an unfinished attempt locally. This is not remote uninstall.                                                              |

### 1. Start an attempt

The `POST` body requires `organizationId` and `projectId`; the remaining fields are optional. Unknown fields are rejected:

| Field                    | Contract                                                                                                                                                                                                          |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `organizationId`         | Initiating organization ID, a nonempty string of at most 128 characters.                                                                                                                                          |
| `projectId`              | Initiating project ID, with the same string bounds.                                                                                                                                                               |
| `destinationProjectIds`  | Defaults to the initiating project. When supplied, between 1 and 20 intended project IDs with those same bounds. Duplicates are collapsed. This list limits later selection; it does not subscribe every project. |
| `connectionName`         | Defaults to `sentry`; 1–100 characters matching `^[a-z0-9][a-z0-9_-]*$`. A taken default name receives an attempt-specific suffix; a taken non-default name fails. Existing grants are not replaced.              |
| `sentryOrganizationSlug` | Optional expected organization slug, 1–255 characters matching `^[a-z0-9_-]+$`. Otherwise discovered from verified approval.                                                                                      |
| `region`                 | Optional `us` or `de` constraint. Otherwise discovered from verified organization metadata; only those fixed regional hosts are accepted.                                                                         |

Use the returned `authorizationUrl` for provider consent. The server generates a random state, stores its hash, and binds it to the initiating user, organization, project, intended destinations, and App. The attempt expires after 15 minutes; submitting a different user or tenant coordinate does not transfer its ownership.

### 2. Complete the provider callback

The callback accepts a 43-character base64url-shaped `state`, an `installationId` UUID, and a nonempty printable-ASCII `code` of at most 8,192 characters. It authenticates against the attempt's persisted scope and requires the same initiating user; state alone is not user authorization.

Before the single exchange, the server claims the authorization-code hash, not ownership of the supplied installation UUID. Only successful exchange and exact App, installation, organization, region, scope, and project-visibility readback establish the installation claim. An invalid code therefore does not reserve another tenant's installation UUID. Concurrent or replayed callbacks cannot repeat the exchange.

Successful proof normally advances the attempt to `awaiting_selection`, exposing verified project IDs and slugs before publication. If exactly one Sentry project and one destination are available, the callback proceeds through confirmation and publication automatically. At least one visible project is required. Enumeration is bounded to ten pages of at most 100 projects; incomplete, repeated, malformed, or oversized enumeration is rejected rather than used as partial permission. Provider pagination URLs are not followed.

### 3. Select recipients and publish

Send a `PUT` body containing only `recipients`, an array of 1–100 objects. Each object contains only `projectId` and `sentryProjectId`. The destination ID must be one of the intended projects; the Sentry project ID must be a positive decimal string from the verified visible projects. Duplicate destination/Sentry-project pairs are collapsed.

Provider visibility is read again before confirmation and after the installation is marked `installed` using its installation token. A short database transaction then rechecks the initiating user's authority, recipient membership, expiration, installation identity, and uninstall records. It atomically publishes one installation, one scoped grant, the selected project allocations/subscriptions, and central credential generation 1. Tokens are not copied into leaf grants; private attempt ciphertext is cleared on completion.

One initial consent can select multiple Sentry projects and multiple permitted destination projects through the API; the browser chooser uses only the current destination. The organization grant records verified project visibility, while each destination's allocation and subscriptions independently constrain investigation and intake. Completion emits connection-established lifecycle events. This is not independent authorization for another tenant. Existing outbound MCP connections are unchanged.

## Manage selected projects through the API

`GET /api/v1/connections/sentry/projects?organizationId={organizationId}&projectId={projectId}` returns the administrator's installation-backed connection options. Each option contains `id`, `name`, `organizationSlug`, `projects` (verified IDs and slugs), `selectedProjectIds` for this auto project, and `available`. Availability reflects a recorded `ready` or `refreshing` installation credential, not a successful live tool call.

`PUT /api/v1/connections/sentry/projects` accepts only `organizationId`, `projectId`, `providerGrantId` and `sentryProjectIds`. The first three are nonempty strings; the last is an array of at most 100 positive decimal ID strings from recorded visibility. Duplicate IDs are collapsed. Both endpoints require an authenticated organization administrator and `provider_grants:write` plus `provider_grants:use` in that project.

A nonempty selection updates this project's allocation and subscriptions. An empty array disconnects this project without remote uninstall. Unchanged subscriptions are retained; removed subscriptions are disabled with a new generation, and reconnect creates new subscription identities. The update records an audit entry and emits connection-established or connection-removed lifecycle events. Other projects' allocations remain unchanged.

## Read-only agent tools

Reference the Public App connection with `kind: connection`, `provider: sentry` and its actual `connection` name. The installation-backed surface contains four tools; an agent's exact-name [tool allowlist](/reference/tools#kind-connection--built-in-hosted-mcp-providers) can narrow it further.

| Tool                 | Scope and input                                                                                                                                                                                                                                                                                   |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `find_organizations` | Returns the connected organization and region; accepts no arguments.                                                                                                                                                                                                                              |
| `find_projects`      | Returns selected projects; an optional `organizationSlug` must match the connection.                                                                                                                                                                                                              |
| `search_issues`      | Searches a selected project. Specify `projectSlugOrId` when several are connected; with one project it is inferred. `query` defaults to `is:unresolved` (at most 4,000 characters), `limit` defaults to 10 (1–100), and `sort` defaults to `date` (`date`, `freq`, `new`, `user`, `recommended`). |
| `get_issue_details`  | Requires `issueId` or an HTTPS Sentry `issueUrl`. Numeric and short IDs resolve locally; issue URLs identify numeric issues. Optional organization and project arguments must match the connected scope and resolved issue.                                                                       |

The server checks live project authorization before issue metadata and latest-event reads, and again before releasing their buffered diagnostics. Issue details use regional REST reads, not hosted detail enrichment. The event must match the verified stable issue and project; a missing latest event returns `event: null`. Output includes projected issue metadata and event-owned exception, stacktrace, thread, message, request and breadcrumb entries. Distributed trace, span, conversation and release enrichment is omitted. This is not a general secret-redaction guarantee.

Only issue search uses the hosted MCP path, fixed to the selected organization and project. Arbitrary catalog execution, mutation tools and other upstream tools are not exposed. Rejected allowlist calls stop before credential lookup or provider I/O. Discovery metadata alone does not establish live access.

Installation-backed requests resolve a server-held shared credential, refreshing near expiry through the installation's single-owner refresh path. Tokens are not copied into the sandbox or leaf grants. Concurrent callers do not independently rotate that token, and uncertain refresh outcomes remain unavailable rather than authorizing another rotation. Existing MCP-only grants continue through their original OAuth resolver.

## Interpret status without implying activation

Status includes the attempt ID, expiry, initiating scope, intended destinations, Sentry organization and region, project choices, and a nullable `providerGrantId`. Organization and region can be `null` before discovery. Project choices are returned only for an unexpired `awaiting_selection` attempt.

| Field                    | Values and meaning                                                                                                                                                                                                                                                                                                                                      |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                 | `awaiting_authorization`, `exchanging`, `awaiting_selection`, `completing`, `completed`, `failed`, `canceled`, or `expired`. Completion records local publication; it is not an automation result.                                                                                                                                                      |
| `inbound`                | `not_configured`, `registered`, or `unavailable`. `registered` requires currently authorized subscriptions for the initiating project and a matching credential recorded as `ready` or `refreshing`. Configuration mismatch or revoked access can make it unavailable after completion; credential use still requires live authorization and freshness. |
| `investigationAccess`    | `available` when inbound access is `registered`; otherwise `not_configured` or `unavailable`. It no longer reports `separate_mcp_connection`. This is local availability, not live execution proof.                                                                                                                                                     |
| `delivery`, `automation` | Both remain `not_verified`, including after successful setup.                                                                                                                                                                                                                                                                                           |

Setup JSON responses use `Cache-Control: no-store` and `Referrer-Policy: no-referrer`; authentication and deployment-policy failures use their existing response handlers. Status does not return App secrets, authorization codes, state hashes, or token ciphertext. Do not infer live delivery from `completed` or `registered`, or use the unsupported Sentry trigger test-fire path as activation proof.

## Cancellation and uncertain outcomes

Cancel an unfinished attempt with the installation API's `DELETE`. Cancellation clears its pending credential locally and never remotely uninstalls the shared App. Dismissing the browser modal is not this API operation. A completed attempt cannot be canceled through this route; use the row's project-scoped Disconnect or the project-selection API for that project. Organization-grant revocation remains a separate, broader action described in [shared intake](/reference/managed-templates#shared-issue-intake-and-delivery).

Code-hash claims and provider-proven installation claims are not released by failure, cancellation, or elapsed time. Unknown exchange or confirmation outcomes are not automatically retried or recovered. If a process stops in `exchanging` or `completing`, expiry does not authorize another exchange, token rotation, or subscriber.

Provider HTTP happens outside database locks. A cancellation, permission change, uninstall, lost confirmation response, or failed local publication can leave a remotely confirmed installation without a local grant. Report that uncertain outcome for separately authorized operator reconciliation; local rollback does not undo remote effects, and this API does not compensate with remote uninstall.

Malformed requests or invalid selections return HTTP 400; setup authorization failures return 403, unknown attempts 404, invalid state or unavailable installation claims 409, and unavailable operator setup 503. Read the current attempt status and the specific error rather than retrying a possibly consumed callback or widening its recipient scope.
