> ## Documentation Index
> Fetch the complete documentation index at: https://docs.metabind.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Android SDK

> Embed a governed agent in your Android app with the Assistant SDK's drop-in chat surface and Jetpack Compose rendering of tool results

The Android Assistant SDK puts a governed agent inside your own app: a streaming client to Metabind's Agent proxy, an MCP client for your project's tools, and rendering of Interactive Tool results as real native Jetpack Compose — not web views — through BindJS. Use the drop-in `MetabindAssistantView` for a complete chat surface, or build your own with the lower-level APIs.

<CardGroup cols={2}>
  <Card title="SDK on GitHub" icon="github" href="https://github.com/metabindai/metabind-android">
    `metabind-android` — the Android SDK. The Assistant SDK is the `:metabindai` module.
  </Card>

  <Card title="Demo app" icon="github" href="https://github.com/metabindai/metabind-android/tree/main/samples/assistant-demo">
    `samples/assistant-demo` — a complete Compose chat app built on `MetabindAssistantView`.
  </Card>
</CardGroup>

## Requirements

| Requirement | Version |
| - | - |
| Android | 8.0 (API 26) or later |
| UI toolkit | Jetpack Compose |
| Gradle | 9.x, Android Gradle Plugin 9.0 or later |
| JDK | 21 |

## Installation

Add the Assistant SDK dependency, which pulls in the MCP client (`ai.metabind:mcpappshost-android`) and the BindJS renderer (`ai.metabind:bindjs-android`) transitively:

<Tabs>
  <Tab title="build.gradle.kts">
    ```kotlin theme={null}
    dependencies {
        implementation("ai.metabind:metabindai-android:0.2.12")
    }
    ```
  </Tab>

  <Tab title="build.gradle">
    ```groovy theme={null}
    dependencies {
        implementation 'ai.metabind:metabindai-android:0.2.12'
    }
    ```
  </Tab>
</Tabs>

