Skip to content

5.12-c Delete and destructive tools (phase 2) #7710

Description

@andypalmi

Parent: #7681 (5.12 Team data and packages)
Tool file: new forge/ee/lib/mcp/tools/teamData.js

destructiveHint: true. Kept separate from ordinary writes so MCP clients gate them behind confirmation by default. One tool per delete endpoint.

Tool Endpoint Scope Annotation
platform_delete_database_table DELETE /teams/:teamId/databases/:databaseId/tables/:tableName team:database:create destructive
platform_delete_team_database DELETE /teams/:teamId/databases/:databaseId team:database:delete destructive
platform_delete_library_entry DELETE /storage/library/:libraryId/* library:entry:delete destructive
platform_delete_git_token DELETE /teams/:teamId/git/tokens/:tokenId team:git:tokens:delete destructive

Design notes:

  • DELETE .../tables/:tableName reuses the team:database:create scope (scope reuse); annotate/allow-list accordingly.
  • Shared-library DELETE skips the permission check for non-user tokens; for user PATs it requires library:entry:delete.

Scopes to allow-list + access-tag (#7445):
team:database:create (write), team:database:delete (write), library:entry:delete (write), team:git:tokens:delete (write).

Tool definitions (description + zod inputSchema):

platform_delete_database_table: {
  description: 'Deletes a table from a database.',
  inputSchema: z.object({
    teamId: z.string().describe('team hashid'),
    databaseId: z.string().describe('database hashid'),
    tableName: z.string().describe('Name of the database table')
  })
},
platform_delete_team_database: {
  description: 'Deletes a team database.',
  inputSchema: z.object({
    teamId: z.string().describe('team hashid'),
    databaseId: z.string().describe('database hashid')
  })
},
platform_delete_library_entry: {
  description: 'Deletes an entry from the team shared library.',
  inputSchema: z.object({
    libraryId: z.string().describe('shared-library hashid (the team hashid)'),
    path: z.string().describe('Library entry path'),
    type: z.string().optional().describe('entry type filter query param')
  })
},
platform_delete_git_token: {
  description: 'Deletes a git token.',
  inputSchema: z.object({
    teamId: z.string().describe('team hashid'),
    tokenId: z.string().describe('git token hashid')
  })
}

Tests:

  • Every tool carries destructiveHint: true.
  • Read-only PAT rejected.
  • Feature-disabled team returns the descriptive gate error.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyA user-oriented description of a feature

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions