Skip to content
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ canonical workflow and required docs live in [../AGENTS.md](../AGENTS.md)

- [specs/README.md](specs/README.md) - Specs index
- [specs/embedded-agent-openai-routing.md](specs/embedded-agent-openai-routing.md) - Embedded agent OpenAI routing spec
- [specs/project-management.md](specs/project-management.md) - Project management tools spec
- [specs/remembered-oauth-skills.md](specs/remembered-oauth-skills.md) - Remembered OAuth skill defaults spec
- [specs/search-events.md](specs/search-events.md) - Search Events spec
- [specs/sentry-bearer-cloudflare-auth.md](specs/sentry-bearer-cloudflare-auth.md) - Direct Sentry token auth for the Cloudflare transport
Expand Down
1 change: 1 addition & 0 deletions docs/specs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ server. Each spec should live in a single Markdown file under `docs/specs/`.

- [AI Conversations](ai-conversations.md)
- [Embedded Agent OpenAI Routing](embedded-agent-openai-routing.md)
- [Project Management Tools](project-management.md)
- [Remembered OAuth Skill Defaults](remembered-oauth-skills.md)
- [Search Events](search-events.md)
- [Sentry-Bearer Cloudflare Auth](sentry-bearer-cloudflare-auth.md)
Expand Down
151 changes: 151 additions & 0 deletions docs/specs/project-management.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Project Management Tools

Project-management tools create and update Sentry projects, teams, project DSNs,
and project team access through the searchable MCP catalog.

## Overview

Project management is intentionally powerful and infrequent. These tools are
available only when the `project-management` skill is granted, and they remain
catalog-only: discover them with `search_sentry_tools` and execute them with
`execute_sentry_tool`.

Implementation references:
- Tool catalog: `packages/mcp-core/src/tools/catalog/`
- Availability rules: `packages/mcp-core/src/tools/catalog-runtime/availability.ts`
- API client: `packages/mcp-core/src/api-client/client.ts`

## Tool Surface

Project-management tools are not direct top-level MCP tools. They must not be
added to `TOP_LEVEL_TOOL_NAMES` in `packages/mcp-core/src/tools/surfaces.ts`.

Core project tools:

```typescript
create_project({
organizationSlug: "my-org",
teamSlug: "my-team",
name: "My Project",
slug: "my-project", // optional
platform: "javascript", // optional
repository: "acme/app", // optional, must already be connected
})

update_project({
organizationSlug: "my-org",
projectSlug: "my-project",
name: "New Name", // at least one metadata field is required
slug: "new-slug",
platform: "python",
})

add_team_to_project({
organizationSlug: "my-org",
projectSlug: "my-project",
teamSlug: "backend",
})

remove_team_from_project({
organizationSlug: "my-org",
projectSlug: "my-project",
teamSlug: "backend",
})
```

## Creation Contract

`create_project` accepts core setup fields:
- `organizationSlug`
- `teamSlug`
- `name`
- optional `slug`
- optional `platform`
- optional `repository`

It does not expose ownership rules, alert rule setup, `defaultRules`, or broader
project settings.

Successful responses must include:
- Project ID
- Project slug
- Project name
- `SENTRY_DSN`

The DSN contract is strict because SDK setup normally follows project creation.
After creating the project, the tool lists project client keys and returns an
existing usable DSN, preferring an active `Default` key. It creates a `Default`
client key only when no usable key exists.

When `repository` is provided, `create_project` resolves the repository before
creating the project. Unknown or ambiguous repositories fail before the project
is created. After creation, the tool links the repository by creating a root
code mapping (`/` to `/`) through Sentry's organization code-mappings endpoint.
If linking fails after project creation, the response still includes the project
slug and DSN and notes that the repository must be linked manually.

## Metadata Updates

`update_project` is metadata-only. It updates only:
- `name`
- `slug`
- `platform`

At least one metadata field is required. Team access changes must use
`add_team_to_project` or `remove_team_from_project`.

