A dating profile management MCP server that handles user profile creation, updates, deletion, and matching with embedding-based similarity scoring
KnoliaConnectMCP demonstrates poor definition quality across most dimensions. While tool names follow verb_noun conventions (create_profile, update_profile, etc.), descriptions are generic and parameter documentation is severely lacking. Schemas are present in the source code but incomplete, many parameters lack descriptions, and nested objects lack proper field-level documentation. Error handling is minimal; most tools return generic error objects without recovery guidance. The server appears to be a dating/social profile management system but the tool definitions do not communicate this clearly to an LLM. Parameter interdependencies (e.g., sexual_preferences is required for profile creation but optional fields within it are not clarified) are undocumented. Output schemas are not formally documented, the code shows responses are dictionaries but the structure is not declared in the tool registration.
Tool to create a new profile
Tool to delete a profile
Get a profile by user_id
Get a random list of profiles with similarity scores relative to the given user_id
Get filtered profiles with advanced filtering options
Tool to update an existing profile
Tool to create or update a profile (upsert operation)
Descriptions lack context and are too generic. Examples: 'Tool to create a new profile' (30 chars), 'Tool to update an existing profile' (35 chars). These fall below the 50-char minimum for actionable descriptions and do not explain WHEN to call the tool or what happens. Baseline for A-grade tools is 194 chars avg.
Parameters within nested objects (sexual_preferences, personality_tags) lack descriptions. The ConnectProfile schema defines sexual_preferences as an object with gender, orientation, looking_for, but none of these fields have descriptions explaining valid values, constraints, or examples. LLMs cannot infer whether 'orientation' should be 'gay', 'Gay', 'homosexual', or an enum value.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 45 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 0 | - | v1 |
No enum constraints on open-ended string parameters. 'relationship_goals', 'orientation', 'gender', 'looking_for' are all free-form strings with no declared enums. An LLM could pass 'seeks romantic partner', 'romance', 'romantic', or 'partner', all potentially invalid. Enums are self-documenting and prevent hallucinated values.
Output schemas not documented. The source code shows tools return dictionaries (e.g., {'status': 'Profile created', 'user_id': user_id}) but these structures are not declared in tool registration. An LLM cannot plan downstream calls without knowing what fields are returned. For example, create_profile returns user_id, but this is not formally documented, so an agent cannot rely on it.
Error handling is non-actionable. Tools return {'error': str(e)} with generic exception messages. Example: A missing profile returns {'error': 'User profile not found.'} but does not suggest alternatives (e.g., 'Try search_profiles() to find a similar user'). No error classification (retryable vs fatal) is provided.
get_profiles and get_profiles_filtered return potentially massive unstructured lists. No pagination documented in tool description, no limit enforcement (limit defaults to 10 but is unbounded). If a query matches 10,000 profiles, returning all embeddings would blow context window. Baseline pattern requires explicit pagination.
Destructive operation (delete_profile) has no confirmation or dry-run support. An agent could permanently delete a user's profile in one call with no safety mechanism. No undo or recovery path is provided.
No rate limiting or timeout declared for tools calling OpenAI embeddings API. An agent could trigger expensive API calls in a loop without bounds. Tools calling external APIs should document expected latency and have explicit timeouts.
Parameter 'limit' in get_profiles and get_profiles_filtered has no documented range (min/max). Baseline requires bounds (e.g., 1 - 100). An LLM could pass limit=999999.
Ambiguous parameter naming in get_profiles_filtered. 'personality_match_type' is clear, but 'sort_by' defaults to 'similarity', the description does not enumerate other valid values. 'looking_for' could mean what the user is seeking or what they offer. Field naming inconsistencies force LLMs to reason about mappings.