Skip to main content

In-process tools for Spring AI

The second starter hands the same operation files to a ChatClient, without a Model Context Protocol (MCP) server:

<dependency>
<groupId>io.gatool</groupId>
<artifactId>gatool-in-process-spring-boot-starter</artifactId>
<version>0.1.0</version>
</dependency>
@Bean
ChatClient assistant(ChatClient.Builder builder, GAToolCallbacks tools) {
return builder.defaultTools(tools.toolCallbackProvider()).build();
}

ChatClient.Builder comes from a Spring AI chat model starter, such as spring-ai-starter-model-anthropic. The application adds that starter beside this one.

Files under gatool/in-process/, the in-process folder, reach the ChatClient. Files under gatool/mcp/, the MCP folder, reach the MCP server. One application can therefore serve both with different lists.

An in-process tool runs inside the application. Three things stay out of its path: the scopes an operation file lists, the rate limiter, and Spring AI's ToolContext. The tool takes its arguments from the model's text alone. The caller is the application itself. Under token-exchange and under gatool.api.credentials.unsafe.forward-client-tokens, the forwarded token, the caller is the user on the thread that calls the tool. Both strategies read the token from that thread's security context. Under a per-caller credential, GATool refuses a call where the thread's security context may belong to another caller. The caller and the request thread describes that refusal.

The arguments travel to the API as the model wrote them. An argument the input schema does not name is forwarded as sent. An argument the model left out stays out. A misspelt name therefore gets the API's own answer for the unnamed argument: its default, or the API's own error. The MCP path refuses such a call before the API sees it. A later minor release may validate arguments before the call, as the MCP path does.

A scope list on an in-process file states what the application has to enforce itself. The application enforces it with method security on the resolver, or in the code that builds the ChatClient. The startup listing, the list of tools GATool prints at INFO when the application starts, says so beside the tool. Spring AI's own spring.ai.tool observation covers each call. A refusal reaches the model as a plain sentence of text. One example is a credential the configured strategy could not supply. An answer arrives as the same GraphQL envelope the MCP path returns.