Florentine.ai MCP 服务器 - 与您的 MongoDB & MySQL 数据交谈
Florentine.ai 模式背景协议(MCP)服务器允许您集成 对您的 MongoDB & MySQL 数据进行自然语言查询 直接输入您的自定义 AI 代理或 AI 桌面 App .
问题由AI代理转发给MCP服务器,转换为数据库查询和 查询结果返回代理 供进一步处理.
还有一对夫妇 额外特性 例如:
- 安全的数据分离 用于多种租户用途
- 自动计划探索
- 语义矢量搜索/RAG支持 自动嵌入创建
- 高级搜索支持
- 钥匙的排除
说明: 如果你在找我们的API,你可以 找到这里。 。 。 .
目录
先决条件
- 节点.js >= v 18.0.0
- Florentine.ai账户(创建 这里的自由账户(中文(简体) )
- 一个连接的数据库和至少一个分析并激活了您的花旗上的收藏/表格 。 ai 账户
- 一个Florentine.ai API 密钥(您可以在您的 账户仪表板(中文(简体) )
安装
可找到 MCP 服务器的详细文件 在这里,我们的文件。 。 。 .
您可以使用 npx 轻松运行服务器 。 Claude桌面(claude_desktop_config.json:
{
"mcpServers": {
"florentine": {
"command": "npx",
"args": ["-y", "@florentine-ai/mcp", "--mode", "static"],
"env": {
"FLORENTINE_TOKEN": "<FLORENTINE_API_KEY>"
}
}
}
}
可用工具
- 弗洛伦丁 列表 收藏 . > 时间 列出所有可以查询的当前活动的收藏/表格。 这包括描述、键和数值类型.
- 花式( a) . > 时间 接收问答并返回查询、查询结果或回答(取决于
returnTypes设置).
参数
| 变量 | 需求 | 允许的值 | 说明 |
|---|---|---|---|
--mode | 对 | static, (中文(简体) ), dynamic | static (针对现有的外部MCP客户端,如克洛德桌面)或 dynamic (为自定义的 MCP 客户端). 见 整合模式部分。 。 。 . |
--debug | 没有 | true | 启用对外部文件的日志 。 如果设定需要 --logpath 也准备就绪. |
--logpath | 没有 | 绝对日志文件路径 | 调试日志的文件路径 。 如果设定需要 --debug 将被设定为 åwell. |
认证
佛罗伦萨.ai MCP 服务器使用API密钥认证请求. 您可以查看和管理您的 API 密钥 账户仪表板。键必须作为 ENV 变量添加到 MCP 服务器的配置设置中 :
"env": {
"FLORENTINE_TOKEN": "<FLORENTINE_API_KEY>"
}
连接您的 LLM 账户
佛罗伦萨。 。 带上自己的钥匙模型,所以您需要在您的 MCP 请求中提供您的 LLM API 密钥( OpenAI, Google, Anthropic, Deepseek) .
您有两个选项可以添加您的 LLM API 密钥 :
选项1: 在账户中保存您的 LLM 密钥( 建议)
连接您的 LLM 提供者的最简单方式是将您的 LLM API 密钥保存在您的 佛罗伦萨.ai仪表板。 。 。 .
- 添加您的 API 密钥
- 选择您的 LLM 提供者( OpenAI, Deepseek, Google 或 Anthropic)
- 单击保存

选项2:在 MCP 服务器配置插件变量中提供您的 LLM 密钥
如果你不想在佛罗伦萨储存钥匙的话 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 服务器配置的内置变量中, 它会覆盖存储在您的账户中的任何密钥 .
整合模式
你必须 设置操作模式 输入 args 您的 MCP 服务器配置的阵列 static 或者说 dynamic数字 :
"args": [
"-y",
"@florentine-ai/mcp",
"--mode",
"static"
]
静态模式
应使用静态模式 如果您将 Florentine.ai 整合到现有的外部 MCP 客户端 类似克洛德桌面或潜水AI.
单位 static 模式中,您将所有参数(如返回类型、必需输入等)设置为配置json中的嵌入变量。 这意味着,这些 参数将保持不变,直到更改设置配置 将随一切请求一同被送到佛罗伦萨。 见以下例子:
{
"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 | 没有 | 字符串 | 指定要使用的 LLM 提供者。 除非你没有在您的 Florentine.ai 账户中保存 LLM 密钥 见 连接您的 LLM 账户区域。 。 。 . |
LLM_KEY | 没有 | 字符串 | 您提供的 LLM 服务的 API 密钥 。 除非你没有在您的 Florentine.ai 账户中保存 LLM 密钥 见 连接您的 LLM 账户区域。 。 。 . |
RETURN_TYPES | 没有 | 结结 JSON | 返回类型 florentine_ask 工具调用。 见 返回类型部分。 。 。 . |
REQUIRED_INPUTS | 没有 | 结结 JSON | 所需投入。 见 所需输入部分。 。 。 . |
动态模式
应使用动态模式 如果您将 Florentine.ai 整合到您自定义的 MCP 客户端。 。 。 .
在动态模式下,您可以直接将所有参数(如返回类型、必需输入等)传递到 florentine_ask 工具。 这意味着你可以 动态向每个请求注入单个参数 转发至florentine.ai(即用户名).
为了能动态地通过数值,你必须 覆盖自定义客户端/代理服务器中的 florentine 任务工具方法。使用标准查看以下示例 @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 任务参数
| 变量 | 需求 | 类型 | 说明 |
|---|---|---|---|
sessionId | 没有 | 字符串 | 客户端的会话ID. 用于服务器侧聊天历史 。 见 会议部分。 。 。 . |
returnTypes | 没有 | Array<String> | 返回类型 florentine_ask 工具调用。 见 返回类型部分。 。 。 . |
requiredInputs | 没有 | Array<Object> | 所需投入。 见 所需输入部分。 。 。 . |
返回类型
默认情况下 florentine_ask 工具返回您 Florentine.ai 账户中配置的结果类型( 默认 ): result) (中文(简体) ). 你们可以 超过每个请求 通过指定一个 returnTypes 组合下列三个步骤的阵列:
- 查询生成:这个问题被转换为数据库查询(MongoDB聚合管或MySQL查询).
- 查询执行: 使用您提供的连接字符串查询数据库.
- 答案生成:结构化的结果被转化为自然语言的答案.
提供返回类型
您有两个选项要包含 returnTypes 数组 :
- 作为
RETURN_TYPESenv您的 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_INPUTSenv您的 MCP 设置配置中的变量( 可能在static财务报告和审定财务报表dynamic模式) - 作为
requiredInputs参数florentine_ask工具(可能仅存在于dynamic模式)
作为一个 env 变量以字符串化的json数组提供值 :
"env": {
"REQUIRED_INPUTS": "[{\"keyPath\":\"userId\",\"value\":\"507f1f77bcf86cd799439011\"}]"
}
作为工具参数,您以数组形式提供值 :
"requiredInputs": [
{
"keyPath": "userId",
"value": "507f1f77bcf86cd799439011"
}
]
您也可提供 database (单位:千美元) collections 阵列,如果您有相同的输入要求 keyPath 在多个收藏/表格中,但不同 value 用于收集/表格:
{
"requiredInputs": [
{
"keyPath": "name",
"value": "Sesame Street",
"database": "rentals",
"collections": ["houses"]
},
{
"keyPath": "name",
"value": { "$in": ["Ernie", "Bert"] },
"database": "rentals",
"collections": ["tenants"]
}
]
}
所需输入配置
| 外地 | 需求 | 类型 | 说明 | 制约因素 |
|---|---|---|---|---|
keyPath | 对 | 字符串 | 应过滤的去字段路径 . | 必须是有效的密钥路径 . |
value | 对 | 任意 | 要过滤的值( 类型, 见 支持的值类型) (中文(简体) ). | 必须匹配字段的类型( String, ObjectId, Boolean, 数字, 或 Date) . |
database | 没有 | 字符串 | 包含要过滤的收藏的数据库 . | 如果 collections 提供. |
collections | 没有 | Array<String> | 数据库中用于应用过滤器的具体收藏/表格. | 必须包含至少一个收藏/表 . |
支持的值类型
基于按键的值类型,您对您可以提供什么有不同的选项 Required Input 值 :
| 类型 | 格式示例 | 支持的运算符 | 页:1 |
|---|---|---|---|
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
使用大小写 : 用户只能看到自己产品的收入.
解决方案 : 限制账户访问一个特定账户.
const res = await FlorentineAI.ask({
question: 'Whats the revenue of my products?',
requiredInputs: [
{
keyPath: 'accountId',
value: '507f1f77bcf86cd799439011'
}
]
});
示例类型 : Boolean
使用大小写 : 对客户的每一次分析只能对付费客户进行.
解决方案 : 限制Paid Account只向付费客户开放.
const res = await FlorentineAI.ask({
question: 'How many customers registered in the last year?',
requiredInputs: [
{
keyPath: 'isPaidAccount',
value: true
}
]
});
示例类型 : Number
使用大小写 : 只应允许雇员看到低于某一数额的付款信息.
解决方案 : 限制获得金额低于10 000美元的付款.
const res = await FlorentineAI.ask({
question: 'List all payments we received.',
requiredInputs: [
{
keyPath: 'amount',
value: { $lt: 10000 }
}
]
});
示例类型 : Date
使用大小写 : 对财务数据的分析只应包括一年.
解决方案 : 2024年通过交易限制所有交易Date访问.
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_IDenv您的 MCP 设置配置中的变量( 可能在static财务报告和审定财务报表dynamic模式) - 作为
sessionId参数florentine_ask工具(可能仅存在于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"
}
}
| 外地 | 类型 | 说明 |
|---|---|---|
name | 字符串 | 错误类名称( 如 ). FlorentineApiError, (中文(简体) ), FlorentineConnectionError(中文(简体) ) |
statusCode | 编号 | HTTP状态代码(例如. 400, (中文(简体) ), 500(中文(简体) ) |
message | 字符串 | 对出错的解释 |
errorCode | 字符串 | 错误标识符(例如). NO_TOKEN, (中文(简体) ), INVALID_LLM_KEY(中文(简体) ) |
requestId | 字符串 | 此请求的唯一 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
}
你可以把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 | 需要历史聊天代号, 但缺少 |
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 | 所有发生未知错误 |