# Story 2.6.5: Implement DELETE /credentials/{id}

<!-- Powered by BMAD™ Core -->

## Status
**Draft**

## Story

**As a** workflow automation user,
**I want** to delete unused credentials from my n8n instance through the MCP server,
**so that** I can maintain security hygiene by removing obsolete authentication data and prevent credential sprawl.

## Acceptance Criteria

1. New `delete_credential` MCP tool registered and functional
2. Tool deletes credential by ID
3. Safety check: Warn/block deletion if credential is in use by workflows
4. Multi-instance routing works correctly
5. Error handling for non-existent credentials (404)
6. Error handling for credentials in use (409 or warning)
7. Deletion is permanent (not soft delete)
8. Comprehensive testing including in-use scenarios
9. Documentation with safety warnings
10. Cascade behavior documented and tested

## Tasks / Subtasks

### Task 1: Implement deleteCredential (AC: 1, 2, 4)
- [ ] Add `deleteCredential` method to N8NApiWrapper
- [ ] Use callWithInstance pattern
- [ ] Use DELETE method
- [ ] Support credentialId parameter
- [ ] Add error handling

### Task 2: Register delete_credential Tool (AC: 1)
- [ ] Add tool definition to src/index.ts
- [ ] Define input schema with credentialId
- [ ] Include instance parameter
- [ ] Add safety warnings in description
- [ ] Implement request handler

### Task 3: Safety Logic (AC: 3, 6)
- [ ] Research n8n deletion behavior
- [ ] Document in-use credential handling
- [ ] Test deletion of active credentials
- [ ] Verify error responses
- [ ] Add safety documentation

### Task 4: Create Tests (AC: 8)
- [ ] **Test 4.1**: Delete unused credential
  - [ ] Create credential
  - [ ] Delete immediately
  - [ ] Verify removed from list
  - [ ] Confirm 404 on retrieval
- [ ] **Test 4.2**: Delete credential in use (AC: 3, 6)
  - [ ] Create credential
  - [ ] Assign to workflow
  - [ ] Attempt deletion
  - [ ] Verify behavior (blocked or cascaded)
  - [ ] Document actual behavior
- [ ] **Test 4.3**: Deletion permanence (AC: 7)
  - [ ] Delete credential
  - [ ] Verify truly removed
  - [ ] Check no soft delete
  - [ ] Confirm unrecoverable
- [ ] **Test 4.4**: Workflow impact
  - [ ] Delete credential used by workflow
  - [ ] Check workflow behavior
  - [ ] Verify workflow still exists
  - [ ] Document credential removal impact
- [ ] **Test 4.5**: Multi-instance deletion
  - [ ] Delete from default instance
  - [ ] Delete from specific instance
  - [ ] Test cross-instance (404)
- [ ] **Test 4.6**: Error scenarios
  - [ ] Delete non-existent credential (404)
  - [ ] Delete already deleted credential
  - [ ] Invalid credential ID
- [ ] **Test 4.7**: Cascade behavior (AC: 10)
  - [ ] Document what happens to workflows
  - [ ] Test node credential references
  - [ ] Verify cascade semantics

### Task 5: Documentation (AC: 9, 10)
- [ ] Add deletion examples
- [ ] Document safety considerations
- [ ] Explain cascade behavior
- [ ] Add warnings about in-use credentials
- [ ] Update README and CHANGELOG

### Task 6: Integration
- [ ] Add to test suite
- [ ] Safety check tests
- [ ] Cleanup utilities

## Dev Notes

### Deletion Safety

**Question:** What happens when deleting credential in use?

**Possible Behaviors:**
1. **Blocked (409 Conflict):** "Credential is in use by X workflows"
2. **Allowed with Warning:** Credential deleted, workflows keep reference
3. **Cascade:** Credential deleted, removed from all workflows

**Testing Required:** Determine actual n8n behavior

### MCP Tool Schema
```typescript
{
  name: 'delete_credential',
  description: 'Delete a credential (WARNING: Check if in use first)',
  inputSchema: {
    type: 'object',
    properties: {
      credentialId: {
        type: 'string',
        description: 'ID of credential to delete'
      },
      instance: {
        type: 'string',
        description: 'Instance identifier (optional)'
      }
    },
    required: ['credentialId']
  }
}
```

### Safety Check Strategy

**Option 1:** Pre-delete check
```javascript
async function deleteCredential(id) {
  // Check usage first
  const credential = await getCredential(id);
  if (credential.nodesAccess.length > 0) {
    throw new Error('Credential in use by workflows');
  }
  // Proceed with deletion
  await api.delete(`/credentials/${id}`);
}
```

**Option 2:** Let n8n enforce
```javascript
async function deleteCredential(id) {
  // Let n8n API handle safety checks
  // Return appropriate error if blocked
  await api.delete(`/credentials/${id}`);
}
```

**Decision:** Test n8n behavior first, then implement appropriate strategy

## Testing

### Test Pattern
```javascript
// Test deletion of unused credential
const cred = await createCredential({...});
await deleteCredential(cred.id);
const list = await listCredentials();
assert(!list.data.find(c => c.id === cred.id));

// Test deletion of in-use credential
const workflow = await createWorkflow({
  // ... uses credential
});
try {
  await deleteCredential(cred.id);
  // Document if allowed or blocked
} catch (error) {
  // Document error response
}
```

## Change Log

| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-26 | 1.0 | Story created for DELETE /credentials/{id} | Sarah (PO) |
