-
Notifications
You must be signed in to change notification settings - Fork 178
Proposal: DSL Builders for request types #399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@devcrocod, this looks waaaaay nicer than the current näive API!
Let's also hide requests behind API DSL methods, as curring lambda parameters, like:
@OptIn(ExperimentalMcpApi::class)
public suspend fun listTools(options: RequestOptions? = null, block: ListToolsRequestBuilder.() -> Unit) {
listTools(listToolsRequest(block), options)
}with usage:
client.listTools {
meta {
put("foo", "bar")
}
cursor = "cccccclulbkukecgbkvvlevelhvejdlitfdutevlgueh"
}❗️Let's ask our silicone friends 🤖 to create a comprehensive test suite verifying that DSL api fully translates to our standard API. Mockk tests will be sufficient.
Tests will serve as the first examples of how the new API can be utilized.
33ac9f3 to
59759ed
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces type-safe DSL builders for all MCP request types, providing a more ergonomic way to construct requests with runtime validation of required fields. The implementation includes builders for initialization, tools, prompts, resources, sampling, elicitation, completion, logging, roots, and ping requests.
Key Changes
- Adds DSL builder functions (
buildXxxRequest) and builder classes for all MCP request types - Introduces
@McpDslannotation to prevent scope leakage in nested builders - Provides base classes
RequestBuilderandPaginatedRequestBuilderfor common functionality - Implements runtime validation with helpful error messages for required fields
Reviewed Changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
McpDsl.kt |
Introduces DSL marker annotation for type-safe builders |
request.dsl.kt |
Base builder classes and request metadata builder |
capabilities.dsl.kt |
Client capabilities builder for initialize requests |
content.dsl.kt |
Media content builders (text, image, audio) |
initialize.dsl.kt |
Initialize request builder with capability configuration |
tools.dsl.kt |
Call tool and list tools request builders |
prompts.dsl.kt |
Get prompt and list prompts request builders |
resources.dsl.kt |
Resource-related request builders (list, read, subscribe, unsubscribe, templates) |
sampling.dsl.kt |
Create message request builder with conversation messages |
elicitation.dsl.kt |
Elicit request builder with schema validation |
completion.dsl.kt |
Completion request builder |
logging.dsl.kt |
Set logging level request builder |
roots.dsl.kt |
List roots request builder |
pingRequest.dsl.kt |
Ping request builder |
kotlin-sdk-core.api |
API surface changes for new public builder classes |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
kpavlov
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool-cool, let's merge it!
59759ed to
7e0d4fc
Compare
This PR introduces type-safe DSL builders for all MCP request types, making it easier to construct requests
Current Solution
All request types now have DSL builders:
Each DSL builder includes:
Design Considerations
The current naming convention (e.g., initializeRequest, callToolRequest) might be confusing since these functions don't send requests, they just build request objects.
Alternative approach: Add a build prefix to clarify intent:
initializeRequest→buildInitializeRequestcallToolRequest→buildCallToolRequestcreateMessageRequest→buildCreateMessageRequestThis would make it clearer that these are builder functions.
Currently, required fields are validated at runtime in the
build()method:Alternative approach: Use Compose UI style where required parameters are in the function signature:
Pros:
Cons: