自然语言数据库查询服务

Florentine.ai MCP Server 提供自然语言查询 MongoDB 和 MySQL 数据的功能,支持多租户安全数据分离、自动模式探索和语义向量搜索。

  • by florentine-ai
  • TypeScript
  • 本地部署
  • 6 星标
  • 更新于
在 GitHub 查看 florentine-ai/mcp

使用说明

Florentine.ai MCP服务器-与您的MongoDB和MySQL数据对话

Florentine.ai模型上下文协议(MCP)服务器允许您集成 MongoDB和MySQL数据的自然语言查询 直接进入您的自定义AI代理或AI桌面应用程序。

AI代理将问题转发到MCP服务器,转换为数据库查询和 查询结果返回给代理 以便进一步处理。

还有几个 额外功能 引擎盖下,例如:

  • 安全的数据分离 适用于多租户使用
  • 自动模式探索
  • 语义向量搜索/RAG支持 具有自动嵌入创建功能
  • 高级查找支持
  • 钥匙排除

注: 如果您正在寻找我们的API,您可以 在这里找到它.

目录

先决条件

  • Node.js>=v18.0.0
  • Florentine.ai帐户(创建 免费帐户在这里)
  • 您的Florentine.ai帐户中有一个连接的数据库和至少一个经过分析和激活的集合/表
  • 佛罗伦萨.ai API密钥(您可以在您的 帐户仪表板)

安装

可以找到MCP服务器的详细文档 在我们的文档中.

您可以使用npx轻松运行服务器。请参阅以下Claude Desktop示例(claude_desktop_config.json):

{
  "mcpServers": {
    "florentine": {
      "command": "npx",
      "args": ["-y", "@florentine-ai/mcp", "--mode", "static"],
      "env": {
        "FLORENTINE_TOKEN": "<FLORENTINE_API_KEY>"
      }
    }
  }
}

可用工具

  • 佛罗伦萨_列表_收藏 -->列出当前可查询的所有活动集合/表。这包括描述、键和值的类型。
  • 佛罗伦萨询问 -->接收问题并返回查询、查询结果或答案(取决于 returnTypes 设置)。

参数

变量 必填 允许值 说明
--mode 是的 static, dynamic static (适用于现有的外部MCP客户端,例如Claude Desktop)或 dynamic (适用于自己的自定义MCP客户端)。看 集成模式部分.
--debug 没有 true 允许记录到外部文件。如果设置需要 --logpath 也要设置。
--logpath 否 绝对日志文件路径 调试日志的文件路径。如果设置需要 --debug 也要设置。

认证

Florentine.ai MCP服务器使用API密钥来验证请求。您可以在您的 帐户仪表板密钥必须作为ENV变量添加到MCP服务器的配置设置中:

"env": {
  "FLORENTINE_TOKEN": "<FLORENTINE_API_KEY>"
}

连接您的LLM帐户

Florentine.ai作为一个 带上你自己的钥匙模型,因此您需要在MCP请求中提供您的LLM API密钥(OpenAI、Google、Anthropic、Deepsseek)。

您有两个选项可以用于添加LLM API密钥:

选项1:将LLM密钥保存在您的帐户中(推荐)

连接到LLM提供程序的最简单方法是将LLM API密钥保存在 Florentine.ai仪表板.

  • 添加API密钥
  • 选择您的法学硕士提供者(OpenAI、Deepseek、谷歌或Anthropic)
  • 单击保存

选项2:在MCP服务器配置环境变量中提供LLM密钥

如果您不想将密钥存储在Florentine.ai帐户中,或者想使用多个LLM密钥,可以在MCP服务器配置中传递密钥:

"env": {
  "LLM_SERVICE": "<YOUR_LLM_SERVICE>",
  "LLM_KEY": "<YOUR_LLM_API_KEY>"
}
参数 说明 允许值
LLM_SERVICE 指定要使用的LLM提供程序。 openai,google,anthropic 或 deepseek
LLM_KEY 提供的LLM服务的API密钥。 有效的API密钥字符串

