|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +This file provides guidance to Codex (Codex.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Language |
| 6 | +Response language: Russian |
| 7 | +Comment language: English |
| 8 | + |
| 9 | +## Project Overview |
| 10 | + |
| 11 | +MCP (Model Context Protocol) server for App Store Connect API integration, designed for Codex CLI. This server provides tools to manage iOS/macOS apps through App Store Connect. |
| 12 | + |
| 13 | +## Build and Run Commands |
| 14 | + |
| 15 | +```bash |
| 16 | +# Build the project |
| 17 | +swift build |
| 18 | + |
| 19 | +# Run all unit tests (436 tests) |
| 20 | +swift test |
| 21 | + |
| 22 | +# Run the MCP server (requires environment variables or companies.json) |
| 23 | +./.build/debug/asc-mcp |
| 24 | + |
| 25 | +# Run with worker filtering (for clients with tool limits) |
| 26 | +./.build/debug/asc-mcp --workers apps,builds,versions,reviews |
| 27 | + |
| 28 | +# Run integration tests |
| 29 | +./.build/debug/asc-mcp --test |
| 30 | + |
| 31 | +# Clean build |
| 32 | +swift package clean |
| 33 | +``` |
| 34 | + |
| 35 | +## Environment Configuration |
| 36 | + |
| 37 | +Three config methods (checked in priority order): |
| 38 | +1. `--companies /path/to/companies.json` (CLI argument) |
| 39 | +2. `ASC_MCP_COMPANIES` env var → path to JSON file |
| 40 | +3. Default JSON: `~/.config/asc-mcp/companies.json` |
| 41 | +4. `ASC_COMPANY_1_KEY_ID`, `ASC_COMPANY_2_KEY_ID`... (multi-company env vars) |
| 42 | +5. `ASC_KEY_ID` + `ASC_ISSUER_ID` + `ASC_PRIVATE_KEY_PATH` (single company env vars) |
| 43 | + |
| 44 | +Each company needs: `keyID`, `issuerID`, `privateKeyPath` (path to `.p8` file). |
| 45 | + |
| 46 | +## Architecture |
| 47 | + |
| 48 | +### Core Components |
| 49 | + |
| 50 | +**WorkerManager** (`Workers/MainWorker/WorkerManager.swift`) — central registry, routes tool calls by prefix. |
| 51 | + |
| 52 | +**Workers** (33 workers, 293 tools): |
| 53 | + |
| 54 | +| Worker | Prefix | Tools | Domain | |
| 55 | +|--------|--------|-------|--------| |
| 56 | +| CompaniesWorker | `company_` | 3 | Multi-account management | |
| 57 | +| AuthWorker | `auth_` | 4 | JWT tokens | |
| 58 | +| AppsWorker | `apps_` | 9 | App listing, metadata, localizations | |
| 59 | +| BuildsWorker | `builds_` | 4 | Build management | |
| 60 | +| BuildBetaDetailsWorker | `builds_*_beta_` | 11 | TestFlight localizations, notifications, beta groups, individual testers | |
| 61 | +| BuildProcessingWorker | `builds_*_processing_` | 4 | Build states, encryption | |
| 62 | +| AppLifecycleWorker | `app_versions_` | 14 | Versions, submit, release, phased rollout, delete | |
| 63 | +| ReviewsWorker | `reviews_` | 8 | Customer reviews, responses, AI summarizations | |
| 64 | +| BetaGroupsWorker | `beta_groups_` | 9 | TestFlight groups CRUD, testers, builds | |
| 65 | +| InAppPurchasesWorker | `iap_` | 24 | IAP, subscriptions, localizations, prices, screenshots, availability, images | |
| 66 | +| ProvisioningWorker | `provisioning_` | 17 | Bundle IDs, devices, certificates, profiles, capabilities | |
| 67 | +| BetaTestersWorker | `beta_testers_` | 12 | Tester management, search, invite, relationships, invitations | |
| 68 | +| AppInfoWorker | `app_info_` | 10 | App info, categories, localizations, EULA | |
| 69 | +| PricingWorker | `pricing_` | 9 | Territories, availability, price points/schedule, app availabilities v2 | |
| 70 | +| UsersWorker | `users_` | 10 | Team members, roles, invitations, visible apps | |
| 71 | +| AppEventsWorker | `app_events_` | 9 | In-app events CRUD, localizations | |
| 72 | +| AnalyticsWorker | `analytics_` | 11 | Sales/financial reports, app summary, analytics reports/instances/segments, snapshot status | |
| 73 | +| SubscriptionsWorker | `subscriptions_` | 29 | Subscription CRUD, groups, localizations, prices, submit, group localizations, images, review screenshots | |
| 74 | +| OfferCodesWorker | `offer_codes_` | 10 | Subscription offer codes, one-time codes, custom codes | |
| 75 | +| WinBackOffersWorker | `winback_` | 5 | Win-back offers for subscriptions | |
| 76 | +| IntroductoryOffersWorker | `intro_offers_` | 4 | Introductory offers (free trial, pay-as-you-go, pay-up-front) | |
| 77 | +| PromotionalOffersWorker | `promo_offers_` | 6 | Promotional offers for subscriptions | |
| 78 | +| SandboxTestersWorker | `sandbox_` | 3 | Sandbox testers (list, update, clear purchase history) | |
| 79 | +| BetaAppWorker | `beta_app_` | 10 | Beta app localizations, review submissions, review details | |
| 80 | +| PreReleaseVersionsWorker | `pre_release_` | 3 | Pre-release versions (list, get, builds) | |
| 81 | +| BetaLicenseAgreementsWorker | `beta_license_` | 3 | Beta license agreements (list, get, update) | |
| 82 | +| ScreenshotsWorker | `screenshots_` | 16 | Screenshots, previews, sets, reorder, full upload, batch upload | |
| 83 | +| CustomProductPagesWorker | `custom_pages_` | 10 | Custom product pages, versions, localizations | |
| 84 | +| ProductPageOptimizationWorker | `ppo_` | 9 | A/B test experiments, treatments | |
| 85 | +| PromotedPurchasesWorker | `promoted_` | 9 | Promoted in-app purchases, images upload | |
| 86 | +| ReviewAttachmentsWorker | `review_attachments_` | 4 | App Store review attachments (upload, get, delete, list) | |
| 87 | +| MetricsWorker | `metrics_` | 4 | Performance/power metrics, diagnostics | |
| 88 | + |
| 89 | +**Services**: HTTPClient (actor, GET/POST/PATCH/PUT/DELETE + retry with 429), JWTService (ES256), CompaniesManager |
| 90 | + |
| 91 | +### Key Implementation Details |
| 92 | + |
| 93 | +1. **Swift 6 Compliance**: All types `Sendable`, proper actor isolation |
| 94 | +2. **JWT Auth**: CryptoKit ES256, tokens expire after 20 min |
| 95 | +3. **Worker Pattern**: 3 files per worker (Main + ToolDefinitions + Handlers) |
| 96 | +4. **Routing**: WorkerManager routes by tool name prefix |
| 97 | +5. **Error Handling**: Custom `ASCError` type |
| 98 | + |
| 99 | +## API Constraints |
| 100 | + |
| 101 | +- **No emojis** in metadata fields (What's New, Description, etc.) |
| 102 | +- **Version states**: |
| 103 | + - `READY_FOR_SALE`: Published, read-only |
| 104 | + - `PREPARE_FOR_SUBMISSION`: Editable |
| 105 | + - `WAITING_FOR_REVIEW`, `IN_REVIEW`: Read-only |
| 106 | +- **Locale codes**: Use standard format (en-US, ru-RU, de-DE, etc.) |
| 107 | + |
| 108 | +## Testing |
| 109 | + |
| 110 | +### Unit Tests (Swift Testing) |
| 111 | + |
| 112 | +```bash |
| 113 | +swift test # Run all 436 tests across 31 suites |
| 114 | +``` |
| 115 | + |
| 116 | +Test categories: |
| 117 | +- **Worker tests** (`Tests/ASCMCPTests/Workers/`): |
| 118 | + - `WorkerToolDefinitionsTests` — tool count and name correctness per worker |
| 119 | + - `WorkerRoutingTests` — unknown tool throws `MCPError.methodNotFound` |
| 120 | + - `ParameterValidationTests` — missing required params returns `isError` |
| 121 | +- **Model tests** (`Tests/ASCMCPTests/Models/`) — decode, roundtrip, edge cases |
| 122 | +- **Service tests** (`Tests/ASCMCPTests/Services/`) — JWT generation |
| 123 | +- **Helper tests** (`Tests/ASCMCPTests/HelperTests/`) — JSON formatting, pagination |
| 124 | +- **Core tests** (`Tests/ASCMCPTests/Core/`) — ASCError, config models |
| 125 | + |
| 126 | +Test infrastructure: `TestFactory` (`Tests/ASCMCPTests/Helpers/TestHelpers.swift`) — creates mock HTTPClient, JWTService, loads fixtures. |
| 127 | + |
| 128 | +### Integration Test Mode |
| 129 | + |
| 130 | +```bash |
| 131 | +./.build/debug/asc-mcp --test # Test company switching |
| 132 | +./.build/debug/asc-mcp --test-metadata # Test metadata update |
| 133 | +``` |
| 134 | + |
| 135 | +## Common Tasks |
| 136 | + |
| 137 | +### Adding New Tool to Existing Worker |
| 138 | + |
| 139 | +1. Implement handler in `Worker+Handlers.swift` |
| 140 | +2. Add tool definition in `Worker+ToolDefinitions.swift` |
| 141 | +3. Register in worker's `getTools()` array |
| 142 | +4. Add case to worker's `handleTool()` switch |
| 143 | +5. No changes needed in WorkerManager — it automatically routes by prefix |
| 144 | + |
| 145 | +### Adding New Worker |
| 146 | + |
| 147 | +1. Create directory `Workers/MyWorker/` with 3 files: |
| 148 | + - `MyWorker.swift` — class, `getTools()`, `handleTool()` switch |
| 149 | + - `MyWorker+ToolDefinitions.swift` — tool schemas |
| 150 | + - `MyWorker+Handlers.swift` — handler implementations |
| 151 | +2. Create models in `Models/MyDomain/MyModels.swift` |
| 152 | +3. Register in `WorkerManager.swift`: property, init, `registerWorkers()` (ListTools + CallTool), `reinitializeWorkers()`, getter method |
| 153 | +4. Add worker name to `EntryPoint.swift` → `validWorkers` set |
| 154 | +5. Add prefix description to `Application.swift` → server instructions |
| 155 | +6. Update tests: `WorkerToolDefinitionsTests`, `WorkerRoutingTests`, `ParameterValidationTests` |
| 156 | + |
| 157 | +### Debugging API Issues |
| 158 | + |
| 159 | +- Check version state (must be PREPARE_FOR_SUBMISSION for edits) |
| 160 | +- Verify locale exists for the version |
| 161 | +- Remove any emojis from text fields |
| 162 | +- Check JWT token expiration (20 minutes) |
| 163 | + |
| 164 | +## Important Files |
| 165 | + |
| 166 | +- `EntryPoint.swift`: Entry point with `--workers` filtering and test modes |
| 167 | +- `Core/Application.swift`: MCP server setup and initialization |
| 168 | +- `Workers/MainWorker/WorkerManager.swift`: Tool registry and routing |
| 169 | +- `Models/`: API response/request models organized by domain: |
| 170 | + - `AppStoreConnect/`, `Builds/`, `AppLifecycle/` — apps, versions, builds |
| 171 | + - `InAppPurchases/`, `Subscriptions/` — IAP, subscriptions, offer codes, win-back |
| 172 | + - `Marketing/` — screenshots, custom pages, PPO experiments, promoted purchases |
| 173 | + - `Metrics/`, `Analytics/`, `AppEvents/` — performance, reports, events |
| 174 | + - `Provisioning/`, `Pricing/`, `Users/`, `AppInfo/` — provisioning, pricing, users |
| 175 | + - `Shared/` — shared types (upload operations, image assets) |
| 176 | +- `Services/HTTPClient.swift`: HTTP actor with JWT auth and retry logic |
| 177 | +- `Services/CompaniesManager.swift`: Multi-account management |
| 178 | +- `Services/JWTService.swift`: ES256 JWT token generation |
| 179 | +- `Helpers/`: JSONFormatter, SafeJSONHelpers, PaginationHelper, StderrWriter |
| 180 | + |
| 181 | +## Development Workflow Rules |
| 182 | + |
| 183 | +### Testing Approach |
| 184 | +- **ALWAYS test as real MCP**: When testing functionality, use actual MCP commands as if you're a real user working with the server |
| 185 | +- Test edge cases and error scenarios |
| 186 | +- Verify responses contain all necessary data for practical use |
| 187 | + |
| 188 | +### Development Process |
| 189 | +1. **After making changes and building the project:** |
| 190 | + - Always respond: "Ready to reload MCP" |
| 191 | + - Wait for user confirmation: "reloaded" or similar |
| 192 | + - Then proceed with testing via MCP commands |
| 193 | + - Fix any issues found during testing |
| 194 | + |
| 195 | +2. **After implementing features:** |
| 196 | + - Explain what each method returns |
| 197 | + - Describe practical use cases for the returned data |
| 198 | + - Example: "The `builds_list` method returns a list of builds with their statuses and dates. This is useful for selecting a build for TestFlight or submitting to the App Store" |
| 199 | + |
| 200 | +### Code Documentation Requirements |
| 201 | +- **MANDATORY**: Comment all public methods with: |
| 202 | + ```swift |
| 203 | + /// Brief description of what the method does |
| 204 | + /// - Returns: Description of return value and its structure |
| 205 | + /// - Throws: What errors can be thrown |
| 206 | + ``` |
| 207 | +- Document complex logic inline |
| 208 | +- Add usage examples for non-obvious methods |
0 commit comments