Florentine.ai MCP server – query MongoDB & MySQL databases in natural language
The Florentine server exposes 2 tools with basic schemas and descriptions, but falls short of production quality on multiple critical dimensions. Tool naming follows a pattern (florentine_* prefix) but lacks clear verb-noun structure. The 'florentine_ask' tool has a moderately detailed description (~230 chars) and visible input schema with 4 parameters, but 'florentine_list_collections' has an empty input schema ({}) and a description that contains markdown formatting inconsistent with LLM optimization. Parameter descriptions are sparse: the 'question' parameter for 'ask' has a minimal description, and 'sessionId', 'requiredInputs', and 'returnTypes' lack any documentation in the source code visible here. Output schemas are not documented, the rubric requires explicit documentation of what each tool returns. Error handling exists (try-catch blocks, ZodError handling) but error messages are not visible in the tool registration code, making it impossible to verify if they guide recovery. The tools lack critical patterns: no idempotent hints, no pagination for list operations, no parameter constraints (enums, ranges), and no indication of data mutability or retry safety. Code shows fetch-based API calls to an external Florentine backend, suggesting the MCP server is a thin wrapper, but no documentation of the external API contract is visible.
Creates a query, executes it and returns the resulting data from a MongoDB or MySQL database for a question asked by the user. It can handle complex questions that require multiple steps, such as filtering, grouping, and sorting data. You should try to put as much information as possible in the question. Only do query decomposition if you are sure that the question is too complex for a single query.
Used internally to fetch metadata (name, summary, structure) of database collections **only when needed** to help answer a question via the "ask" tool. Should not be used alone.
florentine_list_collections has an empty input schema ({}), but accepts no parameters explicitly. Per hard scoring rules, this triggers a schema score of 0. The tool's description also uses markdown formatting (**only when needed**) which is not LLM-optimized.
florentine_ask has 4 input parameters (question, sessionId, requiredInputs, returnTypes), but the source code shows NO DESCRIPTIONS for sessionId, requiredInputs, or returnTypes. Per hard scoring rules, parameters lacking descriptions trigger a cap on schema score. The 'question' parameter has only 'The question to ask about the database', 6 words, providing minimal guidance on format or length constraints.
No output schemas are documented for either tool. The rubric (Section D, SCHEMAS & OUTPUT) mandates that 'Tools returning lists should accept page/offset and limit parameters and return a total count or next_cursor' and '100% of A+ tools have documented return types.' florentine_list_collections returns a 'summaries' field based on the code, but no count, pagination, or structure is documented.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 46 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 37 | - | v1 |
The 'florentine_ask' tool accepts a 'returnTypes' parameter described as 'an array specifying which response types to return (query, result, answer)' but provides no enum constraint. LLMs will hallucinate invalid values; enums are mandatory for constrained choice parameters. Additionally, 'requiredInputs' and 'sessionId' lack any description of their format, purpose, or constraints.
Error handling is present in the code (try-catch, ZodError parsing) but error messages are not visible in the tool registration. The registerTools method returns generic ToolResponseSchema with isError=true, but no recovery guidance (e.g., 'Try query decomposition' or 'Check database connection') is evident. Per pattern:recovery-guide, errors must tell the LLM what to do next.
Tool naming uses a 'florentine_' prefix which is more of a namespace than an action verb. Best practice (arcade.dev/patterns/tool) recommends verb_noun naming (e.g., 'list_collections' not 'florentine_list_collections', or keep prefix if it's a domain but pair with clearer verbs). More critically, both tools lack any annotation of their mutability: is florentine_ask read-only or does it have side effects? The readOnlyHint/destructiveHint annotations (current spec patterns) are absent.
The description for florentine_ask mentions 'sessionId' for 'server side chat history' but does not clarify: (1) Is sessionId required or optional? (2) What is the format (UUID, integer, string)? (3) Can an empty sessionId be used for stateless calls? (4) Do sessions persist across client restarts? LLMs cannot infer this from the parameter name alone.