chore: Archive update-mcp-server-for-organization-members OpenSpec change
Archive completed OpenSpec change after successful implementation and testing. The MCP server has been updated to support organization members with all 11 tasks completed and 57 tests passing. Changes: - Moved change from openspec/changes/ to openspec/changes/archive/ - Archived as 2025-12-04-update-mcp-server-for-organization-members - Skipped spec updates (--skip-specs) as functionality is already covered by existing mcp-integration spec Implementation summary: - Updated TypeScript MCP server with memberType and companyName support - Added proper pytest tests for organization members (4 new tests) - All integration and e2e tests passing - MCP tools now handle both INDIVIDUAL and ORGANIZATION member types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+159
@@ -0,0 +1,159 @@
|
||||
# Spec Delta: MCP Member Tools for Organization Support
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Create Member Tool
|
||||
The MCP server SHALL provide a `create_member` tool that creates both individual and organization members via the GraphQL API.
|
||||
|
||||
#### Scenario: Create individual member with first name
|
||||
- **GIVEN** memberType is "INDIVIDUAL" or not specified
|
||||
- **WHEN** the `create_member` tool is invoked with firstName="Alice"
|
||||
- **THEN** the tool SHALL create a new individual member with firstName="Alice"
|
||||
- **AND** return the created member with generated ID and memberType="INDIVIDUAL"
|
||||
|
||||
#### Scenario: Create organization member with company name
|
||||
- **GIVEN** memberType is "ORGANIZATION"
|
||||
- **WHEN** the `create_member` tool is invoked with memberType="ORGANIZATION" and companyName="Acme Corp"
|
||||
- **THEN** the tool SHALL create a new organization member with companyName="Acme Corp"
|
||||
- **AND** return the created member with generated ID and memberType="ORGANIZATION"
|
||||
|
||||
#### Scenario: Create organization with contact person
|
||||
- **GIVEN** memberType is "ORGANIZATION"
|
||||
- **WHEN** the `create_member` tool is invoked with memberType="ORGANIZATION", companyName="Tech Inc", and firstName="Jane"
|
||||
- **THEN** the tool SHALL create an organization member with both company name and contact person
|
||||
- **AND** return the created member with all fields populated
|
||||
|
||||
#### Scenario: Create individual without firstName
|
||||
- **GIVEN** memberType is "INDIVIDUAL" or not specified
|
||||
- **WHEN** the `create_member` tool is invoked without firstName
|
||||
- **THEN** the tool SHALL return a validation error indicating firstName is required for individual members
|
||||
|
||||
#### Scenario: Create organization without companyName
|
||||
- **GIVEN** memberType is "ORGANIZATION"
|
||||
- **WHEN** the `create_member` tool is invoked without companyName
|
||||
- **THEN** the tool SHALL return a validation error indicating companyName is required for organization members
|
||||
|
||||
### Requirement: Update Member Tool
|
||||
The MCP server SHALL provide an `update_member` tool that updates existing member information including member type transitions.
|
||||
|
||||
#### Scenario: Update member type from individual to organization
|
||||
- **GIVEN** a member exists with ID 1 as type INDIVIDUAL
|
||||
- **WHEN** the `update_member` tool is invoked with id=1, memberType="ORGANIZATION", and companyName="New Corp"
|
||||
- **THEN** the tool SHALL update the member to type ORGANIZATION
|
||||
- **AND** return the updated member with memberType="ORGANIZATION" and companyName="New Corp"
|
||||
|
||||
#### Scenario: Update organization company name
|
||||
- **GIVEN** a member exists with ID 2 as type ORGANIZATION with companyName="Old Corp"
|
||||
- **WHEN** the `update_member` tool is invoked with id=2 and companyName="Updated Corp"
|
||||
- **THEN** the tool SHALL update the company name
|
||||
- **AND** return the updated member with companyName="Updated Corp"
|
||||
|
||||
#### Scenario: Update individual to organization without companyName
|
||||
- **GIVEN** a member exists with ID 1 as type INDIVIDUAL
|
||||
- **WHEN** the `update_member` tool is invoked with id=1 and memberType="ORGANIZATION" but no companyName
|
||||
- **THEN** the tool SHALL return a validation error indicating companyName is required for organization members
|
||||
|
||||
### Requirement: List Members Tool Output
|
||||
The `list_members` tool SHALL return member data including memberType and companyName fields.
|
||||
|
||||
#### Scenario: List members with mixed types
|
||||
- **GIVEN** the database contains 2 individual members and 1 organization member
|
||||
- **WHEN** the `list_members` tool is invoked
|
||||
- **THEN** the tool SHALL return all 3 members
|
||||
- **AND** each member SHALL include memberType field
|
||||
- **AND** organization members SHALL include companyName field
|
||||
- **AND** formatting SHALL distinguish between individuals and organizations
|
||||
|
||||
### Requirement: Get Member Tool Output
|
||||
The `get_member` tool SHALL return member data including memberType and companyName fields.
|
||||
|
||||
#### Scenario: Get individual member by ID
|
||||
- **GIVEN** a member exists with ID 1 as type INDIVIDUAL
|
||||
- **WHEN** the `get_member` tool is invoked with id=1
|
||||
- **THEN** the tool SHALL return the member with memberType="INDIVIDUAL"
|
||||
- **AND** format the output showing "Type: Individual" and "Name: firstName lastName"
|
||||
|
||||
#### Scenario: Get organization member by ID
|
||||
- **GIVEN** a member exists with ID 2 as type ORGANIZATION with companyName="Acme Corp"
|
||||
- **WHEN** the `get_member` tool is invoked with id=2
|
||||
- **THEN** the tool SHALL return the member with memberType="ORGANIZATION" and companyName="Acme Corp"
|
||||
- **AND** format the output showing "Type: Organization" and "Company: Acme Corp"
|
||||
|
||||
### Requirement: Member Formatting
|
||||
The MCP server SHALL format member output differently based on member type.
|
||||
|
||||
#### Scenario: Format individual member
|
||||
- **GIVEN** a member object with memberType="INDIVIDUAL", firstName="John", lastName="Doe"
|
||||
- **WHEN** the formatMember function is called
|
||||
- **THEN** the output SHALL include "Type: Individual"
|
||||
- **AND** the output SHALL include "Name: John Doe"
|
||||
|
||||
#### Scenario: Format organization member
|
||||
- **GIVEN** a member object with memberType="ORGANIZATION", companyName="Tech Corp"
|
||||
- **WHEN** the formatMember function is called
|
||||
- **THEN** the output SHALL include "Type: Organization"
|
||||
- **AND** the output SHALL include "Company: Tech Corp"
|
||||
|
||||
#### Scenario: Format organization with contact person
|
||||
- **GIVEN** a member object with memberType="ORGANIZATION", companyName="Tech Corp", firstName="Jane", lastName="Smith"
|
||||
- **WHEN** the formatMember function is called
|
||||
- **THEN** the output SHALL include "Type: Organization"
|
||||
- **AND** the output SHALL include "Company: Tech Corp"
|
||||
- **AND** the output SHALL include "Contact Person: Jane Smith"
|
||||
|
||||
#### Scenario: Format member with missing memberType
|
||||
- **GIVEN** a member object without memberType field (legacy data)
|
||||
- **WHEN** the formatMember function is called
|
||||
- **THEN** the function SHALL default to treating it as INDIVIDUAL
|
||||
- **AND** format the output using individual member format
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Tool Input Schema for Member Type
|
||||
The `create_member` and `update_member` tools SHALL accept memberType and companyName in their input schemas.
|
||||
|
||||
#### Scenario: Tool accepts memberType enum values
|
||||
- **GIVEN** the create_member tool definition
|
||||
- **WHEN** inspecting the input schema
|
||||
- **THEN** memberType SHALL be defined as an enum with values "INDIVIDUAL" and "ORGANIZATION"
|
||||
- **AND** memberType SHALL be optional with default value "INDIVIDUAL"
|
||||
|
||||
#### Scenario: Tool accepts companyName field
|
||||
- **GIVEN** the create_member tool definition
|
||||
- **WHEN** inspecting the input schema
|
||||
- **THEN** companyName SHALL be defined as a string type
|
||||
- **AND** companyName SHALL be optional
|
||||
- **AND** the description SHALL indicate it's required for ORGANIZATION members
|
||||
|
||||
#### Scenario: firstName is optional in schema
|
||||
- **GIVEN** the create_member tool definition
|
||||
- **WHEN** inspecting the input schema
|
||||
- **THEN** firstName SHALL NOT be in the required array
|
||||
- **AND** the description SHALL indicate it's required for INDIVIDUAL members
|
||||
|
||||
### Requirement: GraphQL Query Completeness
|
||||
All GraphQL queries and mutations in the MCP server SHALL include memberType and companyName fields.
|
||||
|
||||
#### Scenario: listMembers query includes new fields
|
||||
- **GIVEN** the listMembers GraphQL query
|
||||
- **WHEN** the query is executed
|
||||
- **THEN** the query SHALL request memberType field
|
||||
- **AND** the query SHALL request companyName field
|
||||
|
||||
#### Scenario: getMember query includes new fields
|
||||
- **GIVEN** the getMember GraphQL query
|
||||
- **WHEN** the query is executed
|
||||
- **THEN** the query SHALL request memberType field
|
||||
- **AND** the query SHALL request companyName field
|
||||
|
||||
#### Scenario: createMember mutation includes new fields in response
|
||||
- **GIVEN** the createMember mutation
|
||||
- **WHEN** the mutation is executed
|
||||
- **THEN** the mutation SHALL request memberType in the response
|
||||
- **AND** the mutation SHALL request companyName in the response
|
||||
|
||||
#### Scenario: updateMember mutation includes new fields in response
|
||||
- **GIVEN** the updateMember mutation
|
||||
- **WHEN** the mutation is executed
|
||||
- **THEN** the mutation SHALL request memberType in the response
|
||||
- **AND** the mutation SHALL request companyName in the response
|
||||
Reference in New Issue
Block a user