mcpField
F
florentine-ai

florentine-ai

本地服务
github.com/florentine-ai数据库633 周前更新

关于 florentine-ai

florentine-ai 是面向 AI Agent 和桌面应用的 MCP 服务,可用自然语言查询 MongoDB 与 MySQL 数据。它能生成并执行查询、返回结果或答案,并支持架构探索和语义搜索。

主要功能

  1. 01用自然语言查询 MongoDB 和 MySQL
  2. 02列出启用的集合和数据表
  3. 03选择返回查询、结果或答案
  4. 04配置静态或动态参数
  5. 05支持语义向量搜索和 RAG
  6. 06隔离多租户数据

适用场景

  1. 01询问已连接数据库中的数据
  2. 02检查可用集合及表字段
  3. 03返回生成的查询以供审核
  4. 04为每次请求传入用户专属输入

MCP 相关

向 MCP 客户端提供 `florentine_list_collections` 和 `florentine_ask` 工具。后者将问题转交 Florentine.ai 生成并执行数据库查询,支持配置返回类型和集成模式。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"florentine-ai": {
"command": "npx",
"args": [
"-y",
"@florentine-ai/mcp"
],
"env": {
"FLORENTINE_TOKEN": "<FLORENTINE_TOKEN>",
"LLM_SERVICE": "<LLM_SERVICE>",
"LLM_KEY": "<LLM_KEY>",
"SESSION_ID": "<SESSION_ID>",
"RETURN_TYPES": "<RETURN_TYPES>",
"REQUIRED_INPUTS": "<REQUIRED_INPUTS>"
}
}
}
}
启动命令npx -y @florentine-ai/mcp
需要配置的环境变量
FLORENTINE_TOKEN密钥Your Florentine.ai API key, get it from https://florentine.ai/dashboard
LLM_SERVICEThe LLM service to use, one of 'openai', 'anthropic', 'google' or 'deepseek' (must only be provided if you did not set it in your Florentine.ai account)
LLM_KEY密钥Your API key for the LLM service (must only be provided if you did not set it in your Florentine.ai account)
SESSION_IDSession ID for maintaining server-side context across requests
RETURN_TYPESStringified JSON array of return types for the response
REQUIRED_INPUTSStringified JSON array of values for required inputs keys

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@florentine-ai/mcp0.2.1

工具

2

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

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

Florentine.ai 模型上下文协议(MCP)服务可让你将以自然语言查询 MongoDB 和 MySQL 数据的功能,直接集成到自定义 AI Agent 或 AI 桌面应用中。

AI Agent 会将问题转发给 MCP 服务,由服务将其转换为数据库查询,并将查询结果返回给 Agent,以供进一步处理。

此外,服务还提供一些额外功能,例如:

  • 安全的数据隔离,支持多租户使用
  • 自动探索架构
  • 语义向量搜索/RAG 支持,并可自动创建嵌入
  • 高级查找支持
  • 排除键

**注意:**如果你要查找我们的 API,可以点击此处。

目录

先决条件

  • Node.js >= v18.0.0
  • Florentine.ai 账户(在此创建免费账户)
  • 已连接的数据库,以及 Florentine.ai 账户中至少一个已分析并激活的集合/表
  • Florentine.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>"
      }
    }
  }
}

可用工具

  • florentine_list_collections --> 列出当前所有可查询的已激活集合/表,包括说明、键和值类型。
  • florentine_ask --> 接收问题并返回查询、查询结果或答案(具体取决于 returnTypes 设置)。

参数

变量必填允许值描述
--mode是static, dynamicstatic(用于现有的外部 MCP 客户端,例如 Claude Desktop)或 dynamic(用于自定义 MCP 客户端)。请参阅集成模式部分。
--debug否true启用将日志记录到外部文件。如果设置此项,也必须设置 --logpath。
--logpath否绝对日志文件路径调试日志的文件路径。如果设置此项,也必须设置 --debug。

身份验证

Florentine.ai MCP 服务使用 API 密钥对请求进行身份验证。你可以在账户控制面板中查看和管理 API 密钥。必须将该密钥作为 ENV 变量添加到 MCP 服务的配置设置中:

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

连接你的大模型账户

Florentine.ai 采用自带密钥模式,因此你需要在 MCP 请求中提供大模型 API 密钥(OpenAI、Google、Anthropic、Deepseek)。

你可以通过两种方式添加大模型 API 密钥:

选项 1:将大模型密钥保存在账户中(推荐)

连接大模型提供商最简单的方式是将大模型 API 密钥保存在 Florentine.ai 控制面板中。

  • 添加 API 密钥
  • 选择大模型提供商(OpenAI、Deepseek、Google 或 Anthropic)
  • 点击 Save

