mcpField
S
sirikit

sirikit

github.com/ios-agentDevelopment1240 installsUpdated 34w ago
Repository

About sirikit

sirikit is a development skill for Apple app developers implementing SiriKit interactions. It covers custom intents, shortcuts, suggestions, and the associated handling and configuration patterns.

Key features

  1. 01Configure Intents extensions and Siri access
  2. 02Define custom intents and parameters
  3. 03Handle intent resolution, confirmation, and execution
  4. 04Donate and delete shortcuts
  5. 05Customize Siri UI and vocabulary

Use cases

  1. 01Add voice actions to an app
  2. 02Suggest shortcuts based on user actions
  3. 03Receive and handle Siri intents in an app

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/ios-agent/iosagent.dev --skill sirikit

After installing, type/sirikitin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

references/
app-intents.md
custom-intents.md
intent-handling.md
intents-ui.md
shortcuts.md
vocabulary.md

Details

From the project README

SiriKit Development Skill

Empower users to interact with your app through voice, Shortcuts, and intelligent suggestions.

Quick Start

Add Intents Extension
  1. File → New → Target → Intents Extension
  2. Enable "Include UI Extension" if customizing Siri interface
  3. Enable Siri capability in main app target (Signing & Capabilities)
Minimal Intent Handler
import Intents

class IntentHandler: INExtension {
    override func handler(for intent: INIntent) -> Any {
        switch intent {
        case is OrderSoupIntent:
            return OrderSoupIntentHandler()
        default:
            return self
        }
    }
}

class OrderSoupIntentHandler: NSObject, OrderSoupIntentHandling {
    // 1. Resolve parameters
    func resolveSoup(for intent: OrderSoupIntent) async -> SoupResolutionResult {
        guard let soup = intent.soup else {
            return .needsValue()
        }
        return .success(with: soup)
    }
    
    // 2. Confirm intent
    func confirm(intent: OrderSoupIntent) async -> OrderSoupIntentResponse {
        return OrderSoupIntentResponse(code: .ready, userActivity: nil)
    }
    
    // 3. Handle intent
    func handle(intent: OrderSoupIntent) async -> OrderSoupIntentResponse {
        // Fulfill the request
        return OrderSoupIntentResponse.success(message: "Your order is confirmed!")
    }
}

Intent Handling Flow

┌─────────────────────────────────────────────────────────────┐
│                    User speaks to Siri                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 1. RESOLVE - Validate each parameter                         │
│    • Return .success(with:) if valid                        │
│    • Return .needsValue() if missing                        │
│    • Return .disambiguation(with:) for choices              │
│    • Return .unsupported() if invalid                       │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. CONFIRM - Final validation before execution               │
│    • Verify services are ready                              │
│    • Return .ready or appropriate failure code              │
└─────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. HANDLE - Fulfill the intent                               │
│    • Execute the action                                     │
│    • Return success/failure response                        │
└─────────────────────────────────────────────────────────────┘

System Intent Domains

DomainUse CasesKey Intents
MessagingSend/search messagesINSendMessageIntent, INSearchForMessagesIntent
CallingVoIP callsINStartCallIntent, INSearchCallHistoryIntent
PaymentsMoney transfersINSendPaymentIntent, INRequestPaymentIntent
Ride BookingRequest ridesINRequestRideIntent, INGetRideStatusIntent
WorkoutsStart/end workoutsINStartWorkoutIntent, INEndWorkoutIntent
MediaPlay audio/videoINPlayMediaIntent, INAddMediaIntent
PhotosSearch photosINSearchForPhotosIntent
Lists & NotesCreate notes/tasksINCreateNoteIntent, INAddTasksIntent
Car CommandsVehicle controlsINSetCarLockStatusIntent, INActivateCarSignalIntent
ReservationsRestaurant bookingsINGetReservationDetailsIntent

Custom Intents

Define in Intent Definition File
  1. Create Intents.intentdefinition file
  2. Add new intent with VerbNoun naming (e.g., OrderSoup)
  3. Set category matching purpose
  4. Define parameters with types
Parameter Types
  • System: String, Integer, Boolean, Date, Person, Location, Currency
  • Custom: Define your own types as enums or objects

Reference Documentation

Key Configuration

Info.plist (Intents Extension)
<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>IntentsSupported</key>
        <array>
            <string>OrderSoupIntent</string>
        </array>
        <key>IntentsRestrictedWhileLocked</key>
        <array>
            <string>INSendPaymentIntent</string>
        </array>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.intents-service</string>
    <key>NSExtensionPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).IntentHandler</string>
</dict>
Request Siri Authorization
import Intents

INPreferences.requestSiriAuthorization { status in
    switch status {
    case .authorized: print("Siri authorized")
    case .denied: print("Siri denied")
    case .notDetermined: print("Not determined")
    case .restricted: print("Restricted")
    @unknown default: break
    }
}

Common Patterns

Donate Shortcut After User Action
import Intents

func donateOrderShortcut(order: Order) {
    let intent = OrderSoupIntent()
    intent.soup = order.soup
    intent.quantity = order.quantity
    
    let interaction = INInteraction(intent: intent, response: nil)
    interaction.identifier = order.id.uuidString
    
    interaction.donate { error in
        if let error = error {
            print("Donation failed: \(error)")
        }
    }
}
Delete Donated Shortcuts
// Delete specific
INInteraction.delete(with: [orderID.uuidString]) { error in }

// Delete all from app
INInteraction.deleteAll { error in }
Handle Intent in App (when launched)
// SwiftUI
.onContinueUserActivity(NSStringFromClass(OrderSoupIntent.self)) { activity in
    if let intent = activity.interaction?.intent as? OrderSoupIntent {
        handleOrderIntent(intent)
    }
}

// UIKit SceneDelegate
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    if let intent = userActivity.interaction?.intent as? OrderSoupIntent {
        handleOrderIntent(intent)
    }
}

Key Constraints

  • Background execution: Extensions run briefly; launch app for long tasks
  • Shared data: Use App Groups for data between app and extension
  • No UI in extension: Use IntentsUI extension for custom views
  • Testing: Wait after install for Siri to recognize new intents
  • Localization: Provide localized AppIntentVocabulary.plist

Comments

Markdown supported