Overview of AppFunctions

AppFunctions is an Android platform API with an accompanying Jetpack library to simplify Android MCP integration. It empowers your apps to behave like on device MCP servers, contributing functions that act as tools for use by proactive features along with agents and assistants, like Google Gemini. As of May 2026, AppFunctions integration with Gemini is in a private preview with trusted testers. You can begin preparing your apps now to use AppFunctions and development tools.

By defining these AppFunctions, you enable your app to provide services, data, and actions to the registry built into the Android OS, allowing users to complete tasks through agents and system-level interactions.

AppFunctions serve as the mobile equivalent of tools within the Model Context Protocol (MCP). While MCP traditionally standardizes how agents connect to server-side tools, AppFunctions provide the same mechanism for Android apps. This lets you expose your app's capabilities as orchestratable "tools" that authorized apps (callers) can discover and execute to fulfill user intents. Callers must have the EXECUTE_APP_FUNCTIONS permission to discover and execute AppFunctions, and can include agents, apps, and AI assistants like Gemini.

AppFunctions is available on devices running Android 16 or higher.

Example use cases

AppFunctions provide a powerful mechanism to automate tasks and streamline user interactions. By opening up your app's capabilities, you enable users to accomplish complex goals using natural language, often replacing the need for step-by-step, manual navigation with your UI.

The following scenarios illustrate how AppFunctions can be used to drive experiences within a variety of app categories:

  • Task management and productivity

    • User request: "Remind me to pick up my package at work today at 5 PM".
    • AppFunction action: The caller identifies the relevant task management app and invokes a function to create a task, automatically populating the title, time, and location fields based on the user's prompt.
    /**
    *   Create a new task or reminder with a title, due time, and location.
    *
    *   @param context The execution context provided by the system.
    *   @param title The descriptive title of the task (e.g., "Pick up my package").
    *   @param dueDateTime The specific date and time when the task should be completed.
    *   @param location The physical location associated with the task (e.g., "Work").
    *   @return The created Task
    */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun createTask(
        context: AppFunctionContext,
        title: String,
        dueDateTime: LocalDateTime? = null,
        location: String? = null
    ) : Task
    
  • Media and entertainment

    • User request: "Create a new playlist with the top jazz albums from this year".
    • AppFunction action: The caller executes a playlist creation function within a music app, passing context like "top jazz albums for 2026" as the query to generate the playlist immediately.
    /**
    *   Create a new music playlist based on a natural language query.
    *
    *   @param context The execution context provided by the system.
    *   @param query The description used to generate the playlist (e.g., "top jazz albums from 2026").
    *   @return The final created playlist based on songs.
    */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun createPlaylistFromQuery(
        context: AppFunctionContext,
        query: String
    ): Playlist
    
  • Cross-app workflows

    • User request: "Find the noodle recipe from Lisa's email and add the ingredients to my shopping list".
    • AppFunction action: This request uses functions from multiple apps. First, the caller uses an email app's search function to retrieve the content. Then, it extracts the relevant ingredients and invokes a shopping list app's function to populate the user's list.
    /**
    *   Search for emails matching a query or sender name to retrieve content like recipes.
    *
    *   @param context The execution context provided by the system.
    *   @param query The search term or contact name (e.g., "Lisa noodle recipe").
    *   @return A list of matching email summaries containing the requested information.
    */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun searchEmails(
        context: AppFunctionContext,
        query: String
    ): List<EmailSummary>
    
    /**
    *   Add a list of items or ingredients to the user's active shopping list.
    *
    *   @param context The execution context provided by the system.
    *   @param items The names of the ingredients or products to add to the list.
    *   @return The final shopping list with new items added
    */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun addItemsToShoppingList(
        context: AppFunctionContext,
        items: List<String>
    ): ShoppingList
    
  • Calendar and scheduling

    • User request: "Add Mom's birthday party to my calendar for next Monday at 6 PM".
    • AppFunction action: The approved agentic app invokes the calendar app's "create event" function, parsing the relevant context like "next Monday" and "6 PM" to create the entry without the user needing to manually open the calendar.
    /**
    *   Schedule a new event on the user's primary calendar.
    *
    *   @param context The execution context provided by the system.
    *   @param title The name of the calendar event (e.g., "Mom's birthday party").
    *   @param startDateTime The specific date and time the event is scheduled to begin.
    *   @return The created Event object.
    */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun createCalendarEvent(
        context: AppFunctionContext,
        title: String,
        startDateTime: LocalDateTime
    ): Event
    

How AppFunctions work

