# Story 2.6.6: Implement GET /credentials/schema/{typeName}
<!-- Powered by BMAD™ Core -->
## Status
**Draft**
## Story
**As a** workflow automation developer,
**I want** to retrieve JSON schema for specific credential types through the MCP server,
**so that** I can understand required fields, validation rules, and data structure before creating credentials programmatically.
## Acceptance Criteria
1. New `get_credential_schema` MCP tool registered and functional
2. Tool retrieves JSON schema for any credential type by name
3. Schema includes field definitions, types, required fields, and validation rules
4. Response helps developers understand credential structure before creation
5. Multi-instance routing works correctly
6. Error handling for non-existent credential types (404)
7. Error handling for unauthorized access (401)
8. Comprehensive testing with various credential types
9. Documentation with schema interpretation guide
10. Integration with create_credential workflow
## Tasks / Subtasks
### Task 1: Study Credential Schema Endpoint (AC: 2, 3, 4)
- [ ] Read docs/n8n-api-docs/30-CREDENTIALS-API.md (lines 866-940)
- [ ] Understand schema structure and fields
- [ ] Document common credential type names
- [ ] Identify schema properties format
- [ ] Note validation rules encoding
### Task 2: Implement getCredentialSchema (AC: 1, 2, 5)
- [ ] Add `getCredentialSchema` method to N8NApiWrapper
- [ ] Use callWithInstance pattern
- [ ] Support typeName parameter (e.g., 'googleDriveOAuth2Api')
- [ ] Add error handling for invalid types
- [ ] Follow existing patterns
### Task 3: Register get_credential_schema Tool (AC: 1)
- [ ] Add tool definition to src/index.ts
- [ ] Define input schema with typeName parameter
- [ ] Include instance parameter
- [ ] Add comprehensive description with examples
- [ ] Implement request handler
### Task 4: Schema Response Processing (AC: 3, 4)
- [ ] Parse schema response structure
- [ ] Extract field definitions
- [ ] Identify required vs optional fields
- [ ] Document validation rules
- [ ] Format user-friendly output
### Task 5: Create Tests (AC: 8)
- [ ] **Test 5.1**: Get schema for common credential types
- [ ] HTTP Basic Auth schema
- [ ] HTTP Header Auth schema
- [ ] OAuth2 schemas (Google, GitHub, etc.)
- [ ] Verify schema structure
- [ ] **Test 5.2**: Validate schema fields
- [ ] Check properties array/object
- [ ] Verify field types (string, password, etc.)
- [ ] Validate required fields list
- [ ] Check validation rules
- [ ] **Test 5.3**: Schema-based credential creation
- [ ] Get schema for credential type
- [ ] Use schema to create valid credential
- [ ] Verify creation succeeds
- [ ] Test field validation
- [ ] **Test 5.4**: Multi-instance routing
- [ ] Get schema from default instance
- [ ] Get schema from specific instance
- [ ] Verify instance isolation
- [ ] **Test 5.5**: Error scenarios
- [ ] Non-existent credential type (404)
- [ ] Invalid type name format
- [ ] Invalid API key (401)
- [ ] Verify error responses
- [ ] **Test 5.6**: Schema interpretation
- [ ] Parse schema fields programmatically
- [ ] Generate credential creation payload
- [ ] Validate against schema rules
### Task 6: Documentation (AC: 9, 10)
- [ ] Add schema retrieval examples
- [ ] Document schema structure interpretation
- [ ] Create field type reference guide
- [ ] Show integration with create_credential
- [ ] Add common credential type examples
- [ ] Update README and CHANGELOG
### Task 7: Integration (AC: 10)
- [ ] Add to test suite
- [ ] Integration with Story 2.6.3 (create_credential)
- [ ] Create schema-driven credential creation example
- [ ] Cleanup utilities
## Dev Notes
### Credential Schema Structure
**Typical Schema Response:**
```typescript
{
name: string; // Credential type name
displayName: string; // Human-readable name
properties: Array<{ // Field definitions
displayName: string; // Field label
name: string; // Field identifier
type: string; // Field type (string, password, etc.)
default?: any; // Default value
required?: boolean; // Is required
description?: string; // Field description
placeholder?: string; // Placeholder text
}>;
authenticate?: object; // Authentication config
test?: object; // Test configuration
}
```
**Example for HTTP Basic Auth:**
```json
{
"name": "httpBasicAuth",
"displayName": "HTTP Basic Auth",
"properties": [
{
"displayName": "User",
"name": "user",
"type": "string",
"default": "",
"required": true
},
{
"displayName": "Password",
"name": "password",
"type": "string",
"typeOptions": {
"password": true
},
"default": "",
"required": true
}
]
}
```
### MCP Tool Schema
```typescript
{
name: 'get_credential_schema',
description: 'Get JSON schema for a credential type to understand required fields and structure',
inputSchema: {
type: 'object',
properties: {
typeName: {
type: 'string',
description: 'Credential type name (e.g., "httpBasicAuth", "googleOAuth2Api")',
examples: [
'httpBasicAuth',
'httpHeaderAuth',
'googleDriveOAuth2Api',
'slackApi',
'githubApi'
]
},
instance: {
type: 'string',
description: 'Instance identifier (optional)'
}
},
required: ['typeName']
}
}
```
### Common Credential Types
**Authentication Types:**
- `httpBasicAuth` - HTTP Basic Authentication
- `httpHeaderAuth` - HTTP Header Authentication
- `httpDigestAuth` - HTTP Digest Authentication
- `oAuth1Api` - OAuth 1.0
- `oAuth2Api` - OAuth 2.0 (generic)
**Service-Specific:**
- `googleOAuth2Api` - Google OAuth2
- `googleDriveOAuth2Api` - Google Drive
- `slackApi` - Slack
- `githubApi` - GitHub
- `airtableApi` - Airtable
- `notionApi` - Notion
- And 100+ more in n8n
### Integration with create_credential
**Workflow Pattern:**
```javascript
// 1. Get schema for credential type
const schema = await getCredentialSchema('httpBasicAuth');
// 2. Extract required fields
const requiredFields = schema.properties
.filter(p => p.required)
.map(p => p.name);
console.log('Required fields:', requiredFields);
// Output: ['user', 'password']
// 3. Create credential with correct structure
const credential = await createCredential({
name: 'My Basic Auth',
type: 'httpBasicAuth',
data: {
user: 'username',
password: 'password123'
}
});
```
### Field Type Mapping
**Common Field Types:**
- `string` - Text input
- `password` - Password input (masked)
- `number` - Numeric input
- `boolean` - Checkbox
- `options` - Dropdown selection
- `collection` - Nested object
- `fixedCollection` - Array of objects
### Use Cases
**Use Case 1: Discover required fields**
```javascript
const schema = await getCredentialSchema('googleOAuth2Api');
const required = schema.properties.filter(p => p.required);
console.log('Must provide:', required.map(f => f.displayName));
```
**Use Case 2: Validate before creation**
```javascript
const schema = await getCredentialSchema('slackApi');
const credentialData = { apiKey: 'xoxb-...' };
// Validate all required fields present
const missing = schema.properties
.filter(p => p.required && !credentialData[p.name])
.map(p => p.displayName);
if (missing.length > 0) {
throw new Error(`Missing fields: ${missing.join(', ')}`);
}
await createCredential({ type: 'slackApi', data: credentialData });
```
**Use Case 3: Dynamic form generation**
```javascript
// Generate UI form from schema
const schema = await getCredentialSchema('airtableApi');
schema.properties.forEach(field => {
renderFormField({
label: field.displayName,
type: field.type,
required: field.required,
placeholder: field.placeholder,
description: field.description
});
});
```
## Testing
### Test Pattern
```javascript
// Test schema retrieval
const schema = await getCredentialSchema('httpBasicAuth');
// Validate schema structure
assert(schema.name === 'httpBasicAuth');
assert(schema.displayName !== undefined);
assert(Array.isArray(schema.properties));
assert(schema.properties.length > 0);
// Validate field structure
const userField = schema.properties.find(p => p.name === 'user');
assert(userField !== undefined);
assert(userField.type === 'string');
assert(userField.required === true);
```
### Schema-Driven Credential Creation Test
```javascript
// Get schema
const schema = await getCredentialSchema('httpBasicAuth');
// Build credential data from schema
const credentialData = {};
schema.properties.forEach(field => {
if (field.required) {
credentialData[field.name] = field.default || 'test-value';
}
});
// Create credential
const credential = await createCredential({
name: 'Schema-Generated Credential',
type: schema.name,
data: credentialData
});
// Verify creation
assert(credential.id !== undefined);
assert(credential.type === schema.name);
```
## Change Log
| Date | Version | Description | Author |
|------|---------|-------------|--------|
| 2025-12-26 | 1.0 | Story created for GET /credentials/schema/{typeName} | Sarah (PO) |
| 2025-12-26 | 1.1 | Replaced incorrect test_credential story | Sarah (PO) |
## Dev Agent Record
*This section will be populated by the development agent during implementation.*
### Agent Model Used
*To be filled by dev agent*
### Debug Log References
*To be filled by dev agent*
### Completion Notes List
*To be filled by dev agent*
### File List
*To be filled by dev agent*
## QA Results
*This section will be populated by QA agent after implementation and validation.*