modularize sdk (#208)

* Modularize SDK: migrated client and server implementations to separate modules. Removed old configuration files and reorganized the source code structure

* add support native targets and update js/wasm configurations

* Refactor sample projects: add samples as composite builds, replace hardcoded dependencies with version catalog, remove obsolete gradle wrapper files

* Update .gitignore: exclude SWE agent directories (.claude/ and .junie/)

* Refine CodeQL workflow: update Kotlin build steps to target individual modules separately instead of building all at once
This commit is contained in:
Pavel Gorgulov 2025-08-04 11:53:38 +02:00 • committed by GitHub
commit 8698b96dd2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 979 additions and 2003 deletions

16
buildSrc/build.gradle.kts Normal file
View file

@ -0,0 +1,16 @@
plugins {
`kotlin-dsl`
}
repositories {
gradlePluginPortal()
mavenCentral()
}
dependencies {
implementation(libs.kotlin.gradle)
implementation(libs.kotlin.serialization)
implementation(libs.kotlinx.atomicfu.gradle)
implementation(libs.dokka.gradle)
implementation(libs.jreleaser.gradle)
}

View file

@ -0,0 +1,7 @@
dependencyResolutionManagement {
versionCatalogs {
create("libs") {
from(files("../gradle/libs.versions.toml"))
}
}
}

View file

@ -0,0 +1,23 @@
import org.jetbrains.dokka.gradle.engine.parameters.VisibilityModifier
plugins {
id("org.jetbrains.dokka")
}
dokka {
moduleName.set("MCP Kotlin SDK - ${project.name}")
dokkaSourceSets.configureEach {
sourceLink {
localDirectory = projectDir.resolve("src")
remoteUrl("https://github.com/modelcontextprotocol/kotlin-sdk/tree/main/${project.name}/src")
remoteLineSuffix = "#L"
}
documentedVisibilities(VisibilityModifier.Public)
}
dokkaPublications.html {
outputDirectory = rootProject.layout.projectDirectory.dir("docs/${project.name}")
}
}

View file

@ -0,0 +1,73 @@
import org.jreleaser.model.Active
plugins {
id("org.jreleaser")
id("mcp.publishing")
}
jreleaser {
gitRootSearch = true
strict = true
signing {
active = Active.ALWAYS
armored = true
artifacts = true
files = true
}
deploy {
active = Active.ALWAYS
maven {
active = Active.ALWAYS
mavenCentral.create("ossrh") {
active = Active.ALWAYS
url = "https://central.sonatype.com/api/v1/publisher"
applyMavenCentralRules = false
maxRetries = 240
stagingRepository(layout.buildDirectory.dir("staging-deploy").get().asFile.path)
// workaround: https://github.com/jreleaser/jreleaser/issues/1784
afterEvaluate {
publishing.publications.forEach { publication ->
if (publication is MavenPublication) {
val pubName = publication.name
if (!pubName.contains("jvm", ignoreCase = true)
&& !pubName.contains("metadata", ignoreCase = true)
&& !pubName.contains("kotlinMultiplatform", ignoreCase = true)
) {
artifactOverride {
artifactId = when {
pubName.contains("wasm", ignoreCase = true) ->
"${project.name}-wasm-${pubName.lowercase().substringAfter("wasm")}"
else -> "${project.name}-${pubName.lowercase()}"
}
jar = false
verifyPom = false
sourceJar = false
javadocJar = false
}
}
}
}
}
}
}
release {
github {
enabled = false
skipRelease = true
skipTag = true
}
}
checksum {
individual = false
artifacts = false
files = false
}
}
}

View file

@ -0,0 +1,50 @@
@file:OptIn(ExperimentalWasmDsl::class)
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins {
kotlin("multiplatform")
kotlin("plugin.serialization")
id("org.jetbrains.kotlinx.atomicfu")
}
// Generation library versions
val generateLibVersion by tasks.registering {
val outputDir = layout.buildDirectory.dir("generated-sources/libVersion")
outputs.dir(outputDir)
doLast {
val sourceFile = outputDir.get().file("io/modelcontextprotocol/kotlin/sdk/LibVersion.kt").asFile
sourceFile.parentFile.mkdirs()
sourceFile.writeText(
"""
package io.modelcontextprotocol.kotlin.sdk
public const val LIB_VERSION: String = "${project.version}"
""".trimIndent()
)
}
}
kotlin {
jvm {
compilerOptions.jvmTarget = JvmTarget.JVM_1_8
}
macosX64(); macosArm64()
linuxX64(); linuxArm64()
mingwX64()
js { nodejs() }
wasmJs { nodejs() }
explicitApi = ExplicitApiMode.Strict
jvmToolchain(21)
sourceSets {
commonMain {
kotlin.srcDir(generateLibVersion)
}
}
}

View file

@ -0,0 +1,66 @@
plugins {
`maven-publish`
signing
}
val javadocJar by tasks.registering(Jar::class) {
archiveClassifier.set("javadoc")
}
publishing {
publications.withType<MavenPublication>().configureEach {
if (name.contains("jvm", ignoreCase = true)) {
artifact(javadocJar)
}
pom {
name = project.name
description = "Kotlin implementation of the Model Context Protocol (MCP)"
url = "https://github.com/modelcontextprotocol/kotlin-sdk"
licenses {
license {
name = "MIT License"
url = "https://github.com/modelcontextprotocol/kotlin-sdk/blob/main/LICENSE"
distribution = "repo"
}
}
developers {
developer {
id = "Anthropic"
name = "Anthropic Team"
organization = "Anthropic"
organizationUrl = "https://www.anthropic.com"
}
}
scm {
url = "https://github.com/modelcontextprotocol/kotlin-sdk"
connection = "scm:git:git://github.com/modelcontextprotocol/kotlin-sdk.git"
developerConnection = "scm:git:git@github.com:modelcontextprotocol/kotlin-sdk.git"
}
}
}
repositories {
maven {
name = "staging"
url = uri(layout.buildDirectory.dir("staging-deploy"))
}
}
}
signing {
val gpgKeyName = "GPG_SIGNING_KEY"
val gpgPassphraseName = "SIGNING_PASSPHRASE"
val signingKey = providers.environmentVariable(gpgKeyName)
.orElse(providers.gradleProperty(gpgKeyName))
val signingPassphrase = providers.environmentVariable(gpgPassphraseName)
.orElse(providers.gradleProperty(gpgPassphraseName))
if (signingKey.isPresent) {
useInMemoryPgpKeys(signingKey.get(), signingPassphrase.get())
sign(publishing.publications)
}
}