Project-scoped sessions reject slug updates. A successful slug rename would
leave the active MCP session constrained to the old project slug until the
client reconnects.

## Team Access

`add_team_to_project` grants an existing team access to an existing project. It
lists current project teams first. If the team already has access, it returns a
successful no-op response with the current team list.

`remove_team_from_project` revokes team access and is marked destructive. It
lists current project teams before deleting and rejects:
- Teams that are not currently assigned to the project
- Removing the last assigned team

This MCP guard is stricter than the upstream delete endpoint so agents do not
accidentally leave a project without a team.

## Constraints

Organization and project constraints are enforced by catalog availability and
parameter injection:
- Organization-scoped sessions filter `organizationSlug` from schemas and inject
the constrained organization.
- Project-scoped sessions filter `projectSlug` from update/team-access schemas
and inject the constrained project.
- Project-scoped sessions hide `create_project` because sibling project creation
is outside the active project constraint.

Conflicting explicit `organizationSlug` or `projectSlug` arguments from a caller
are filtered before handler execution.

## Migration

Previous behavior mixed unrelated operations into project tools:
- `update_project` could grant team access through `teamSlug`.

Use these replacements:
- Repository linking: use `create_project(..., repository: "owner/repo")` during
creation.
- Team grant: `add_team_to_project`
- Team revoke: `remove_team_from_project`

## Testing

Required coverage lives with the tools and catalog runtime:
- `packages/mcp-core/src/tools/catalog/create-project.test.ts`
- `packages/mcp-core/src/tools/catalog/update-project.test.ts`
- `packages/mcp-core/src/tools/catalog/add-team-to-project.test.ts`
- `packages/mcp-core/src/tools/catalog/remove-team-from-project.test.ts`
- `packages/mcp-core/src/tools/catalog-runtime/availability.test.ts`
- `packages/mcp-core/src/tools/tools.test.ts`

Run `pnpm run --filter @sentry/mcp-core generate-definitions` after changing
tool descriptions, schemas, or catalog registration.
11 changes: 6 additions & 5 deletions docs/testing/remote.md
Original file line number Diff line number Diff line change
Expand Up @@ -412,10 +412,10 @@ pnpm -w run cli "list organizations"
**Verify tools reflect the current session grant:**
```bash
# With read-only grants: no write tools
pnpm -w run cli "list tools" | grep "create_"
pnpm -w run cli "search Sentry tools for create project"

# With all grants: includes write tools
# Should see: create_project, create_team, update_issue, etc.
# With all grants: catalog search includes write-capable tools
# Should find: create_project, create_team, update_issue, etc.
```

### 3. Test Multi-Organization Access
Expand Down Expand Up @@ -547,8 +547,9 @@ pnpm -w run cli "who am I?"
# Check tool list
pnpm -w run cli "list tools" | jq '.tools[] | .name'

# Verify the session grant includes the capability for the tool you need
# Example: create_project is only available with project-management capabilities
# Verify the session grant includes the capability for the tool you need.
# Project-management tools are catalog-only; find them with search_sentry_tools.
# Example: create_project requires project-management and is hidden in project-scoped sessions.

# Rebuild and restart
pnpm -w run build && pnpm dev
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-07-03
100 changes: 100 additions & 0 deletions openspec/changes/refine-project-management-tools/design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
## Context

The MCP catalog already includes `create_project`, `update_project`, `create_team`, and DSN management tools under the `project-management` skill. The current project tools need sharper boundaries:

- `create_project` creates a project, creates an additional DSN, and optionally links a repository.
- `update_project` changes project metadata and can also grant a team access to the project.
- Project-scoped MCP sessions can still discover `create_project`, even though creating sibling projects is outside the active project constraint.

Sentry's upstream project creation endpoint creates the project under a team and emits normal project creation side effects, including default key creation through Sentry's project post-save hook. Agents still need the DSN in the tool response because creating a Sentry project is usually followed immediately by SDK setup.