注: 如果您提供 LLM_KEY 在MCP服务器配置的env变量中,它将覆盖存储在您帐户中的任何密钥。

集成模式

你必须 设置操作模式 在 args 将MCP服务器配置数组设置为 static 或 dynamic:

"args": [
  "-y",
  "@florentine-ai/mcp",
  "--mode",
  "static"
]

静态模式

应使用静态模式 如果您将Florentine.ai集成到现有的外部MCP客户端中 例如支持MCP的桌面应用程序,如Claude Desktop或Dive AI。

在 static 在配置json中,您可以将所有参数(如返回类型、必需输入等)设置为env变量。这意味着这些 在更改设置配置之前,参数将保持不变 并将与每个请求一起发送到Florentine.ai。请参阅以下示例:

{
  "mcpServers": {
    "florentine": {
      "command": "npx",
      "args": ["-y", "@florentine-ai/mcp", "--mode", "static"],
      "env": {
        "FLORENTINE_TOKEN": "<FLORENTINE_API_KEY>",
        "SESSION_ID": "6f7d62f9-8ceb-456b-b7ef-6bd869c3b13a",
        "LLM_SERVICE": "openai",
        "LLM_KEY": "<YOUR_OPENAI_KEY>",
        "RETURN_TYPES": "[\"result\"]",
        "REQUIRED_INPUTS": "[{\"keyPath\":\"accountId\",\"value\":\"507f1f77bcf86cd799439011\"}]"
      }
    }
  }
}

环境变量

变量 必填 类型 描述
FLORENTINE_TOKEN 是 字符串 您的Florentine.ai api密钥,从复制 仪表盘.
SESSION_ID 否 字符串 客户端的会话id。用于服务器端聊天记录。看 会议部分.
LLM_SERVICE No String 指定要使用的LLM提供程序。只有当您没有将LLM密钥保存在Florentine.ai帐户中时才需要。看 连接您的LLM帐户部分.
LLM_KEY 否 字符串 您提供的LLM服务的API密钥。只有当您没有将LLM密钥保存在Florentine.ai帐户中时才需要。看 连接您的LLM帐户部分.
RETURN_TYPES 否 字符串化JSON 的返回类型 florentine_ask 工具调用。看 返回类型部分.
REQUIRED_INPUTS 否 字符串化JSON 所需的输入。看 所需输入部分.

动态模式

应使用动态模式 如果您将Florentine.ai集成到自己的自定义MCP客户端中.

在动态模式下,您可以将所有参数(如返回类型、所需输入等)直接传递给 florentine_ask 工具。这意味着你可以 为每个请求动态注入单个参数 转发到Florentine.ai(即用户id)。

为了能够动态传递值,您必须 覆盖自定义客户端/代理中的florentineask工具方法。使用标准查看以下示例 @modelcontextprotocol 打字SDK:

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?'
  }
});

示例分解

让我们详细看看上面的例子中发生了什么。

首先,我们创建mcp客户端并连接它:

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);

注: 您可以使用 env 变量在 dynamic 模式也是。但是,如果动态指定参数,这些参数将覆盖现有参数 env 参数的值。

接下来,我们保存原始文件 callTool 函数到变量:

const originalCallTool = mcpClient.callTool;

然后我们创建一个 enhanceAskParameters 将问题作为输入的函数,获取其他参数(例如。 returnTypes, requiredInputs 等等),并返回合并后的参数:

const enhanceAskParameters = async ({ question }: { question: string }) => {
  return {
    question,
    // Example function that fetches additional data, e.g. user-specfic requiredInputs
    ...(await fetchUserSpecificData({ userId: '<USER_ID>' }))
  };
};

然后我们覆盖原始内容 callTool 功能,实现增强 florentine_ask 工具的参数来自 enhanceAskParameters 并呼叫原件 callTool 我们保存到变量中的函数 originalCallTool:

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);
};

