Skip to content

Commit b370494

Browse files
ochafikclaude
andcommitted
refactor(kotlin): convert SDK to Android library and move WebViewTransport
- Convert Kotlin SDK from pure JVM to Android library to match Swift SDK structure - Move WebViewTransport.kt from example to SDK transport folder - Update package from com.example.mcpappshost to io.modelcontextprotocol.apps.transport - Update Gradle to 8.10.2 and Android Gradle Plugin to 8.7.3 - Add proguard and consumer rules for serialization - Fix lint compatibility issues with Kotlin 2.1 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 16ad0cd commit b370494

11 files changed

Lines changed: 135 additions & 23 deletions

File tree

examples/basic-host-kotlin/build.gradle.kts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
plugins {
2-
id("com.android.application") version "8.2.0"
2+
id("com.android.application") version "8.7.3"
33
kotlin("android") version "2.1.0"
44
kotlin("plugin.serialization") version "2.1.0"
55
kotlin("plugin.compose") version "2.1.0"
@@ -30,18 +30,25 @@ android {
3030
}
3131

3232
compileOptions {
33-
sourceCompatibility = JavaVersion.VERSION_17
34-
targetCompatibility = JavaVersion.VERSION_17
33+
sourceCompatibility = JavaVersion.VERSION_21
34+
targetCompatibility = JavaVersion.VERSION_21
3535
}
3636

3737
kotlinOptions {
38-
jvmTarget = "17"
38+
jvmTarget = "21"
3939
}
4040

4141
buildFeatures {
4242
compose = true
4343
}
4444

45+
lint {
46+
// Workaround for kotlinx-metadata version mismatch with Kotlin 2.1
47+
disable += setOf(
48+
"FlowOperatorInvokedInComposition",
49+
"StateFlowValueCalledInComposition"
50+
)
51+
}
4552

4653
packaging {
4754
resources {

examples/basic-host-kotlin/gradle.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
# The setting is particularly useful for tweaking memory settings.
1111
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
1212

13+
# Java home
14+
org.gradle.java.home=/opt/homebrew/opt/openjdk@21
15+
1316
# When configured, Gradle will run in incubating parallel mode.
1417
# This option should only be used with decoupled projects. More details, visit
1518
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects

examples/basic-host-kotlin/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

examples/basic-host-kotlin/src/main/kotlin/com/example/mcpappshost/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import androidx.compose.ui.viewinterop.AndroidView
3131
import androidx.lifecycle.Lifecycle
3232
import androidx.lifecycle.LifecycleEventObserver
3333
import androidx.lifecycle.viewmodel.compose.viewModel
34+
import io.modelcontextprotocol.apps.transport.injectBridgeScript
3435
import kotlinx.serialization.json.jsonArray
3536
import kotlinx.serialization.json.jsonObject
3637
import kotlinx.serialization.json.jsonPrimitive

kotlin/build.gradle.kts

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,48 @@
11
plugins {
2-
kotlin("jvm") version "2.1.0"
2+
id("com.android.library") version "8.7.3"
3+
kotlin("android") version "2.1.0"
34
kotlin("plugin.serialization") version "2.1.0"
45
id("maven-publish")
56
}
67

78
group = "io.modelcontextprotocol"
89
version = "0.1.0-SNAPSHOT"
910

10-
repositories {
11-
mavenCentral()
12-
google()
13-
}
11+
android {
12+
namespace = "io.modelcontextprotocol.apps"
13+
compileSdk = 34
1414

15-
// Target Java 21 (Kotlin doesn't support 25 yet)
16-
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
17-
kotlinOptions.jvmTarget = "21"
18-
}
15+
defaultConfig {
16+
minSdk = 26 // Android 8.0 - required for WebView features
17+
18+
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
19+
consumerProguardFiles("consumer-rules.pro")
20+
}
21+
22+
buildTypes {
23+
release {
24+
isMinifyEnabled = false
25+
proguardFiles(
26+
getDefaultProguardFile("proguard-android-optimize.txt"),
27+
"proguard-rules.pro"
28+
)
29+
}
30+
}
1931

20-
tasks.withType<JavaCompile> {
21-
sourceCompatibility = "21"
22-
targetCompatibility = "21"
32+
compileOptions {
33+
sourceCompatibility = JavaVersion.VERSION_21
34+
targetCompatibility = JavaVersion.VERSION_21
35+
}
36+
37+
kotlinOptions {
38+
jvmTarget = "21"
39+
}
40+
41+
publishing {
42+
singleVariant("release") {
43+
withSourcesJar()
44+
}
45+
}
2346
}
2447

2548
dependencies {
@@ -31,13 +54,29 @@ dependencies {
3154

3255
// Coroutines
3356
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0")
57+
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
58+
59+
// AndroidX Core (for Handler, etc.)
60+
implementation("androidx.core:core-ktx:1.12.0")
3461

3562
// Testing
3663
testImplementation(kotlin("test"))
3764
testImplementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.9.0")
3865
testImplementation("org.junit.jupiter:junit-jupiter:5.10.0")
66+
67+
androidTestImplementation("androidx.test.ext:junit:1.1.5")
68+
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
3969
}
4070

41-
tasks.test {
42-
useJUnitPlatform()
71+
afterEvaluate {
72+
publishing {
73+
publications {
74+
create<MavenPublication>("release") {
75+
from(components["release"])
76+
groupId = "io.modelcontextprotocol"
77+
artifactId = "mcp-apps-kotlin-sdk"
78+
version = project.version.toString()
79+
}
80+
}
81+
}
4382
}

kotlin/consumer-rules.pro

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Keep JSON serialization classes
2+
-keepattributes *Annotation*, InnerClasses
3+
-dontnote kotlinx.serialization.AnnotationsKt
4+
5+
-keepclassmembers class kotlinx.serialization.json.** {
6+
*** Companion;
7+
}
8+
-keepclasseswithmembers class kotlinx.serialization.json.** {
9+
kotlinx.serialization.KSerializer serializer(...);
10+
}
11+
12+
# Keep MCP Apps SDK classes
13+
-keep,includedescriptorclasses class io.modelcontextprotocol.apps.**$$serializer { *; }
14+
-keepclassmembers class io.modelcontextprotocol.apps.** {
15+
*** Companion;
16+
}
17+
-keepclasseswithmembers class io.modelcontextprotocol.apps.** {
18+
kotlinx.serialization.KSerializer serializer(...);
19+
}

kotlin/gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
kotlin.code.style=official
22
kotlin.mpp.stability.nowarn=true
3+
org.gradle.java.home=/opt/homebrew/opt/openjdk@21
4+
android.useAndroidX=true

kotlin/gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
44
networkTimeout=10000
55
validateDistributionUrl=true
66
zipStoreBase=GRADLE_USER_HOME

kotlin/proguard-rules.pro

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# ProGuard rules for MCP Apps SDK
2+
# Add project specific ProGuard rules here.

kotlin/settings.gradle.kts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,17 @@
1+
pluginManagement {
2+
repositories {
3+
google()
4+
mavenCentral()
5+
gradlePluginPortal()
6+
}
7+
}
8+
9+
dependencyResolutionManagement {
10+
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
11+
repositories {
12+
google()
13+
mavenCentral()
14+
}
15+
}
16+
117
rootProject.name = "mcp-apps-sdk"

0 commit comments

Comments
 (0)