Endpoint validation:
- `~/src/sentry/src/sentry/core/endpoints/project_teams.py` lists project teams through `ProjectTeamsEndpoint.get`, backed by `OffsetPaginator` and cursor `Link` headers, so MCP must page through cursors before applying team-access safety checks.
- `~/src/sentry/src/sentry/integrations/api/endpoints/organization_code_mappings_bulk.py` persists repository/project associations through `OrganizationCodeMappingsBulkEndpoint.post` at `/organizations/{org}/code-mappings/bulk/`; it resolves the project by slug, resolves the repository by name/provider, infers the default branch when possible, and creates or updates `RepositoryProjectPathConfig` rows.

## Goals / Non-Goals

**Goals:**

- Make project creation a safe, focused setup workflow that always returns a usable `SENTRY_DSN`.
- Keep project metadata updates separate from project team access changes.
- Add explicit tools for granting and revoking project team access.
- Preserve catalog-only exposure behind the `project-management` skill.
- Document project-management behavior in a durable repo spec.
- Add focused test coverage for success paths, guardrails, constraints, and generated definitions.

**Non-Goals:**

- Repository linking as a metadata update or team access concern.
- Project deletion, transfer, ownership rule management, alert rule management, or broader project settings.
- Direct top-level MCP exposure for project-management tools.
- Changing Sentry's upstream API semantics.

## Decisions

### Keep `create_project` focused on project setup

`create_project` will call Sentry's team project creation endpoint with core fields: organization, team, name, optional slug, and optional platform. It will not expose the upstream `default_rules` flag in the first iteration; Sentry's default behavior remains active.

Repository linking stays first-class in `create_project` because project setup often includes connecting the new project to its source repository. When requested, the tool resolves the repository before creating the project so missing or ambiguous repositories fail without creating a project. Linking creates a root code mapping through Sentry's organization code-mappings endpoint after project creation because it requires the created project slug; link failures are reported in the response with the DSN so the user can retry manually.

Alternative considered: move repository linking to a separate tool only. This was rejected because repository linking is part of the primary project setup workflow and is useful to keep alongside creation while team access remains separate.

### Guarantee a DSN without creating duplicates in the normal path

After project creation, the tool will call `listClientKeys` for the created project. If a key exists, it will return an existing DSN, preferring a key named `Default` when present. If no key exists, it will create a `Default` key and return that DSN.

Alternative considered: always call `createClientKey` after project creation. This guarantees a DSN, but it creates duplicate keys in normal Sentry deployments where the default key already exists.

### Make `update_project` metadata-only

`update_project` will only update `name`, `slug`, and `platform`. Team access changes will move to separate tools. This keeps the tool's destructive annotation and user-facing description aligned with what it actually mutates.

Alternative considered: keep team assignment as an optional field. This was rejected because changing teams changes access and rule ownership behavior, which is materially different from correcting a project name or platform.

### Reject project-scoped slug changes

When a session is constrained to a project, `update_project` will reject `slug` updates. A successful rename would leave the active session constrained to the old slug until reconnect, which makes follow-up tool calls ambiguous or likely to fail.

Alternative considered: allow the update and report the new slug. This was rejected for the first iteration because the active MCP constraint is session state, not a mutable output from the tool call.

### Add explicit team access tools

`add_team_to_project` and `remove_team_from_project` will be separate catalog tools. Adding a team widens access; removing a team revokes access and can clear alert/rule team ownership upstream. The separate names make those effects visible to agents and users.

Alternative considered: one `update_project_team_access` tool with an action enum. Separate tools are clearer for tool search, safety annotations, examples, and audit-focused responses.

### Preflight team removal

`remove_team_from_project` will fetch current project teams before deleting. It will reject removal when the target team is not assigned and when it is the only assigned team.

Alternative considered: rely entirely on the backend DELETE. This was rejected because the backend path deletes the project-team row and clears ownership references without a last-team guard at that layer.