See the [repository README](https://github.com/metabindai/metabind-android#installation) for the Maven repository configuration.

## What you configure

* A **Metabind API key**, sent as a `Bearer` token to both the Agent proxy and the MCP server.
* Your project's **`orgId`** and **`projectId`**: the internal IDs, not the slugs, because the Agent proxy accepts only IDs. The SDK derives your project's MCP server URL from these. To look them up, see [Find your organization and project IDs](/guides/getting-started/embed-an-assistant#find-your-organization-and-project-ids).
* Optionally, the **`agentHost`** and **`mcpHost`** constructor parameters, which default to `https://agent.metabind.ai` and `https://mcp.metabind.ai`.

## Drop in the chat surface

The SDK ships `MetabindAssistantView`, a complete chat UI:

```kotlin theme={null}
import ai.metabind.ai.MetabindAssistant
import ai.metabind.ai.MetabindAssistantView

@Composable
fun AssistantScreen() {
    val assistant = remember {
        MetabindAssistant(
            apiKey = apiKey,
            orgId = orgId,
            projectId = projectId
        )
    }

    MetabindAssistantView(assistant = assistant)
}
```

`MetabindAssistantView` handles message bubbles, streaming indicators, tool rendering, input, and auto-scrolling. It follows your app's Material3 theme.

<Note>
  Retain the `MetabindAssistant` instance at an appropriate scope — inside a ViewModel, for example — and call `close()` when you discard it.
</Note>

### MetabindAssistant

`MetabindAssistant` manages the conversation. For custom UIs, observe its state directly:

| Property | Type | Description |
| - | - | - |
| `messages` | `StateFlow<List<ChatMessage>>` | Conversation history |
| `isLoading` | `StateFlow<Boolean>` | True while streaming |
| `error` | `StateFlow<String?>` | Error message, if any |
| `toolUIContent` | `StateFlow<Map<String, ToolUIContent>>` | Tool UI payloads by call ID |

| Method | Description |
| - | - |
| `send(text)` | Send a user message |
| `cancel()` | Cancel current response |
| `reset()` | Clear conversation history and reset the agent's server-side session |
| `close()` | Release resources |

### ChatMessage

```kotlin theme={null}
data class ChatMessage(
    val id: String = UUID.randomUUID().toString(),
    val role: MessageRole,              // USER, ASSISTANT, TOOL, or ERROR
    val content: String,
    val toolName: String? = null,
    val toolStatus: ToolStatus? = null  // LOADING, COMPLETED, or ERROR
)
```

## Stream a conversation turn

`MetabindAgentProvider` calls the Agent proxy — which holds the LLM key and runs the tool loop server-side — and streams results back as a `Flow<LLMStreamEvent>`:

```kotlin theme={null}
import ai.metabind.ai.MetabindAgentProvider
import ai.metabind.mcpappshost.LLMMessage
import ai.metabind.mcpappshost.LLMStreamEvent

val provider = MetabindAgentProvider()

provider.streamMessage(
    baseUrl = "https://agent.metabind.ai",
    apiKey = apiKey,
    orgId = orgId,
    projectId = projectId,
    messages = history   // List<LLMMessage>: User / Assistant / ToolResults
).collect { event ->
    when (event) {
        is LLMStreamEvent.TextDelta     -> { /* append streaming text */ }
        is LLMStreamEvent.ToolCallStart -> { /* a tool was invoked */ }
        is LLMStreamEvent.ToolResult    -> { /* tool finished */ }
        is LLMStreamEvent.Done          -> { /* turn complete */ }
        is LLMStreamEvent.Error         -> { /* handle the error */ }
        else -> {}
    }
}
```

The Android SDK is **Agent-proxy only** — there's no bring-your-own-key Anthropic provider. See [LLM provider configuration](/guides/assistant-sdk/llm-provider-configuration) for how the proxy works.

## Discover and fetch tool UIs

Use `MCPAppsClient` to list your project's tools and fetch the UI resource for a tool that renders one:

```kotlin theme={null}
import ai.metabind.mcpappshost.MCPAppsClient
import ai.metabind.ai.ToolUIContent

val client = MCPAppsClient(
    url = mcpServerUrl,
    headers = mapOf("authorization" to "Bearer $apiKey")
)

val tools = client.listTools()

// When a tool with a UI is called, fetch and parse its resource:
val resource = client.readResource(resourceUri)
val ui = ToolUIContent.fromResource(resource, toolArguments)  // BindJS or Html
```

`MCPAppsClient` also exposes `callTool(name, arguments)` for invoking tools.

## Native rendering of tool output

If you use `MetabindAssistantView`, tool rendering is automatic.

For custom UIs, render each tool call with `MetabindToolView`, the same renderer `MetabindAssistantView` uses. It takes a `ToolUIContent`, which has two variants:

* `ToolUIContent.BindJS` — rendered as Compose through `bindjs-android`
* `ToolUIContent.Html` — rendered in a WebView

```kotlin theme={null}
import ai.metabind.ai.MetabindToolView

val toolUIContent by assistant.toolUIContent.collectAsState()

toolUIContent[message.id]?.let { content ->
    MetabindToolView(
        assistant = assistant,
        toolName = message.toolName ?: "",
        content = content,
    )
}
```

`toolUIContent` is keyed by tool call ID, the same ID as the `TOOL` message the call produced. See [`MetabindToolView.kt`](https://github.com/metabindai/metabind-android/blob/main/metabindai/src/main/java/ai/metabind/ai/MetabindToolView.kt) for the optional parameters.

## Build a custom chat UI

If `MetabindAssistantView` doesn't fit your design, build your own around `MetabindAssistant`. Observe `assistant.messages`, call `assistant.send(text)`, and render each `TOOL` message's UI by passing `assistant.toolUIContent[message.id]` to `MetabindToolView`. The [finance demo](https://github.com/metabindai/metabind-android/tree/main/samples/finance-demo) is a complete custom UI built this way, and [Custom host UI](/guides/assistant-sdk/custom-host-ui#android-example) has a short example. The [`MetabindAssistantView` source](https://github.com/metabindai/metabind-android/blob/main/metabindai/src/main/java/ai/metabind/ai/MetabindAssistantView.kt) shows the drop-in surface built on the same APIs.

## Next steps

<CardGroup cols={2}>
  <Card title="Demo app" icon="github" href="https://github.com/metabindai/metabind-android/tree/main/samples/assistant-demo">
    The reference Compose chat app, end to end.
  </Card>

  <Card title="LLM provider configuration" icon="brain" href="/guides/assistant-sdk/llm-provider-configuration">
    How the Agent proxy holds keys and runs the tool loop.
  </Card>

  <Card title="BindJS reference" icon="code" href="/bindjs/introduction">
    The component language the tool UIs are written in.
  </Card>

  <Card title="iOS SDK" icon="apple" href="/guides/assistant-sdk/ios-sdk">
    The iOS equivalent.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.