Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0d9e2c0
Update sbt-mdoc to 2.9.2 (#256)
softwaremill-ci Sep 7, 2026
aaed0a8
Update slf4j-api to 2.0.19 (#257)
softwaremill-ci Sep 8, 2026
a4ad7b7
Update zio-http to 3.11.5 (#261)
softwaremill-ci Sep 15, 2026
1458072
Add serverSecurityLogic (#259)
max-peroch Sep 15, 2026
55e4dc3
Commit messages structure for agents (#264)
kubinio123 Sep 15, 2026
1bd5134
Update zio-process to 0.8.1 (#262)
softwaremill-ci Sep 16, 2026
6083984
Use -Yfuture-lazy-vals (#267)
adamw Sep 17, 2026
de91b33
Update zio-http to 3.11.6 (#269)
softwaremill-ci Sep 18, 2026
42ab72e
Update ox:core to 1.0.7 (#268)
softwaremill-ci Sep 19, 2026
5c3a58d
Add secure prompts and resources (#266)
max-peroch Sep 22, 2026
86fd286
Release 0.6.0
kubinio123 Sep 22, 2026
62a75b9
Update slf4j-api to 2.0.20 (#277)
softwaremill-ci Sep 26, 2026
3ff7c1b
Update ox:core to 1.0.8 (#278)
softwaremill-ci Sep 27, 2026
030892b
Update logback-classic to 1.6.4 (#279)
softwaremill-ci Sep 28, 2026
662933c
Update pekko-http-backend, zio to 4.0.27 (#280)
softwaremill-ci Sep 29, 2026
ad8e5cb
Introducing sbt 2.0.9 (#272)
pierscin Sep 29, 2026
8ad778a
Update tapir-apispec-docs, tapir-core, ... to 1.13.32 (#281)
softwaremill-ci Oct 1, 2026
8a493de
Update ox:core to 1.0.9 (#284)
softwaremill-ci Oct 5, 2026
92bcdd9
Update logback-classic to 1.6.5 (#282)
softwaremill-ci Oct 5, 2026
4e8c875
Update sbt to 2.0.10 (#285)
softwaremill-ci Oct 6, 2026
fd65fc2
Update sbt to 2.0.10 (#286)
pierscin Oct 6, 2026
eb09ab0
Update pekko-actor-typed, pekko-stream to 1.7.1 (#288)
softwaremill-ci Oct 8, 2026
da76f27
Update circe-core, circe-generic, ... to 0.14.17 (#290)
softwaremill-ci Oct 10, 2026
07661b4
Update tapir-apispec-docs, tapir-core, ... to 1.13.33 (#291)
softwaremill-ci Oct 11, 2026
a96d8c4
Migrate to Scala 3.9.0 LTS (#287)
pierscin Oct 12, 2026
ad45de5
Update sbt-softwaremill-common, ... to 3.0.2 (#292)
softwaremill-ci Oct 14, 2026
84ef940
Merge master into 2026-07-28-protocol-support
kubinio123 Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .claude/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
name: commit
description: Write commit messages for the chimp project. Use when drafting or suggesting a git commit message.
---

# Commit Message Structure

Use Conventional Commits prefixes:

- `feat:` - a new feature
- `fix:` - a bug fix
- `docs:` - documentation only
- `test:` - test changes only
- `refactor:` - code change with no behaviour change
- `chore:` - build, tooling, or dependency changes
- `perf:` - a performance improvement

Rules:

- Subject line: prefix + short description. Max 40 characters.
- Describe what the change does, not why.
- Body lines: max 70 characters each. Wrap long lines.
- Keep the body short. Add it only if the subject is not enough.
4 changes: 2 additions & 2 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ RUN apt-get update && \
rm -rf /var/lib/apt/lists/*

# Install sbt
RUN curl -fL "https://github.com/sbt/sbt/releases/download/v1.12.0/sbt-1.12.0.tgz" | tar xz -C /tmp && \
RUN curl -fL "https://github.com/sbt/sbt/releases/download/v2.0.10/sbt-2.0.10.tgz" | tar xz -C /tmp && \
mv /tmp/sbt/bin/sbt /usr/local/bin/ && \
mv /tmp/sbt/bin/sbt-launch.jar /usr/local/bin/ && \
chmod +x /usr/local/bin/sbt && \
rm -rf /tmp/sbt

ENV DEVCONTAINER=true
ENV DEVCONTAINER=true
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
distribution: 'temurin'
java-version: 21
cache: 'sbt'
- uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1, specifically v1.1.14
- uses: sbt/setup-sbt@ce95da69b39609ea153bad087708da5f37366897 # v1, specifically v1.5.10
- name: Set up Node
uses: actions/setup-node@v4
with:
Expand All @@ -45,7 +45,7 @@ jobs:
- name: Compile documentation
run: sbt -v compileDocs
- name: Unit tests
run: sbt -v test
run: sbt -v testFull
- name: Client conformance tests (2025-11-25)
run: sbt -v "clientConformance/conformance client --requirements 2025-11-25"
- name: Client conformance tests (2026-07-28)
Expand All @@ -55,7 +55,7 @@ jobs:
- name: Server conformance tests (2026-07-28)
run: sbt -v "serverConformance/conformance server --requirements 2026-07-28"
- name: Integration tests
run: sbt -v "testOnly -- -n Integration"
run: sbt -v "testOnly * -- -n Integration"
- uses: actions/upload-artifact@v5
if: success() || failure()
with:
Expand All @@ -80,4 +80,4 @@ jobs:
if: github.event.pull_request.user.login == 'softwaremill-ci'
needs: [ build, label ]
uses: softwaremill/github-actions-workflows/.github/workflows/auto-merge.yml@main
secrets: inherit
secrets: inherit
2 changes: 1 addition & 1 deletion .scala-steward.conf
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
updates.pin = [
{ groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.3." }
{ groupId = "org.scala-lang", artifactId = "scala3-library", version = "3.9." }
]
7 changes: 6 additions & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
version = 3.11.5
maxColumn = 140
rewrite.rules = [RedundantBraces, RedundantParens, SortImports]
runner.dialect = scala3
runner.dialect = scala3
fileOverride {
"glob:**/*.sbt" {
runner.dialect = scala3
}
}
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ ALWAYS use ASD-STE100 Simplified Technical English for documentation, responses
### 6 - Code comments

NEVER add any comments in the code, unless you're asked to do so.

### 7 - Commits

Use `/commit` skill to keep the common style of commit messages.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ the MCP protocol with bidirectional communication between server and client. Cur
Run a basic MCP server with Netty exposing a simple adder tool:

```scala
//> using dep com.softwaremill.chimp::chimp-server:0.5.2
//> using dep com.softwaremill.chimp::chimp-server:0.6.0
//> using dep com.softwaremill.sttp.tapir::tapir-netty-server-sync:1.13.19

import chimp.server.*
Expand All @@ -39,7 +39,7 @@ case class AdderInput(a: Int, b: Int) derives Codec, Schema
Connect and invoke the tool as an MCP client:

```scala
//> using dep com.softwaremill.chimp::chimp-client:0.5.2
//> using dep com.softwaremill.chimp::chimp-client:0.6.0
//> using dep com.softwaremill.sttp.client4::core:4.0.24

import chimp.client.*
Expand All @@ -65,7 +65,7 @@ import io.circe.Json
Run a basic MCP server using stdio transport:

```scala
//> using dep com.softwaremill.chimp::chimp-server:0.5.2
//> using dep com.softwaremill.chimp::chimp-server:0.6.0

import chimp.server.*
import chimp.server.transport.ServerStdioTransport
Expand All @@ -84,7 +84,7 @@ case class EchoInput(message: String) derives Codec, Schema
Start the server as a subprocess and invoke the tool as an MCP client:

```scala
//> using dep com.softwaremill.chimp::chimp-client:0.5.2
//> using dep com.softwaremill.chimp::chimp-client:0.6.0

import chimp.client.*
import chimp.client.transport.ClientStdioTransport
Expand All @@ -107,7 +107,7 @@ With the integration modules (like `chimp-server-ox` and `chimp-client-ox` for o
For example, run a basic streaming MCP server using Netty and ox:

```scala
//> using dep com.softwaremill.chimp::chimp-server-ox:0.5.2
//> using dep com.softwaremill.chimp::chimp-server-ox:0.6.0

import chimp.protocol.LoggingLevel
import chimp.server.*
Expand Down Expand Up @@ -136,7 +136,7 @@ case class WorkInput(steps: Int) derives Codec, Schema
Connect and invoke the tool as an MCP client, receiving server's notifications while the tool call is in flight:

```scala
//> using dep com.softwaremill.chimp::chimp-client-ox:0.5.2
//> using dep com.softwaremill.chimp::chimp-client-ox:0.6.0

import chimp.client.McpClient
import chimp.client.notifications.ServerNotification
Expand Down
87 changes: 36 additions & 51 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,40 @@ import com.softwaremill.SbtSoftwareMillCommon.commonSmlBuildSettings
import com.softwaremill.UpdateVersionInDocs

val scalaTestV = "3.2.20"
val circeV = "0.14.16"
val slf4jV = "2.0.18"
val logbackV = "1.6.3"
val tapirV = "1.13.31"
val sttpClientV = "4.0.26"
val circeV = "0.14.17"
val slf4jV = "2.0.20"
val logbackV = "1.6.5"
val tapirV = "1.13.33"
val sttpClientV = "4.0.27"
val zioV = "2.1.26"
val zioProcessV = "0.8.0"
val zioHttpV = "3.11.4"
val oxV = "1.0.6"
val zioProcessV = "0.8.1"
val zioHttpV = "3.11.6"
val oxV = "1.0.9"
val testcontainersScalaV = "0.41.8"
val pekkoV = "1.7.0"
val pekkoV = "1.7.1"
val conformanceHarnessV = "0.2.0-alpha.11"

lazy val verifyExamplesCompileUsingScalaCli = taskKey[Unit]("Verify that each example compiles using Scala CLI")
lazy val verifyExamplesCompileUsingScalaCli: TaskKey[Unit] = taskKey[Unit]("Verify that each example compiles using Scala CLI")
lazy val compileDocs: TaskKey[Unit] = taskKey[Unit]("Compiles docs module throwing away its output")

lazy val commonSettings = commonSmlBuildSettings ++ ossPublishSettings ++ Seq(
organization := "com.softwaremill.chimp",
scalaVersion := "3.3.7",
Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.Assertion:s",
Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.compatible.Assertion:s",
Test / test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-l", "Integration"),
Test / parallelExecution := false,
scalacOptions ++= Seq("-Wunused:all", "-Werror")
)
commonSmlBuildSettings
ossPublishSettings

organization := "com.softwaremill.chimp"
scalaVersion := "3.9.0"
Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.Assertion:s"
Test / scalacOptions += "-Wconf:msg=unused value of type org.scalatest.compatible.Assertion:s"
Test / test / testOptions += Tests.Argument(TestFrameworks.ScalaTest, "-l", "Integration")
Test / parallelExecution := false
scalacOptions ++= Seq("-Wunused:all", "-Werror", "-java-output-version", "17")

val scalaTest = "org.scalatest" %% "scalatest" % scalaTestV % Test

lazy val root = (project in file("."))
.settings(commonSettings: _*)
.settings(
publishArtifact := false,
name := "chimp",
updateDocs := Def.taskDyn {
updateDocs := Def.uncached(Def.taskDyn {
val log = sLog.value
val org = organization.value
val releaseVersion = version.value
Expand All @@ -46,7 +47,8 @@ lazy val root = (project in file("."))
(docs / mdoc).toTask("").value
files ++ Seq(file("generated-docs/out"))
}
}.value
}.value),
compileDocs := (docs / mdoc).toTask(" --out target/chimp-docs").value
)
.aggregate(
core,
Expand All @@ -66,7 +68,6 @@ lazy val root = (project in file("."))
val conformance = inputKey[Unit]("Run the MCP conformance harness via npx, extra args are passed through")

lazy val core: Project = (project in file("core"))
.settings(commonSettings: _*)
.settings(
name := "chimp-core",
libraryDependencies ++= Seq(
Expand All @@ -80,7 +81,6 @@ lazy val core: Project = (project in file("core"))
)

lazy val server: Project = (project in file("server"))
.settings(commonSettings: _*)
.settings(
name := "chimp-server",
libraryDependencies ++= Seq(
Expand All @@ -96,7 +96,6 @@ lazy val server: Project = (project in file("server"))
.dependsOn(core, client % "test->compile")

lazy val serverZio: Project = (project in file("server-streaming/server-zio"))
.settings(commonSettings: _*)
.settings(
name := "chimp-server-zio",
libraryDependencies ++= Seq(
Expand All @@ -111,7 +110,6 @@ lazy val serverZio: Project = (project in file("server-streaming/server-zio"))
.dependsOn(server % "compile->compile;test->test", clientZio % "test->compile")

lazy val serverOx: Project = (project in file("server-streaming/server-ox"))
.settings(commonSettings: _*)
.settings(
name := "chimp-server-ox",
libraryDependencies ++= Seq(
Expand All @@ -123,7 +121,6 @@ lazy val serverOx: Project = (project in file("server-streaming/server-ox"))
.dependsOn(server % "compile->compile;test->test", clientOx % "test->compile")

lazy val serverPekko: Project = (project in file("server-streaming/server-pekko"))
.settings(commonSettings: _*)
.settings(
name := "chimp-server-pekko",
libraryDependencies ++= Seq(
Expand All @@ -135,7 +132,6 @@ lazy val serverPekko: Project = (project in file("server-streaming/server-pekko"
.dependsOn(server % "compile->compile;test->test", clientPekko % "test->compile")

lazy val client: Project = (project in file("client"))
.settings(commonSettings: _*)
.settings(
name := "chimp-client",
libraryDependencies ++= Seq(
Expand All @@ -149,7 +145,6 @@ lazy val client: Project = (project in file("client"))
.dependsOn(core)

lazy val clientZio: Project = (project in file("client-streaming/client-zio"))
.settings(commonSettings: _*)
.settings(
name := "chimp-client-zio",
libraryDependencies ++= Seq(
Expand All @@ -163,7 +158,6 @@ lazy val clientZio: Project = (project in file("client-streaming/client-zio"))
.dependsOn(client % "compile->compile;test->test")

lazy val clientOx: Project = (project in file("client-streaming/client-ox"))
.settings(commonSettings: _*)
.settings(
name := "chimp-client-ox",
libraryDependencies ++= Seq(
Expand All @@ -175,7 +169,6 @@ lazy val clientOx: Project = (project in file("client-streaming/client-ox"))
.dependsOn(client % "compile->compile;test->test")

lazy val clientPekko: Project = (project in file("client-streaming/client-pekko"))
.settings(commonSettings: _*)
.settings(
name := "chimp-client-pekko",
libraryDependencies ++= Seq(
Expand All @@ -188,7 +181,6 @@ lazy val clientPekko: Project = (project in file("client-streaming/client-pekko"
.dependsOn(client % "compile->compile;test->test")

lazy val examples = (project in file("examples"))
.settings(commonSettings: _*)
.settings(
publishArtifact := false,
name := "examples",
Expand All @@ -198,30 +190,29 @@ lazy val examples = (project in file("examples"))
"com.softwaremill.sttp.tapir" %% "tapir-zio-http-server" % tapirV,
"ch.qos.logback" % "logback-classic" % logbackV
),
verifyExamplesCompileUsingScalaCli := VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value)
verifyExamplesCompileUsingScalaCli := Def.uncached(VerifyExamplesCompileUsingScalaCli(sLog.value, sourceDirectory.value))
)
.dependsOn(server, serverOx, client, clientOx)

import sbtassembly.AssemblyPlugin.autoImport.*

lazy val assemblySettings = Seq(
assembly / assemblyMergeStrategy := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", "INDEX.LIST") => MergeStrategy.discard
case PathList("META-INF", "DEPENDENCIES") => MergeStrategy.discard
case PathList("META-INF", "services", _ @_*) => MergeStrategy.concat
case PathList("META-INF", xs @ _*) if xs.lastOption.exists(s => s.endsWith(".SF") || s.endsWith(".DSA") || s.endsWith(".RSA")) =>
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case PathList("META-INF", "INDEX.LIST") => MergeStrategy.discard
case PathList("META-INF", "DEPENDENCIES") => MergeStrategy.discard
case PathList("META-INF", "services", _*) => MergeStrategy.concat
case PathList("META-INF", xs*) if xs.lastOption.exists(s => s.endsWith(".SF") || s.endsWith(".DSA") || s.endsWith(".RSA")) =>
MergeStrategy.discard
case PathList("META-INF", _ @_*) => MergeStrategy.first
case PathList("META-INF", _*) => MergeStrategy.first
case PathList("module-info.class") => MergeStrategy.discard
case _ => MergeStrategy.first
}
)

lazy val serverConformance = (project in file("server-conformance"))
.enablePlugins(AssemblyPlugin)
.settings(commonSettings: _*)
.settings(assemblySettings: _*)
.settings(assemblySettings*)
.settings(
publishArtifact := false,
name := "server-conformance",
Expand All @@ -236,7 +227,7 @@ lazy val serverConformance = (project in file("server-conformance"))

import scala.sys.process.*
val args = spaceDelimited("<args>").parsed.toList
val jar = assembly.value
val jar = fileConverter.value.toPath(assembly.value).toFile
val rootDir = (LocalRootProject / baseDirectory).value
val specVersion = args
.sliding(2)
Expand Down Expand Up @@ -270,7 +261,7 @@ lazy val serverConformance = (project in file("server-conformance"))
more = reader.readLine()
}
} catch {
case t: Throwable => urlPromise.tryFailure(t)
case t: Throwable => urlPromise.tryFailure(t): Unit
}
})
readerThread.setDaemon(true)
Expand Down Expand Up @@ -308,8 +299,7 @@ lazy val serverConformance = (project in file("server-conformance"))

lazy val clientConformance = (project in file("client-conformance"))
.enablePlugins(AssemblyPlugin)
.settings(commonSettings: _*)
.settings(assemblySettings: _*)
.settings(assemblySettings*)
.settings(
publishArtifact := false,
name := "client-conformance",
Expand All @@ -323,7 +313,7 @@ lazy val clientConformance = (project in file("client-conformance"))

import scala.sys.process.*
val args = spaceDelimited("<args>").parsed.toList
val jar = assembly.value
val jar = fileConverter.value.toPath(assembly.value).toFile
val baseDir = baseDirectory.value
val rootDir = (LocalRootProject / baseDirectory).value
val wrapper = (baseDir / "bin" / "chimp-conformance-client").getAbsolutePath
Expand All @@ -350,13 +340,8 @@ lazy val clientConformance = (project in file("client-conformance"))
)
.dependsOn(clientOx)

val compileDocs: TaskKey[Unit] = taskKey[Unit]("Compiles docs module throwing away its output")
compileDocs :=
(docs / mdoc).toTask(" --out target/chimp-docs").value

lazy val docs: Project = (project in file("generated-docs"))
.enablePlugins(MdocPlugin)
.settings(commonSettings)
.settings(
mdocIn := file("docs"),
moduleName := "chimp-docs",
Expand Down
Loading
Loading