CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

tessl/maven-com-embabel-agent--embabel-agent-mcpserver

Discover and Export available Agent(s) as MCP Servers

Overview
Eval results
Files

tool-export.mddocs/api/

Tool Export API

API reference for McpToolExport interface and factory methods for converting Embabel components into MCP-compatible tool exports.

Package

com.embabel.agent.mcpserver

Interface

McpToolExport { .api }

Primary interface for tool export operations.

interface McpToolExport {
    val toolCallbacks: List<ToolCallback>

    companion object {
        fun fromToolObject(toolObject: ToolObject): McpToolExport
        fun fromToolObjects(
            toolObjects: List<ToolObject>,
            namingStrategy: StringTransformer? = null
        ): McpToolExport
        fun fromLlmReference(
            llmReference: LlmReference,
            namingStrategy: StringTransformer? = null
        ): McpToolExport
        fun fromLlmReferences(
            llmReferences: List<LlmReference>,
            namingStrategy: StringTransformer? = null
        ): McpToolExport
    }
}

Properties:

  • toolCallbacks: List<ToolCallback> - List of Spring AI ToolCallback instances ready for MCP registration

Factory Methods

fromToolObject { .api }

Create export from a single ToolObject.

fun fromToolObject(toolObject: ToolObject): McpToolExport

Parameters:

  • toolObject: ToolObject - Embabel ToolObject containing tool instances

Returns: McpToolExport with exported tool callbacks

Usage:

import com.embabel.agent.mcpserver.McpToolExport
import com.embabel.agent.api.common.ToolObject

val toolObject = ToolObject(
    objects = listOf(calculatorTool, weatherTool),
    namingStrategy = { "api_$it" }
)

val export = McpToolExport.fromToolObject(toolObject)
val callbacks = export.toolCallbacks  // List of ToolCallback

Naming Strategy:

ToolObject's namingStrategy parameter transforms tool names:

// Add prefix
ToolObject(
    objects = listOf(myTool),
    namingStrategy = { "myapp_$it" }
)

// Transform to uppercase
ToolObject(
    objects = listOf(myTool),
    namingStrategy = { it.uppercase() }
)

// No transformation
ToolObject(
    objects = listOf(myTool),
    namingStrategy = StringTransformer.IDENTITY
)

fromToolObjects { .api }

Create export from multiple ToolObjects with optional global naming strategy.

fun fromToolObjects(
    toolObjects: List<ToolObject>,
    namingStrategy: StringTransformer? = null
): McpToolExport

Parameters:

  • toolObjects: List<ToolObject> - List of ToolObject instances
  • namingStrategy: StringTransformer? - Optional global naming transformation applied after individual strategies

Returns: McpToolExport with all tools from all objects

Usage:

val apiTools = ToolObject(
    objects = listOf(getTool, postTool),
    namingStrategy = { "api_$it" }
)

val utilTools = ToolObject(
    objects = listOf(formatTool, validateTool),
    namingStrategy = { "util_$it" }
)

// Export both with global prefix
val export = McpToolExport.fromToolObjects(
    toolObjects = listOf(apiTools, utilTools),
    namingStrategy = { "v1_$it" }
)
// Results in: "v1_api_getTool", "v1_util_formatTool", etc.

Naming Strategy Composition:

Individual ToolObject strategies are applied first, then global strategy:

ToolObject(namingStrategy = { "api_$it" })  // First
↓
Global namingStrategy = { "v2_$it" }         // Second
↓
Result: "v2_api_toolName"

fromLlmReference { .api }

Create export from LlmReference with automatic prefix from reference name.

fun fromLlmReference(
    llmReference: LlmReference,
    namingStrategy: StringTransformer? = null
): McpToolExport

Parameters:

  • llmReference: LlmReference - Embabel LlmReference containing agent definitions
  • namingStrategy: StringTransformer? - Optional additional naming transformation

Returns: McpToolExport with tools from the reference

Usage:

import com.embabel.agent.api.common.LlmReference

val llmRef: LlmReference = // Obtain from Embabel framework

