docs: Create OpenSpec proposal for MCP server organization member support
Add comprehensive proposal to update the TypeScript MCP server to support organization members. The GraphQL backend was updated in the feat/organization-member-support branch to add memberType and companyName fields, but the MCP server tools still assume all members are individuals. Proposal includes: - Detailed design for updating tool definitions and GraphQL queries - Member formatting logic to distinguish individuals from organizations - Comprehensive spec deltas with 22 scenarios covering all use cases - 11 implementation tasks All changes are contained in a single file: src/mcp_server.ts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
# Design: Update MCP Server for Organization Members
|
||||
|
||||
## MCP Tool Definition Changes
|
||||
|
||||
### Tool: create_member
|
||||
**Current State:**
|
||||
- Description: "Create a new member. Only firstName is required..."
|
||||
- Required field: `firstName`
|
||||
- Missing fields: `memberType`, `companyName`
|
||||
|
||||
**Changes Needed:**
|
||||
- Update description to explain conditional requirements:
|
||||
- INDIVIDUAL members require `firstName`
|
||||
- ORGANIZATION members require `companyName`
|
||||
- `memberType` defaults to INDIVIDUAL if not specified
|
||||
- Add `memberType` property (enum: INDIVIDUAL, ORGANIZATION)
|
||||
- Add `companyName` property (string, optional)
|
||||
- Make `firstName` optional in schema (validation happens server-side)
|
||||
- Remove `firstName` from required array
|
||||
|
||||
### Tool: update_member
|
||||
**Current State:**
|
||||
- Missing fields: `memberType`, `companyName`
|
||||
|
||||
**Changes Needed:**
|
||||
- Add `memberType` property (enum: INDIVIDUAL, ORGANIZATION)
|
||||
- Add `companyName` property (string, optional)
|
||||
- Update description to mention type transitions
|
||||
|
||||
### Tools: list_members and get_member
|
||||
**Current State:**
|
||||
- No input changes needed (query tools)
|
||||
- Output fields come from GraphQL queries
|
||||
|
||||
**Changes Needed:**
|
||||
- No changes to tool definitions
|
||||
- GraphQL queries will be updated to include new fields
|
||||
|
||||
## GraphQL Query Updates
|
||||
|
||||
### Query: listMembers (line ~297)
|
||||
**Add fields:**
|
||||
```graphql
|
||||
memberType
|
||||
companyName
|
||||
```
|
||||
|
||||
### Query: getMember (line ~328)
|
||||
**Add fields:**
|
||||
```graphql
|
||||
memberType
|
||||
companyName
|
||||
```
|
||||
|
||||
### Mutation: createMember (line ~371)
|
||||
**Add fields to response:**
|
||||
```graphql
|
||||
memberType
|
||||
companyName
|
||||
```
|
||||
|
||||
### Mutation: updateMember (line ~402)
|
||||
**Add fields to response:**
|
||||
```graphql
|
||||
memberType
|
||||
companyName
|
||||
```
|
||||
|
||||
## Member Formatting Logic
|
||||
|
||||
### Function: formatMember (line ~580)
|
||||
**Current State:**
|
||||
- Line 583: Always displays "Name: firstName lastName"
|
||||
- Assumes all members are individuals
|
||||
|
||||
**Changes Needed:**
|
||||
1. Check `member.memberType` to determine formatting approach
|
||||
2. For INDIVIDUAL members:
|
||||
- Display: `Type: Individual`
|
||||
- Display: `Name: firstName lastName`
|
||||
3. For ORGANIZATION members:
|
||||
- Display: `Type: Organization`
|
||||
- Display: `Company: companyName`
|
||||
- Optionally display: `Contact Person: firstName lastName` (if present)
|
||||
|
||||
**Example Output:**
|
||||
|
||||
For Individual:
|
||||
```
|
||||
ID: 1
|
||||
Type: Individual
|
||||
Name: John Doe
|
||||
Email: john@example.com
|
||||
...
|
||||
```
|
||||
|
||||
For Organization:
|
||||
```
|
||||
ID: 2
|
||||
Type: Organization
|
||||
Company: Acme Corporation
|
||||
Contact Person: Jane Smith
|
||||
Email: info@acme.com
|
||||
...
|
||||
```
|
||||
|
||||
### Function: formatMembers (line ~622)
|
||||
**Current State:**
|
||||
- Calls `formatMember()` for each member
|
||||
- No changes needed (delegates to formatMember)
|
||||
|
||||
## Schema Discovery
|
||||
|
||||
The MCP server includes a `get_graphql_schema` tool that performs introspection. This tool will automatically discover the new `MemberType` enum without code changes, but we should verify it works correctly.
|
||||
|
||||
## Implementation Strategy
|
||||
|
||||
1. **Update tool definitions** (create_member and update_member)
|
||||
- Add memberType and companyName properties
|
||||
- Update descriptions
|
||||
- Adjust required fields
|
||||
|
||||
2. **Update GraphQL queries/mutations**
|
||||
- Add memberType and companyName to all member queries
|
||||
- Add to all mutation responses
|
||||
|
||||
3. **Update formatMember function**
|
||||
- Add type checking logic
|
||||
- Branch formatting based on memberType
|
||||
- Handle both individual and organization display
|
||||
|
||||
4. **Test changes**
|
||||
- Verify individual member creation (existing behavior)
|
||||
- Verify organization member creation (new behavior)
|
||||
- Verify member listing shows correct formatting
|
||||
- Verify schema introspection includes MemberType enum
|
||||
|
||||
## Backward Compatibility
|
||||
|
||||
- Existing MCP clients not providing `memberType` will default to INDIVIDUAL (GraphQL default)
|
||||
- Existing queries will work as before (new fields are optional in responses)
|
||||
- Member formatting will gracefully handle missing memberType (defaults to INDIVIDUAL)
|
||||
|
||||
## File Changes Summary
|
||||
|
||||
**Single File to Modify:**
|
||||
- `src/mcp_server.ts` - All changes are in this file
|
||||
- Lines 154-189: update_member tool definition
|
||||
- Lines 191-228: update_member tool definition
|
||||
- Lines 297-314: listMembers query
|
||||
- Lines 328-344: getMember query
|
||||
- Lines 371-388: createMember mutation
|
||||
- Lines 402-419: updateMember mutation
|
||||
- Lines 580-620: formatMember function
|
||||
Reference in New Issue
Block a user