最后我们可以打电话给 florentine_ask 工具中有一个问题,并动态注入用户特定的参数:

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

重要: 确保在不覆盖的情况下从不使用动态模式 florentine_ask 实施。 如果你不覆盖它,你的客户端/代理将直接使用mcp服务器端实现 florentine_ask 该工具具有所有附加参数。 因此,客户/代理将自行决定填写哪些值 returnTypes, requiredInputs 等等 这将导致意外的行为,并导致错误和错误的结果。

florentine_ask参数

变量 必填 类型 描述
sessionId 否 字符串 客户端的会话id。用于服务器端聊天记录。看 会议部分.
returnTypes 没有 Array<String> 返回类型为 florentine_ask 工具调用。看 返回类型部分.
requiredInputs 没有 Array<Object> 所需的输入。看 所需输入部分.

返回类型

默认情况下 florentine_ask 工具返回在Florentine.ai帐户中配置的结果类型(默认值: result).你可以 根据请求覆盖此内容 通过指定a returnTypes 数组包含以下三个步骤的任意组合:

  1. 查询生成:问题转换为数据库查询(MongoDB聚合管道或MySQL查询)。
  2. 查询执行:查询使用您提供的连接字符串对数据库运行。
  3. 答案生成:结构化结果转换为自然语言答案。

提供退货类型

您有两个选项可以包含 returnTypes 数组:

  • 随着 RETURN_TYPES env MCP设置配置中的变量(可能在 static 和 dynamic 模式)
  • 随着 returnTypes 参数到 florentine_ask 工具(仅在 dynamic 模式)

作为一个 env 变量,您将值作为字符串化的json数组提供:

"env": {
  "RETURN_TYPES": "[\"query\",\"result\",\"answer\"]"
}

作为工具参数,您可以将值作为数组提供:

{
  "returnTypes": ["query", "result", "answer"]
}

退货类型配置

您可以通过指定以下步骤来选择要返回的步骤 returnTypes 具有以下任意组合的数组:

returnTypes 值 描述 响应中的预期键
"query" 返回生成的数据库查询、使用的数据库和集合/表、0到10的置信度评分和数据库类型("mongodb" 或 "mysql"). confidence, database, collection, query, databaseType
"result" 返回已执行查询的原始查询结果。 result
"answer" 根据执行的查询结果返回自然语言响应。 answer

多租户使用的安全数据分离

您可以启用 安全数据分离 通过确保查询 根据提供的值过滤数据 我们称之为 Required Inputs.

这些值是 添加到查询中 通过Florentine.ai转换层 LLM生成查询后因此 Florentine.ai可以确保每个用户只检索他有资格检索的数据.

密钥定义为 Required Input 在您的账户中,请参考 我们官方文件中的部分 关于如何做到这一点。

提供所需输入

您有两个选项可以包含 requiredInputs 数组:

  • 随着 REQUIRED_INPUTS env MCP设置配置中的变量(可能在 static 和 dynamic 模式)
  • 随着 requiredInputs 参数到 florentine_ask 工具(仅在 dynamic 模式)

作为一个 env 变量,您将值作为字符串化的json数组提供:

"env": {
  "REQUIRED_INPUTS": "[{\"keyPath\":\"userId\",\"value\":\"507f1f77bcf86cd799439011\"}]"
}

作为工具参数,您可以将值作为数组提供:

"requiredInputs": [
    {
      "keyPath": "userId",
      "value": "507f1f77bcf86cd799439011"
    }
  ]

您还可以提供 database 以及a collections 数组,以防您有相同的必需输入 keyPath 在多个集合/表中,但不同 value 对于集合/表格:

{
  "requiredInputs": [
    {
      "keyPath": "name",
      "value": "Sesame Street",
      "database": "rentals",
      "collections": ["houses"]
    },
    {
      "keyPath": "name",
      "value": { "$in": ["Ernie", "Bert"] },
      "database": "rentals",
      "collections": ["tenants"]
    }
  ]
}

