Skip to main content
The Android Assistant SDK gives you the building blocks for an in-app AI assistant: a streaming client to Metabind’s Agent proxy, an MCP client for your project’s tools, and native Jetpack Compose rendering of tool results through BindJS. Use the drop-in MetabindAssistantView for a complete chat UI, or build your own with the lower-level APIs.

SDK on GitHub

metabind-ai-android — the Assistant SDK source.

Demo app

metabind-assistant-demo-android — a complete Compose chat app built on the SDK.

Requirements

RequirementVersion
Android8.0 (API 26) or later
UI toolkitJetpack Compose
JDK21

Installation

Add the umbrella dependency, which pulls in the MCP client (mcpappshost-android) and the BindJS renderer (bindjs-android) transitively:
dependencies {
    implementation("ai.metabind:metabind-assistant-android:0.1.6")
}
See the repository README 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 Agent proxy host (https://agent.metabind.ai) and your project’s MCP server URL (copy it from the Server tab in MCP App Studio).

Drop in the chat surface

The SDK ships MetabindAssistantView, a complete chat UI:
import ai.metabind.assistant.MetabindAssistant
import ai.metabind.assistant.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.

MetabindAssistant

MetabindAssistant manages the conversation. For custom UIs, observe its state directly:
PropertyTypeDescription
messagesStateFlow<List<ChatMessage>>Conversation history
isLoadingStateFlow<Boolean>True while streaming
errorStateFlow<String?>Error message, if any
toolUIContentStateFlow<Map<String, ToolUIContent>>Tool UI payloads by call ID
MethodDescription
send(text)Send a user message
cancel()Cancel current response
reset()Clear conversation
close()Release resources

ChatMessage

data class ChatMessage(
    val id: String,
    val role: MessageRole,       // USER, ASSISTANT, or TOOL
    val content: String,
    val toolName: String?,
    val toolStatus: ToolStatus?  // 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>:
import ai.metabind.assistant.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 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:
import ai.metabind.mcpappshost.MCPAppsClient
import ai.metabind.assistant.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, ToolUIContent has two variants:
  • ToolUIContent.BindJS — render via BindJSView from bindjs-android
  • ToolUIContent.Html — render in a WebView
See the demo app’s HomeScreen.kt for the full wiring.

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 tool UIs via assistant.toolUIContent. The demo app’s HomeScreen.kt is a complete reference.

Next steps

Demo app

The reference Compose chat app, end to end.

LLM provider configuration

How the Agent proxy holds keys and runs the tool loop.

BindJS reference

The component language the tool UIs are written in.

iOS SDK

The iOS equivalent.