FoundationModelsKit
Community made tools to directly use it in your app with Foundation Models framework
Install / Use
/learn @rryam/FoundationModelsKitREADME
FoundationModelsKit
A collection of tools and utilities for Apple's Foundation Models Framework that help working with the language model, better.
Table of Contents
- Overview
- Features
- Requirements
- Installation
- Quick Start
- Configuration
- Tool Reference
- Utilities
- Usage Examples
- Advanced Topics
- Contributing
- License
Overview
FoundationModelsTools provides a set of pre-built tools and utilities that extend the capabilities of models using Apple's Foundation Models Framework. These tools allow you to:
- Access and manage calendar events
- Read and create contacts
- Get health data from HealthKit
- Access location services
- Control music playback
- Manage reminders
- Fetch weather information
- Extract metadata from web pages
- Search the web using Exa
- Manage context windows with token counting utilities
Features
- Native Apple Framework Integration: Works seamlessly with EventKit, Contacts, HealthKit, CoreLocation, MapKit, and MusicKit
- Modern Swift Concurrency: Built with async/await patterns throughout
- Type-Safe: Leverages Swift's type system with the
@Generableprotocol - Permission Handling: Automatic authorization checks for privacy-sensitive operations
- Cross-Platform: Supports both iOS and macOS
- Comprehensive Error Handling: Detailed error messages for troubleshooting
Requirements
- macOS 26.0+
- iOS 26.0+
- Swift 6.2+
- Xcode 26.0+
Installation
Add FoundationModelsTools as a dependency in your Package.swift:
dependencies: [
.package(url: "https://github.com/rudrankriyam/FoundationModelsTools", from: "0.1.0")
]
Then add it to your target dependencies:
.target(
name: "YourTarget",
dependencies: ["FoundationModelsTools"]
)
Quick Start
Here's a simple example to get you started:
import FoundationModels
import FoundationModelsTools
// Create a weather tool
let weatherTool = WeatherTool()
// Call it directly
let arguments = WeatherTool.Arguments(city: "San Francisco")
let result = try await weatherTool.call(arguments: arguments)
// Access the results
let temperature = result.value(Double.self, forProperty: "temperature")
let condition = result.value(String.self, forProperty: "condition")
print("It's \(temperature)°C and \(condition)")
Configuration
Privacy Permissions
Add the required usage descriptions to your Info.plist for the tools you plan to use:
<!-- Calendar Access -->
<key>NSCalendarsUsageDescription</key>
<string>This app needs access to your calendar to create and manage events</string>
<!-- Contacts Access -->
<key>NSContactsUsageDescription</key>
<string>This app needs access to your contacts to search and create contact entries</string>
<!-- Health Data Access -->
<key>NSHealthShareUsageDescription</key>
<string>This app needs to read your health data</string>
<!-- Location Access -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs your location to provide location-based services</string>
<!-- Apple Music Access -->
<key>NSAppleMusicUsageDescription</key>
<string>This app needs access to Apple Music to control playback</string>
<!-- Reminders Access -->
<key>NSRemindersUsageDescription</key>
<string>This app needs access to reminders to create and manage tasks</string>
API Keys
WebTool requires an Exa API key.
⚠️ SECURITY WARNING
Do note store API keys directly in your app code or use
@AppStoragefor your production apps. API keys stored client-side can be extracted from your app bundle and misused.Recommended approach: Make API requests from a secure server where the API key is stored as an environment variable. Your app should call your server endpoint, which then makes the request to Exa's API.
For development/testing only, you can configure the key using @AppStorage:
import SwiftUI
@main
struct MyApp: App {
@AppStorage("exaAPIKey") private var exaAPIKey = ""
var body: some Scene {
WindowGroup {
ContentView()
.onAppear {
// DEVELOPMENT ONLY - Never ship API keys in production
// Get your key from: https://exa.ai
exaAPIKey = "your-api-key-here"
}
}
}
}
Production setup:
- Create a server endpoint (e.g.,
/api/search) - Store your Exa API key in environment variables on the server
- Your app calls your server endpoint with the search query
- Your server makes the request to Exa's API and returns the results
Tool Reference
CalendarTool
Access and manage calendar events using EventKit.
Name: manageCalendar
Actions: create, query, read, update
Requirements:
- Calendar entitlement
- User permission via
NSCalendarsUsageDescription
Arguments:
action: The operation to performtitle: Event title (required for create)startDate: Start date inYYYY-MM-DD HH:mm:ssformatendDate: End date inYYYY-MM-DD HH:mm:ssformatlocation: Event locationnotes: Additional notescalendarName: Specific calendar to use (optional)daysAhead: Number of days to query (default: 7)eventId: Event identifier for read/update operations
Example:
let calendarTool = CalendarTool()
// Create an event
let createArgs = CalendarTool.Arguments(
action: "create",
title: "Team Meeting",
startDate: "2025-11-15 14:00:00",
endDate: "2025-11-15 15:00:00",
location: "Conference Room A",
notes: "Discuss Q4 planning"
)
let result = try await calendarTool.call(arguments: createArgs)
// Query upcoming events
let queryArgs = CalendarTool.Arguments(
action: "query",
daysAhead: 7
)
let events = try await calendarTool.call(arguments: queryArgs)
print(events.value(String.self, forProperty: "events"))
Returns:
status: "success" or "error"eventId: Unique event identifiertitle: Event titlestartDate: Formatted start dateendDate: Formatted end datelocation: Event locationcalendar: Calendar name
ContactsTool
Search, read, and create contacts using the Contacts framework.
Name: manageContacts
Actions: search, read, create
Requirements:
- Contacts entitlement
- User permission via
NSContactsUsageDescription
Arguments:
action: The operation to performname: Name to search for (for search action)contactId: Contact identifier (for read action)firstName: First name (for create action)lastName: Last name (for create action)phoneNumber: Phone number (for create action)email: Email address (for create action)organization: Company/organization (for create action)
Example:
let contactsTool = ContactsTool()
// Search for contacts
let searchArgs = ContactsTool.Arguments(
action: "search",
name: "John"
)
let results = try await contactsTool.call(arguments: searchArgs)
// Create a new contact
let createArgs = ContactsTool.Arguments(
action: "create",
firstName: "Jane",
lastName: "Doe",
email: "jane.doe@example.com",
phoneNumber: "+1234567890",
organization: "Acme Corp"
)
let contact = try await contactsTool.call(arguments: createArgs)
Returns:
status: "success" or "error"contactId: Unique contact identifiergivenName: First namefamilyName: Last namefullName: Combined full nameemails: Array of email addressesphoneNumbers: Array of phone numbersorganization: Company name
HealthTool
Read health data from HealthKit including steps, heart rate, workouts, and more.
Name: accessHealth
Data Types: steps, heartRate, workouts, sleep, activeEnergy, distance
Requirements:
- HealthKit capability
- User permission via
NSHealthShareUsageDescription
Arguments:
dataType: Type of health data to querystartDate: Start date inYYYY-MM-DDformat (optional, defaults to 7 days ago)endDate: End date inYYYY-MM-DDformat (optional, defaults to today)
Example:
let healthTool = HealthTool()
// Query steps for the last 7 days
let stepsArgs = HealthTool.Arguments(
dataType: "steps",
startDate: "2025-11-07",
endDate: "2025-11-14"
)
let steps = try await healthTool.call(arguments: stepsArgs)
print("Total steps: \(steps.value(Int.self, forProperty: "totalSteps"))")
// Query heart rate
let heartArgs = HealthTool.Arguments(dataType: "heartRate")
let heartRate = try await healthTool.call(arguments: heartArgs)
// Query workouts
let workoutsArgs = HealthTool.Arguments(
dataType: "workouts",
startDate: "2025-11-01",
endDate: "2025-11-14"
)
let workouts = try await healthTool.call(arguments: workoutsArgs)
Returns (varies by data type):
status: "success" or "error"dataType: Type of data returnedtotalSteps: Total step count (for steps)averageBPM: Average heart rate (for heartRate)workoutCount: Number of workouts (for workouts)averageSleepHours: Average sleep duration (for sleep)totalCalories: Total act