所需输入配置

字段 必填 类型 描述 约束
keyPath Yes String 应筛选字段的路径。 必须是有效的密钥路径。
value Yes Any 要筛选的值(特定于类型,请参阅 支持的值类型). 必须与字段的类型(字符串、对象ID、布尔值、数字或日期)匹配。
database 否 字符串 包含要筛选的集合的数据库。 如果满足以下条件,则必须提供 collections 提供。
collections 没有 Array<String> 数据库中要应用筛选器的特定集合/表。 必须至少包含一个集合/表。

支持的值类型

根据密钥值的类型,您可以选择提供不同的选项 Required Input 值:

类型 格式示例 支持的运算符 备注
String 或 Array<String> "text"
{ $in: ["text1", "text2"] }
$in 案件敏感。
ObjectId 或 Array<ObjectId> "507f191e810c19729de860ea"
{ $in: ["507f191e810c19729de860ea", "507f191e810c19729de860eb"] }
$in 以字符串形式提供。
Boolean true/false -- 只有精确值。
Number 或 Array<Number> 42
{ $gt: 10, $lte: 100 }
{ $in: [1, 2, 3] }
{ $in: [{$gte:1}, {$lt:10}] }
$gt, $gte, $lt, $lte, $in 支持小数。
Date 或 Array<Date> "2024-01-01T00:00:00Z" (UTC)
"2024-01-01T00:00:00-05:00"(时区偏移)
$gt, $gte, $lt, $lte, $in ISO 8601格式。

用法示例

注: 我们将仅提供示例作为工具参数输入。对于 env 您只需将键名更改为 REQUIRED_INPUTS 并将json字符串化。

示例类型: String

用例: 用户应该只能看到他经常玩的玩家的统计数据。

解决方案: 按玩家名称限制4名玩家的访问。

const res = await FlorentineAI.ask({
  question: 'Which player had the most wins?',
  requiredInputs: [
    {
      keyPath: 'name',
      value: { $in: ['Megan', 'Frank', 'Jen', 'Bob'] }
    }
  ]
});

示例类型: ObjectId

用例: 用户应该只能看到自己产品的收入。

解决方案: 将accountId的访问限制为一个特定帐户。

const res = await FlorentineAI.ask({
  question: 'Whats the revenue of my products?',
  requiredInputs: [
    {
      keyPath: 'accountId',
      value: '507f1f77bcf86cd799439011'
    }
  ]
});

示例类型: Boolean

用例: 对客户的每一次分析都应该只对付费客户进行。

解决方案: 将isPaidAccount的访问权限限制为仅限付费客户。

const res = await FlorentineAI.ask({
  question: 'How many customers registered in the last year?',
  requiredInputs: [
    {
      keyPath: 'isPaidAccount',
      value: true
    }
  ]
});

示例类型: Number

用例: 员工只能查看低于一定金额的付款信息。

解决方案: 限制按金额访问10000以下的付款。

const res = await FlorentineAI.ask({
  question: 'List all payments we received.',
  requiredInputs: [
    {
      keyPath: 'amount',
      value: { $lt: 10000 }
    }
  ]
});

示例类型: Date

用例: 财务数据分析应仅包括一个特定年份。

解决方案: 限制通过transactionDate访问2024年的所有交易。

const res = await FlorentineAI.ask({
  question: 'What was our revenue, profit and margin per month?',
  requiredInputs: [
    {
      keyPath: 'transactionDate',
      value: {
        $gte: '2023-01-01T00:00:00Z',
        $lt: '2024-01-01T00:00:00Z'
      }
    }
  ]
});

会话

会话 允许Florentine.ai 启用服务器端聊天记录.

由于客户端/代理(包括MCP服务器)通常会跟踪聊天历史记录本身,因此 添加会话不是绝对必要的.

