The Android Developers account called AppFunctions "officially in beta" from the Android Dev Summit stage. The Jetpack library it points you to is 1.0.0-alpha10.
That gap is the whole story.
i opened the docs page to check what i would actually be installing. The banner at the top still calls AppFunctions an experimental preview, subject to change. The page was last updated a week before the summit.
So the announcement walked one step ahead of the code. Not by much. Just enough that the tweet and the artifact disagree.
Here is the short version. Your app becomes a local MCP server, and every annotated Kotlin function becomes a tool an agent can call.
Not a remote server. No network hop. The function runs inside your app, on the phone, in your own process, against your own local state.
Which sounds great until you ask who is allowed to call it, and what they read when they decide.
i spent an evening on this and came out more interested than i expected. Also more annoyed. Both things are true.
What actually ships
Four steps. Your app declares functions. The Jetpack annotation processor generates an XML schema listing them. The OS indexes that schema. An agent reads the metadata, picks a function, and runs it with arguments.
The declaration is one annotation:
@AppFunction(isDescribedByKDoc = true)
suspend fun createTask(
title: String,
dueDateTime: LocalDateTime? = null,
location: String? = null,
): Task
That is close to the whole developer experience. One annotation, one doc comment, and the OS knows your app can create a task.
The gate is a permission. Any caller needs android.permission.EXECUTE_APP_FUNCTIONS to discover your functions at all. The device floor is Android 16.
And the flag in that annotation is the part i cannot stop thinking about.
Your comments became prompts
isDescribedByKDoc = true means the doc comment above your function is what the agent reads when it picks a tool.
Sit with that.
For years a KDoc comment was a courtesy. You wrote it for the next developer, or for the docs site, or for nobody. Now it is the thing standing between your function being called correctly and being called with nonsense arguments.
the docstring stopped being documentation. it became the interface.
i have written "Creates a task" a hundred times. That sentence is a bad tool description. It says nothing about when to use the function, what it needs, or what it refuses to do.
Google's own sample does it properly. The note service throws AppFunctionInvalidArgumentException when neither a title nor content is passed. It throws AppFunctionElementNotFoundException when the record is missing. The agent gets a reason instead of silence.
That is more care than most apps put into their error messages. And it is now load-bearing.
The floor is the real problem
AppFunctions needs compileSdk 36 and a device on Android 16 or later. The adb commands for listing and running functions need Android 17.
Your users are not there. Most of them are two or three versions back, on phones that will never see this API. i checked the install numbers out of habit and closed the tab.
Here is the split that keeps getting flattened into "every app is an MCP server":
| AppFunctions | Remote MCP server | |
|---|---|---|
| Runs on | the phone, inside your app | your infrastructure |
| Reach | Android 16 and up | any platform |
| Discovery | OS registry | MCP tool listing |
| Auth | EXECUTE_APP_FUNCTIONS |
your own scopes |
These are not rivals. One is local state, the other is a service you run.
But only one of them works on the phone in your pocket right now.
The thing people already built
The hype reads like Google invented this. The pattern existed before the OS version did.
There is an open source project called Android-MCP that bridges agents to a phone over ADB and the accessibility API. It taps, swipes, types, and reads the view hierarchy. It works on Android 10 and up, which is most of the planet.
The catch is the number in its own README. Two to five seconds between two taps, depending on the device.
That is the whole argument for AppFunctions in one line. Tapping through a screen is slow, fragile, and depends on your UI not moving. Calling a function is fast and does not care what your layout looks like.
But the old way works on the phone you have. The new way works on the phone you will have.
The line that did not make the tweet
The Gemini integration is a private preview with trusted testers. You request access through an Early Access Program form. Google states that registering does not guarantee access.
So you can ship AppFunctions that nothing on the device is able to call.
There is one public example. Samsung Gallery on the Galaxy S26, where you ask Gemini for photos of your cat and it pulls them from the gallery. Gemini is also wired into Calendar, Notes, and Tasks. That is the list. No numbers on apps, no numbers on users.
Then there is the fallback, which is the detail that actually got under my skin. Apps that never add AppFunctions can still be driven by a UI automation layer that taps through their screens.
So agent reach is not opt-in. Only the clean version is.
Off topic for a second. i keep a notes app i wrote for myself, maybe four hundred lines, no sync, no accounts. Last month i tried to give it a tool interface so my own agent could add notes while i work.
i got stuck for an hour, and not on the code. On the description. "add note" was too vague. "add note with title and body" was better. "add note, use when the user wants to capture a thought, do not use for tasks" was the version that finally worked.
Four hundred lines of my own code, and i could not describe it to a machine that reads my comments for a living. Weird feeling. Like finding out you never actually knew your own app.
The real talk
Most Android apps should not touch this yet.
If you ship to consumers, your install base is on Android 13 and 14. You cannot use the API, and the assistant that calls it sits behind a form. Writing functions now is a learning exercise, not a product decision.
If your app is a small utility with three obvious actions, sure, try it. The annotation is cheap and the schema is generated for you. Worst case you learn what a good tool description looks like.
But do not restructure your app around function signatures that the docs still call experimental. Do not rename your domain models because an agent might like the shape better. The surface can change, and Google has said so in writing on the same page it announced a beta.
The biggest misconception is the headline itself. "Every Android app is an MCP server" does not mean every agent can call your app. It means your app can describe itself to a registry, and a caller with the right permission, on the right OS version, approved by Google, can read that description.
That is a narrower sentence. It is also the true one.
What i would actually do
Pick two workflows. Not ten.
A reminder with a due time. A search across your own data. Something a user would phrase in one sentence and expect to work.
Write the KDoc like a product spec, not a comment. Say when to use it and when not to. Then run adb shell cmd app_function list-app-functions and confirm the OS actually sees it.
If nothing can call it yet, that is expected. Ship the description and wait.
i still think about that KDoc flag. Somewhere a team is shipping a feature and the most important code they wrote was a comment above a function.
Two years from now, "write good tool descriptions" might be a line on a job post.
What would you write above your app's best feature, in one sentence, for something that has never seen your UI?
Top comments (2)
One question on your closing line: for the long tail of apps that will never annotate a single function, do you read the permission gate as Google wanting agents off the UI entirely, or only preferring functions where they exist?
To your question, I'd write the outcome plus the boundary, e.g. "Creates a reminder for a given time; never edits or deletes existing ones." The agent learns as much from what a tool won't do.
(Disclosure: I'm with the Auten team. We drive apps through the screen, Android is in beta, so this matters a lot to us.)
The 'the docstring stopped being documentation. it became the interface' is the most important line in this article. We've spent years treating comments as an afterthought, and now they're load-bearing. I wonder how many teams will actually rewrite their KDoc for agent consumption, or just ship the vague version and hope.