// Basic export (uses reference name as prefix automatically)
val export = McpToolExport.fromLlmReference(llmRef)

// With additional strategy
val export = McpToolExport.fromLlmReference(
    llmReference = llmRef,
    namingStrategy = { "v2_$it" }
)

Built-in Prefixing:

LlmReference includes its own naming strategy based on reference name:

  • Reference named "PaymentAPI" → prefix "paymentapi_"
  • Additional strategy applied after built-in prefix

fromLlmReferences { .api }

Create export from multiple LlmReferences.

fun fromLlmReferences(
    llmReferences: List<LlmReference>,
    namingStrategy: StringTransformer? = null
): McpToolExport

Parameters:

  • llmReferences: List<LlmReference> - List of LlmReference instances
  • namingStrategy: StringTransformer? - Optional global naming transformation

Returns: McpToolExport with tools from all references

Usage:

val authRef: LlmReference = // Authentication reference
val dataRef: LlmReference = // Data access reference

val export = McpToolExport.fromLlmReferences(
    llmReferences = listOf(authRef, dataRef),
    namingStrategy = { "service_$it" }
)
// Each reference gets its own prefix plus "service_"

Filtering

ToolObject Filtering { .api }

Filter tools before export using ToolObject's filter parameter:

ToolObject(
    objects: List<Any>,
    namingStrategy: StringTransformer? = null,
    filter: ((String) -> Boolean)? = null
)

Usage:

// Only tools with specific prefix
val toolObject = ToolObject(
    objects = listOf(publicTool, privateTool, internalTool),
    filter = { toolName -> toolName.startsWith("public_") }
)

// Exclude deprecated tools
val toolObject = ToolObject(
    objects = allTools,
    filter = { toolName -> !toolName.contains("deprecated") }
)

// Whitelist specific tools
val allowedTools = setOf("getTool", "postTool", "deleteTool")
val toolObject = ToolObject(
    objects = allTools,
    filter = { toolName -> toolName in allowedTools }
)

// Complex filtering
val toolObject = ToolObject(
    objects = allTools,
    filter = { toolName ->
        toolName.length <= 50 &&
        !toolName.startsWith("_") &&
        toolName.matches(Regex("[a-zA-Z0-9_]+"))
    }
)

Deduplication

Tools with identical names (after all transformations) are automatically deduplicated. Only the first occurrence is retained.

val tools1 = ToolObject(
    objects = listOf(tool1),
    namingStrategy = { "api_getData" }
)

val tools2 = ToolObject(
    objects = listOf(tool2),
    namingStrategy = { "api_getData" }  // Same name
)

val export = McpToolExport.fromToolObjects(
    toolObjects = listOf(tools1, tools2)
)
// Only one "api_getData" tool is exported

Usage with Publishers

Basic Publisher { .api }

import com.embabel.agent.mcpserver.McpExportToolCallbackPublisher
import org.springframework.stereotype.Service

@Service
class MyToolPublisher : McpExportToolCallbackPublisher {

    override val toolCallbacks: List<ToolCallback>
        get() {
            val toolObject = ToolObject(
                objects = listOf(tool1, tool2, tool3),
                namingStrategy = { "myapp_$it" }
            )
            return McpToolExport.fromToolObject(toolObject).toolCallbacks
        }

    override fun infoString(verbose: Boolean?, indent: Int): String {
        return "MyToolPublisher: ${toolCallbacks.size} tools"
    }
}

Combined Export Publisher { .api }

@Service
class CombinedPublisher : McpExportToolCallbackPublisher {

    override val toolCallbacks: List<ToolCallback>
        get() {
            // Export from ToolObject
            val toolObjectExport = McpToolExport.fromToolObject(
                ToolObject(
                    objects = listOf(customTool1, customTool2),
                    namingStrategy = { "custom_$it" }
                )
            )

            // Export from LlmReference
            val llmRefExport = McpToolExport.fromLlmReference(
                llmReference = myLlmReference,
                namingStrategy = { "llm_$it" }
            )

            // Combine all callbacks
            return toolObjectExport.toolCallbacks + llmRefExport.toolCallbacks
        }