然而,它可能仍然有助于Florentine.ai更好地理解上下文,并可能提高结果质量。

提供会话

您有两个选项可以包含 sessionId:

  • 随着 SESSION_ID env MCP设置配置中的变量(可能在 static 和 dynamic 模式)
  • 随着 sessionId 参数到 florentine_ask 工具(仅在 dynamic 模式)

作为一个 env 变量:

"env": {
  "SESSION_ID": "<YOUR_SESSION_ID>"
}

作为工具参数:

{
  "sessionId": "<YOUR_SESSION_ID>"
}

错误

MCP Server工具调用的所有错误都遵循以下一致的JSON结构:

{
  "error": {
    "name": "FlorentineApiError",
    "statusCode": 500,
    "message": "The provided Florentine API key is invalid. You can find the key in your account settings: https://florentine.ai/settings",
    "errorCode": "INVALID_TOKEN",
    "requestId": "abc123"
  }
}
字段 类型 描述
name string 错误类名(例如。 FlorentineApiError, FlorentineConnectionError)
statusCode number HTTP状态码(例如。 400, 500)
message string 解释出了什么问题
errorCode string 错误标识符(例如。 NO_TOKEN, INVALID_LLM_KEY)
requestId string 此请求的唯一ID(有助于支持和调试)

自定义客户端错误处理

错误对象在 content 数组:

{
  "content": [
    {
      "type": "text",
      "text": "{\"error\":{\"name\":\"FlorentineApiError\",\"statusCode\":401,\"message\":\"The provided Florentine API key is invalid. You can find the key in your account settings: https://florentine.ai/settings\",\"errorCode\":\"INVALID_TOKEN\",\"requestId\":\"uhv99g\"}}"
    }
  ],
  "isError": true
}

您可以在中解析JSON text 并处理自定义客户端/代理中的不同错误。

常见错误

错误名称 错误代码 含义
FlorentineApiError MODE_MISSING 您必须提供 static 或 dynamic 作为模式参数
FlorentineApiError MODE_INVALID 模式无效(必须是 static 或 dynamic)
FlorentineApiError INVALID_TOKEN Florentine API密钥无效
FlorentineApiError LLM_KEY_WITHOUT_SERVICE 您必须提供 llmService 如果 llmKey 已定义
FlorentineApiError LLM_SERVICE_WITHOUT_KEY 您必须提供 llmKey 如果 llmService 已定义
FlorentineApiError INVALID_LLM_SERVICE 无效 llmService 提供
FlorentineApiError NO_OWN_LLM_KEY 您需要提供自己的llm密钥
FlorentineApiError NO_ACTIVE_COLLECTIONS 没有为该帐户激活集合/表格
FlorentineApiError MISSING_REQUIRED_INPUT 缺少必需的输入
FlorentineApiError INVALID_REQUIRED_INPUT 所需输入无效
FlorentineApiError INVALID_REQUIRED_INPUT_FORMAT 所需的输入格式无效
FlorentineApiError NO_QUESTION 问题缺失
FlorentineApiError EXECUTION_FAILURE 创建查询执行失败
FlorentineApiError NO_CHAT_ID 需要历史聊天id,但缺少
FlorentineApiError TOO_MANY_TOKENS 查询提示超出了LLM模型的最大标记数
FlorentineLLMError API_KEY_ISSUE LLM API密钥无效
FlorentineLLMError NO_RETURN Florentine.ai没有收到有效的LLM申报表
FlorentineLLMError RATE_LIMIT_EXCEEDED LLM请求大小太大
FlorentineConnectionError CONNECTION_REFUSED 无法连接到数据库以执行查询
FlorentineCollectionError NO_EXECUTION 创建的查询无法执行
FlorentinePipelineError MODIFICATION_FAILED 修改查询管道失败
FlorentineUsageError LIMIT_REACHED 计划中包含的所有API请求已耗尽
FlorentineUnknownError UNKNOWN_ERROR 所有发生的未知错误