### Keep tools catalog-only

The project-management tools will remain discoverable through `search_sentry_tools` and executable through `execute_sentry_tool`, filtered by skills, scopes, and constraints. They will not be added to `TOP_LEVEL_TOOL_NAMES`.

Alternative considered: expose `create_project` directly. This was rejected because project management is powerful, less frequent than inspection/search, and the direct surface has a strict tool budget.

## Risks / Trade-offs

- Duplicate DSN fallback could still create a key if key listing races with Sentry's default key hook. Mitigation: list first, create only when the list is empty, and keep the fallback explicit in tests.
- Repository linking can fail after project creation because code mapping creation needs the created project. Mitigation: preflight repository resolution before project creation and report post-create link failures without hiding the project slug or DSN.
- Last-team removal guard may reject a backend operation that Sentry technically allows. Mitigation: prefer safe MCP behavior; users can use Sentry directly for exceptional cases until a deliberate override is designed.
- Slug updates can make project-scoped sessions confusing after the mutation. Mitigation: reject and test slug changes in project-scoped sessions.
- Adding team access tools increases catalog size. Mitigation: keep them catalog-only and behind the existing `project-management` skill.

## Migration Plan

1. Update API client support for project creation slug, repository linking, and project team access reads/deletes.
2. Tighten `create_project` and `update_project` schemas and descriptions.
3. Add `add_team_to_project` and `remove_team_from_project`.
4. Add tests covering old behavior removal and new contracts.
5. Add `docs/specs/project-management.md` and link it from `docs/specs/README.md`.
6. Regenerate tool definitions.

Rollback is straightforward: revert the catalog and API client changes. Existing users of `update_project(..., teamSlug=...)` will need to switch to `add_team_to_project`; this should be called out in the spec and release notes if applicable.

## Open Questions

None.
43 changes: 43 additions & 0 deletions openspec/changes/refine-project-management-tools/proposal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
## Why

Project management is already partially exposed through catalog tools, but the current surface mixes unrelated side effects into broad operations. Creating a project must reliably return a usable DSN, while project metadata updates and team access changes need separate contracts so agents do not accidentally change access when renaming or re-platforming a project.

## What Changes

- Tighten `create_project` to focus on project creation and immediate SDK setup:
- Accept organization, team, project name, optional project slug, and optional platform.
- Optionally link an existing organization repository as a first-class setup step.
- Return the created project identity and a usable `SENTRY_DSN`.
- Prefer the default DSN created by Sentry; create a `Default` DSN only as a fallback when no key exists.
- Tighten `update_project` to metadata-only updates:
- Allow project name, slug, and platform changes.
- Reject slug changes from project-scoped sessions so the active project constraint does not become stale.
- Remove team assignment from this tool.
- Add explicit team access tools:
- `add_team_to_project` grants an additional team access to a project.
- `remove_team_from_project` revokes a team from a project, with preflight guardrails.
- Keep all project-management operations catalog-only behind the `project-management` skill.
- Add durable project-management documentation under `docs/specs/project-management.md` and link it from the specs index.

## Capabilities

### New Capabilities

- `project-management`: Defines safe project, DSN, and project team access management through MCP catalog tools.

### Modified Capabilities

None.

## Impact

- `packages/mcp-core/src/tools/catalog/create-project.ts`
- `packages/mcp-core/src/tools/catalog/update-project.ts`
- New catalog tools for adding and removing project teams
- `packages/mcp-core/src/tools/catalog/index.ts`
- `packages/mcp-core/src/api-client/client.ts`
- `packages/mcp-core/src/api-client/schema.ts`
- Catalog tool tests and mocks for project creation, metadata updates, team access changes, and constraints
- Generated definitions from `pnpm run --filter @sentry/mcp-core generate-definitions`
- `docs/specs/project-management.md`
- `docs/specs/README.md`
Loading
Loading