添加大模型密钥

选项 2:在 MCP 服务配置的环境变量中提供大模型密钥

如果你不想将密钥保存在 Florentine.ai 账户中,或想使用多个大模型密钥,可以在 MCP 服务配置中传入密钥:

"env": {
  "LLM_SERVICE": "<YOUR_LLM_SERVICE>",
  "LLM_KEY": "<YOUR_LLM_API_KEY>"
}
参数描述允许值
LLM_SERVICE指定要使用的大模型提供商。openai,google,anthropic 或 deepseek
LLM_KEY所提供的大模型服务的 API 密钥。有效的 API 密钥字符串

**注意:**如果在 MCP 服务配置的环境变量中提供 LLM_KEY,它将覆盖账户中保存的任何密钥。

集成模式

你必须在 MCP 服务配置的 args 数组中将运行模式设置为 static 或 dynamic:

"args": [
  "-y",
  "@florentine-ai/mcp",
  "--mode",
  "static"
]
静态模式

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

在 static 模式下,你需要将所有参数(例如返回类型、必填输入等)作为环境变量设置在配置 JSON 中。这意味着这些参数将保持静态,直到你更改设置配置,并且每次请求 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是String你的 Florentine.ai api 密钥,可从 控制面板 复制。
SESSION_ID否String客户端的会话 ID。用于服务端聊天记录。请参阅会话部分。
LLM_SERVICE否String指定要使用的 LLM 提供商。仅当你没有在 Florentine.ai 账户中保存 LLM 密钥时才需要。请参阅连接 LLM 账户部分。
LLM_KEY否String你所提供的 LLM 服务的 API 密钥。仅当你没有在 Florentine.ai 账户中保存 LLM 密钥时才需要。请参阅连接 LLM 账户部分。
RETURN_TYPES否Stringified JSONflorentine_ask 工具调用的返回类型。请参阅返回类型部分。
REQUIRED_INPUTS否Stringified JSON必需的输入。请参阅必需输入部分。
动态模式

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

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

要能够动态传入值,你必须在自定义客户端/Agent 中覆盖 florentine_ask 工具方法。请查看以下使用标准 @modelcontextprotocol Typescript 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);

注意: 在 dynamic 模式下,你也可以使用 env 变量。不过,如果你动态指定参数,这些参数将覆盖现有的 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 函数替换为一个实现:该实现使用 enhanceAskParameters 返回的参数增强 florentine_ask 工具,并调用保存到 originalCallTool 变量中的原始 callTool 函数:

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

IMPORTANT: 请确保在使用动态模式时,始终覆盖 florentine_ask 的实现。 如果不覆盖,客户端/Agent 将直接使用 MCP 服务端的 florentine_ask 工具实现及其所有附加参数。 因此,客户端/Agent 会自行决定为 returnTypes、requiredInputs 等参数填入哪些值。 这会导致意外行为、错误和错误结果。

florentine_ask 参数
变量必填类型描述
sessionId否String客户端的会话 ID。用于服务端聊天记录。请参阅会话部分。
returnTypes否Array<String>florentine_ask 工具调用的返回类型。请参阅返回类型部分。
requiredInputs否Array<Object>必需的输入。请参阅必需输入部分。

返回类型

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

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

你可以通过两种方式提供 returnTypes 数组:

  • 在 MCP 设置配置中将其设为 RETURN_TYPES env 变量(适用于 static 和 dynamic 模式)
  • 将其作为参数传递给 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。

这些值会在 LLM 生成查询后,由 Florentine.ai 转换层添加到查询中。因此,Florentine.ai 可以确保每位用户只能检索其有权访问的数据。

在您的账户中将键定义为 Required Input。如何操作,请参阅官方文档中的相关章节。

提供 Required Inputs

您可以通过以下两种方式包含 requiredInputs 数组:

  • 在 MCP 配置中将其作为 REQUIRED_INPUTS env 变量(static 和 dynamic 模式均可)
  • 将其作为 requiredInputs 参数传递给 florentine_ask 工具(仅限 dynamic 模式)

作为 env 变量时,请将值以字符串形式提供,内容为 JSON 数组:

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

作为工具参数时,请将值以数组形式提供:

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

如果多个集合/表中存在 keyPath 相同但 value 不同的 Required Inputs,您还可以提供 database 和 collections 数组:

{
  "requiredInputs": [
    {
      "keyPath": "name",
      "value": "Sesame Street",
      "database": "rentals",
      "collections": ["houses"]
    },
    {
      "keyPath": "name",
      "value": { "$in": ["Ernie", "Bert"] },
      "database": "rentals",
      "collections": ["tenants"]
    }
  ]
}
必需输入配置
字段必需类型描述约束
keyPath是String要筛选的字段路径。必须是有效的键路径。
value是Any用于筛选的值(因类型而异,参见支持的值类型)。必须与字段类型匹配(String、ObjectId、Boolean、Number 或 Date)。
database否String包含要筛选的集合的数据库。如果提供了 collections,则必须提供此项。
collections否Array<String>数据库中要应用筛选条件的特定集合/表。必须至少包含一个集合/表。
支持的值类型

根据键对应值的类型,你可以为 Required Input 值提供不同的选项:

类型格式示例支持的运算符备注
String 或 Array<String>"text"
{ $in: ["text1", "text2"] }
$in区分大小写。
ObjectId 或 Array<ObjectId>"507f191e810c19729de860ea"
{ $in: ["507f191e810c19729de860ea", "507f191e810c19729de860eb"] }
$in以字符串形式提供。
Booleantrue/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、$inISO 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

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

解决方案: 按 amount 限制访问范围,仅允许查看金额低于 10.000 的付款。

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 能够启用服务端聊天记录。

由于客户端/Agent(包括 MCP 服务)通常会自行跟踪聊天记录,因此并非一定要添加会话。

不过,这仍有助于 Florentine.ai 更好地理解上下文,并可能提升结果质量。

提供会话

有两种方式可以添加 sessionId:

  • 在 MCP 配置中将其设为 SESSION_ID env 变量(static 和 dynamic 模式均可)
  • 将其设为 florentine_ask 工具的 sessionId 参数(仅 dynamic 模式可用)

作为 env 变量:

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

作为工具参数:

{
  "sessionId": "<YOUR_SESSION_ID>"
}

错误

MCP 服务工具调用返回的所有错误都遵循以下统一的 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"
  }
}
字段类型说明
namestring错误类名称(例如 FlorentineApiError、FlorentineConnectionError)
statusCodenumberHTTP 状态码(例如 400、500)
messagestring对错误原因的说明
errorCodestring错误标识符(例如 NO_TOKEN、INVALID_LLM_KEY)
requestIdstring此请求的唯一 ID(有助于支持和调试)
自定义客户端错误处理

错误对象会以字符串化 JSON 的形式在 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
}

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

常见错误
错误名称errorCode含义
FlorentineApiErrorMODE_MISSING必须将 static 或 dynamic 作为模式参数提供
FlorentineApiErrorMODE_INVALID模式无效(必须为 static 或 dynamic)
FlorentineApiErrorINVALID_TOKENFlorentine API 密钥无效
FlorentineApiErrorLLM_KEY_WITHOUT_SERVICE如果定义了 llmKey,必须提供 llmService
FlorentineApiErrorLLM_SERVICE_WITHOUT_KEY如果定义了 llmService,必须提供 llmKey
FlorentineApiErrorINVALID_LLM_SERVICE提供的 llmService 无效
FlorentineApiErrorNO_OWN_LLM_KEY需要提供自己的 LLM 密钥
FlorentineApiErrorNO_ACTIVE_COLLECTIONS此账户没有已启用的集合/表
FlorentineApiErrorMISSING_REQUIRED_INPUT缺少必需输入
FlorentineApiErrorINVALID_REQUIRED_INPUT必需输入无效
FlorentineApiErrorINVALID_REQUIRED_INPUT_FORMAT必需输入的格式无效
FlorentineApiErrorNO_QUESTION缺少问题
FlorentineApiErrorEXECUTION_FAILURE创建的查询执行失败
FlorentineApiErrorNO_CHAT_ID需要历史聊天 ID,但未提供
FlorentineApiErrorTOO_MANY_TOKENS查询提示词超出 LLM 模型的最大令牌数
FlorentineLLMErrorAPI_KEY_ISSUELLM API 密钥无效
FlorentineLLMErrorNO_RETURNFlorentine.ai 未收到有效的 LLM 返回结果
FlorentineLLMErrorRATE_LIMIT_EXCEEDEDLLM 请求过大
FlorentineConnectionErrorCONNECTION_REFUSED无法连接到数据库以执行查询
FlorentineCollectionErrorNO_EXECUTION创建的查询无法执行
FlorentinePipelineErrorMODIFICATION_FAILED修改查询管道失败
FlorentineUsageErrorLIMIT_REACHED套餐包含的 API 请求次数已全部用尽
FlorentineUnknownErrorUNKNOWN_ERROR所有发生的未知错误

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。