MCPClient / Server - Dissallow tool usage

MCP Client / Server setup - X number of tools available on the server.

I want to prevent specific tool usage if they are a certain class of user.

To test this I implemented OnBeforeUseTool of the TMSMCPClient


procedure TForm1.MCPClientBeforeUseTool(Sender: TObject; AToolName: string;
  AParam: TJSONObject; var AAllow: Boolean);
begin
  ThinkingMemo.Lines.Add('<-' + AToolName + ' - ' + AParam.ToString);
  AAllow := False;
end;

Using Grok - I see that it gets stuck in a loop calling the same tool over and over again.

<-run-sql - {"sql":"SELECT COUNT() AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:38 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT(
) AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:39 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT() AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:43 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT(
) AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:44 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT() AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:46 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT(
) AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:47 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT() AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:48 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT(
) AS CustomerCount FROM MAccount WHERE Type = 1"}
11/12/2025 4:50:49 PM - Tool execution not allowed: run-sql
<-run-sql - {"sql":"SELECT COUNT(*) AS CustomerCount FROM MAccount WHERE Type = 1"}
...

OpenAI - seems to be a lot better here, it tries a couple different tools and then gives up. That's more than fine.

I don't have API keys for the others, or I'd report them here.

Thoughts?

Hi,

The OnBeforeUseTool is to implement a message for users to confirm a tool will be invoked, not to filter which tools should be exposed to the LLM.

We'll need to look to expose tools at server item level in TTMSMCPClient, but in the meantime you could try manipulating the TTMSMCPClient.LLM.Tools collection before invoking a query to the LLM to exclude the tools you do not want to share. Each tool has an Enabled property you can set to False.

That makes sense - but in the Grok example, if the user would dissallow the tool, it would still infinitely run.

Tried that out, and that looks like it might work. We'll play around with it.

A more elegant way to do this would be fantastic.

Essentially we have user security for each of our reports across the system. Our plan would be to have a tool that represents each report.

Thanks all.

That is part of the MCP specification as a strong recommendation. The user should be allowed to make a final decesion on whether they want to let the chosen tool by the LLM to run or not. See here.

When you disable a tool it won't be sent to the LLM for discovery.