    override fun infoString(verbose: Boolean?, indent: Int): String {
        return "CombinedPublisher: ${toolCallbacks.size} tools"
    }
}

Modular Export Publisher { .api }

@Service
class ModularPublisher : McpExportToolCallbackPublisher {

    override val toolCallbacks: List<ToolCallback>
        get() {
            val modules = mapOf(
                "auth" to authTools,
                "data" to dataTools,
                "report" to reportTools
            )

            return modules.flatMap { (moduleName, tools) ->
                McpToolExport.fromToolObject(
                    ToolObject(
                        objects = tools,
                        namingStrategy = { "${moduleName}_$it" }
                    )
                ).toolCallbacks
            }
        }

    override fun infoString(verbose: Boolean?, indent: Int): String {
        return "ModularPublisher: ${toolCallbacks.size} tools"
    }

    private val authTools = listOf(/* auth tool instances */)
    private val dataTools = listOf(/* data tool instances */)
    private val reportTools = listOf(/* report tool instances */)
}

Related Types

StringTransformer { .api }

Functional interface for name transformation.

fun interface StringTransformer {
    fun transform(input: String): String

    companion object {
        val IDENTITY: StringTransformer = StringTransformer { it }
    }
}

Usage:

// Lambda
val prefixer = StringTransformer { "api_$it" }

// Method reference
val uppercaser = StringTransformer(String::uppercase)

// Identity (no transformation)
val identity = StringTransformer.IDENTITY

// Custom implementation
class VersionTransformer(private val version: String) : StringTransformer {
    override fun transform(input: String): String {
        return "${version}_$input"
    }
}

ToolCallback { .api }

Spring AI interface for tool execution (provided by Spring AI, not this library).

interface ToolCallback {
    fun getName(): String
    fun getDescription(): String
    fun call(functionArguments: String): String
    fun getInputTypeSchema(): String?
}

Logging

All tool exports are logged at INFO level:

[INFO] McpToolExport - Exporting tool: myapp_api_getData
[INFO] McpToolExport - Exporting tool: myapp_api_postData
[INFO] McpToolExport - Exporting tool: myapp_util_formatData
[INFO] McpToolExport - Total tools exported: 3

Enable DEBUG logging for detailed information:

logging.level.com.embabel.agent.mcpserver=DEBUG

Best Practices

  1. Use Descriptive Prefixes: Choose clear namespace prefixes to avoid collisions

    namingStrategy = { "payment_api_$it" }  // Good
    namingStrategy = { "pa_$it" }           // Avoid
  2. Filter Early: Apply filters at ToolObject level for efficiency

    ToolObject(
        objects = allTools,
        filter = { !it.startsWith("_") }
    )
  3. Compose Strategies: Use multiple levels of naming for organization

    ToolObject(namingStrategy = { "api_$it" })  // Module level
    ↓
    fromToolObjects(namingStrategy = { "v2_$it" })  // Version level
    ↓
    Result: "v2_api_toolName"
  4. Handle Empty Results: Check for empty tool lists in publishers

    override val toolCallbacks: List<ToolCallback>
        get() {
            val export = McpToolExport.fromToolObject(toolObject)
            if (export.toolCallbacks.isEmpty()) {
                logger.warn("No tools exported from publisher")
            }
            return export.toolCallbacks
        }
  5. Document Naming Conventions: Comment naming strategy rationale

    /**
     * Exports API tools with "api_" prefix to avoid conflicts
     * with utility tools from other publishers.
     */
    override val toolCallbacks: List<ToolCallback>
        get() = McpToolExport.fromToolObject(
            ToolObject(
                objects = apiTools,
                namingStrategy = { "api_$it" }
            )
        ).toolCallbacks

See Also

  • Exporting Tools Guide - Comprehensive tool export examples
  • Creating Publishers Guide - Publisher implementation patterns
  • Publishers API - Publisher interfaces
  • Getting Started Guide - Initial setup
tessl i tessl/maven-com-embabel-agent--embabel-agent-mcpserver@0.3.1

docs

index.md

tile.json