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>
7.9 KiB
7.9 KiB
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_membertool 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_membertool 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_membertool 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_membertool 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_membertool 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_membertool 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_membertool 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_membertool 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_memberstool 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_membertool 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_membertool 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