使用说明
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 数组包含以下三个步骤的任意组合:
- 查询生成:问题转换为数据库查询(MongoDB聚合管道或MySQL查询)。
- 查询执行:查询使用您提供的连接字符串对数据库运行。
- 答案生成:结构化结果转换为自然语言答案。
提供退货类型
您有两个选项可以包含 returnTypes 数组:
- 随着
RETURN_TYPESenvMCP设置配置中的变量(可能在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_INPUTSenvMCP设置配置中的变量(可能在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_IDenvMCP设置配置中的变量(可能在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 |
所有发生的未知错误 |