Skip to content

Add parameters in dynamic mode

In dynamic mode all parameters (such as Return Types, Required Inputs, etc.) can be injected into the florentine_ask tool. This allows for a more flexible approach allowing you to dynamically change the florentine_ask tool input i.e. based on a given userId.

In order to be able to pass in values dynamically you have to overwrite the florentine_ask tool method inside your custom client/agent. Look at the following example using the standard @modelcontextprotocol Typescript SDK:

ts
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { fetchUserSpecificData } from "./userService.js";

// Create the MCP client instance
const mcpClient = new Client({
  name: "florentine",
  version: "1.0.0"
});

// Define MCP setup configuration
const mcpSetupConfig = new StdioClientTransport({
  command: "npx",
  args: ["-y", "@florentine-ai/mcp", "--mode", "dynamic"],
  env: {
    FLORENTINE_TOKEN: "<FLORENTINE_API_KEY>"
  }
});

// Connect the MCP client
await mcpClient.connect(mcpSetupConfig);

// Save original callTool function to variable
const originalCallTool = mcpClient.callTool;

// Fetch and add florentine_ask parameters dynamically (mock implementation)
const enhanceAskParameters = async ({ question }: { question: string }) => {
  return {
    question,
    // Mocking user data fetch (i.e. returnTypes, requiredInputs, etc.),
    // replace with actual implementation
    ...(await fetchUserSpecificData({ userId: "<USER_ID>" }))
  };
};

// Overwrite callTool function with custom implemention
// enhancing florentine_ask method with dynamically injected parameters
mcpClient.callTool = async (params, resultSchema, options) => {
  if (params.name === "florentine_ask")
    params.arguments = await enhanceAskParameters(params.arguments as unknown as { question: string });
  return await originalCallTool(params, resultSchema, options);
};

// Call to florentine_ask tool will automatically enhance parameters
const result = await mcpClient.callTool({
  name: "florentine_ask",
  arguments: {
    question: "Who won the last tabletennis match?"
  }
});

Example breakdown

So let's see what is happening here in detail. First of all we create the mcp client and connect it:

ts
const mcpClient = new Client({
  name: "florentine",
  version: "1.0.0"
});

const mcpSetupConfig = new StdioClientTransport({
  command: "npx",
  args: ["-y", "@florentine-ai/mcp", "--mode", "dynamic"],
  env: {
    FLORENTINE_TOKEN: "<FLORENTINE_API_KEY>"
  }
});

await mcpClient.connect(mcpSetupConfig);

Please note

You may use env variables in dynamic mode as well. However if you specify parameters dynamically these will overwrite existing env values for the parameters.

Next, we save the original callTool function to a variable:

ts
const originalCallTool = mcpClient.callTool;

Then we create an enhanceAskParameters function that takes a question as input, fetches additional parameters (e.g. returnTypes, requiredInputs etc.) for the user and returns the merged parameters:

ts
const enhanceAskParameters = async ({ question }: { question: string }) => {
  return {
    question,
    ...(await fetchUserSpecificData({ userId: "<USER_ID>" }))
  };
};

Then we overwrite the original callTool function with an implementation that enhances the florentine_ask tool with the parameters coming from enhanceAskParameters and call the original callTool function we save to the variable originalCallTool:

ts
mcpClient.callTool = async (params, resultSchema, options) => {
  if (params.name === "florentine_ask")
    params.arguments = await enhanceAskParameters(params.arguments as unknown as { question: string });
  return await originalCallTool(params, resultSchema, options);
};

Finally we can call the florentine_ask tool with a question and have the user-specific parameters dynamically injected:

ts
const result = await mcpClient.callTool({
  name: "florentine_ask",
  arguments: {
    question: "Who won the last tabletennis match?"
  }
});

DANGER

Make sure that you never use dynamic mode without overwriting florentine_ask implementation.

If you do not overwrite it your client/agent will directly use the mcp server-side implementation of the florentine_ask tool with all additional parameters.

So the client/agent will decide on its own what values to fill in for returnTypes, requiredInputs etc.

That will result in unexpected behavior and lead to errors and wrong results.

florentine_ask parameters

VariableRequiredTypeDescription
sessionIdNoStringThe session id of the client. Used for server-side chat history. See the sessions section.
returnTypesNoArray<String>The return types for florentine_ask tool calls. See the return types section.
requiredInputsNoArray<Object>The required inputs. See the required inputs section.