The following diagram illustrates the typical flow of how AppFunctions are shared by apps to an agent and subsequently executed. Agents are likely to consider both server-side remote MCP tools and local AppFunctions together when handling user requests. The detailed flow for using local AppFunctions is as follows:

  • AppFunction declaration: The Android app is built to use AppFunctions to make its features available, such as "Create note" or "Send message".
  • Schema generation: The AppFunctions Jetpack library generates an XML schema file that lists all the declared AppFunctions in the app. The Android OS uses this file to index the available AppFunctions.
  • Metadata retrieval: The agent can retrieve AppFunction metadata by querying it.
  • AppFunction selection and execution: Based on user prompts, the agent selects and executes the appropriate AppFunction with the appropriate parameters.
Typical AppFunctions flow from app exposure to agent execution.
Figure 1: The typical flow of how AppFunctions are exposed and subsequently executed by an agent.

The AppFunctions Jetpack library simplifies exposing your app's functionality. With the annotation processor, you annotate the functions you want to make available to agents. Callers can then discover and invoke these indexed functions using AppFunctionManager.

Before invoking a function, callers should verify that the device supports the AppFunctions feature by attempting to retrieve an instance of AppFunctionManager. Once supported, callers can verify whether a specific function is enabled within a target app using isAppFunctionEnabled(packageName,functionId). Querying the status of functions in other packages requires the android.permission.EXECUTE_APP_FUNCTIONSpermission.

Your app is not required to verify whether the AppFunction feature is supported; this is automatically handled within the Jetpack library. For example, AppFunctionManager can verify whether or not the feature is supported.

Here's an example of AppFunctions for a note-taking app with capabilities to create, edit, and list notes:

/**
 * A note app's [AppFunction]s.
 */
class NoteFunctions(
    private val noteRepository: NoteRepository
) {
    /**
     * Lists all available notes.
     *
     * @param appFunctionContext The context in which the AppFunction is executed.
     */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun listNotes(appFunctionContext: AppFunctionContext): List<Note>? {
        return noteRepository.appNotes.ifEmpty { null }?.toList()
    }

    /**
     * Adds a new note to the app.
     *
     * @param appFunctionContext The context in which the AppFunction is executed.
     * @param title The title of the note.
     * @param content The note's content.
     */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun createNote(
        appFunctionContext: AppFunctionContext,
        title: String,
        content: String
    ): Note {
        return noteRepository.createNote(title, content)
    }

    /**
     * Edits a single note.
     *
     * @param appFunctionContext The context in which the AppFunction is executed.
     * @param noteId The target note's ID.
     * @param title The note's title if it should be updated.
     * @param content The new content if it should be updated.
     */
    @AppFunction(isDescribedByKDoc = true)
    suspend fun editNote(
        appFunctionContext: AppFunctionContext,
        noteId: Int,
        title: String?,
        content: String?,
    ): Note? {
        return noteRepository.updateNote(noteId, title, content)
    }
}

/**
 * A note.
 */
@AppFunctionSerializable(isDescribedByKDoc = true)
data class Note(
    /** The note's identifier */
    val id: Int,
    /** The note's title */
    val title: String,
    /** The note's content */
    val content: String
)

Frequently asked questions (FAQs)

The following section addresses frequently asked questions about AppFunctions.

I'm an app developer. Can I implement AppFunctions today?

Yes, it's possible to implement and test AppFunctions within your app by following the guidance detailed in the preceding sections.

What's the difference between AppFunctions and MCP?

Both allow AI agents to orchestrate tools, but have significant differences in their architecture, latency, and required developer effort. AppFunctions are built-in OS-level hooks exclusive to Android that execute locally. By contrast, a standard MCP server is a platform-agnostic solution that relies on cloud execution and network round-trips.

In short, developing with AppFunctions lets you use the existing app state directly on-device and does not require you to maintain services outside your Android app.

I have implemented AppFunctions in my app. Why can my system agent not access them?

AppFunctions are an experimental feature. To carefully evaluate the quality of the overall experience during this experimental phase, only a limited number of apps and system agents can access the entire pipeline.

How can I prepare my app for general availability of AppFunctions?

Consider which features of your app you want to expose to agentic automation. You can implement AppFunctions in your app. To do so, follow the steps in the preceding sections on this page, and verify that they are registered on the device by calling adb shell cmd app_function list-app-functions.

Can I get early access to the end-to-end agentic developer experience?

We're conducting an Early Access Program (EAP) to onboard select apps in testing the end-to-end developer experience required to launch AppFunctions to production on Android. You can register your interest in integrating your AppFunctions through this EAP registration up form. By registering your interest, you do NOT automatically obtain access to the full integration. We'll email you if your app is selected for the EAP, or to let you know when AppFunctions become publicly available.

How can I provide feedback on AppFunctions?

You can provide feedback on the API by filing an issue and registering your interest in the Early Access Program form.