The OSDU MCP Server has 31 tools with mixed quality. Naming is generally strong (verb_noun convention: health_check, partition_list, legaltag_create, storage_get_record). Descriptions are present for all tools and range from 40-120 characters, meeting baseline minimums. However, parameter schemas are incomplete: while basic types are declared (string, boolean, object, array, integer), many lack formal constraints. For example, 'partition_id' appears in 5+ tools but has no enum/pattern validation, 'limit' parameters lack min/max bounds, and 'sort_order' accepts free-form strings instead of enums. Output schemas are entirely undocumented, there is no visible specification of what fields are returned by each tool. Error handling is not evident in the provided source (no recovery guidance, no error categorization visible). Security parameters appear handled server-side (auth_handler.py visible), but no explicit tool-level permission gates documented. Composition is strong: tools are single-responsibility (e.g., partition_list vs partition_get vs partition_create), and naming chains are clear (search_by_id → storage_get_record). The server uses FastMCP, which auto-generates schemas from function signatures, but the rubric requires VISIBLE, explicit schemas and descriptions in the source, many are inferred from decorators rather than documented.
Get groups for the current authenticated user
Check OSDU platform connectivity and service health
Retrieve multiple legal tags by name
Create a new legal tag (write-protected)
Delete a legal tag (delete-protected)
Retrieve a specific legal tag by name
Get allowed values for legal tag properties
Output schemas completely undocumented. No visible specification of return types or fields for any tool. The source shows parameter schemas inferred from FastMCP decorators, but no explicit documentation of what fields are returned (e.g., what does health_check return? What fields in a partition object?).
Parameter validation lacks formal constraints. 'limit' appears in 8+ tools with no min/max bounds (could accept -1 or 999999). 'sort_order' and 'status' fields lack enum validation. 'partition_id', 'name', 'id' fields lack pattern/format constraints. Free-form strings invite LLM hallucination.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 49 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 37 | - | v1 |
List all legal tags in the current partition
Search legal tags with filter conditions
Update an existing legal tag (write-protected)
Create a new partition (write-protected)
Delete a partition (delete-protected)
Retrieve configuration for a specific partition
List all accessible OSDU partitions
Update partition properties (write-protected)
Create a new schema (write-protected)
Retrieve complete schema by ID
List schemas with optional filtering
Advanced schema discovery with rich filtering and text search
Update an existing schema (write-protected)
Find specific records by ID
Find all records of specific type
Execute search queries using Elasticsearch syntax
Create or update records (write-protected)
Logically delete a record (delete-protected)
Retrieve multiple records at once
Get latest version of a record by ID
Get specific version of a record
List all versions of a record
Permanently delete a record (delete-protected)
Get record IDs of a specific kind
Destructive operations (partition_delete, legaltag_delete, storage_delete_record, storage_purge_record) accept a 'confirm' boolean but provide no dry_run option. LLMs may skip confirmation. Only partition_delete and partition_update offer dry_run; others do not. Inconsistent safety patterns.
No explicit error handling guidance visible. Descriptions do not indicate recovery paths (e.g., 'If partition not found, call partition_list() first'). No categorization of errors as retryable vs. user-fixable. LLMs will have no guidance on what to do when a call fails.
Tool descriptions lack operational context. Many are purely definitional (e.g., 'List all legal tags') without explaining WHEN to call (e.g., 'Call this before creating a legal tag to check valid values'). Descriptions average ~75 chars; optimal is 50-200 chars with intent context.
Pagination support incomplete. Tools accepting 'limit' and 'offset' do not document total_count or next_cursor in returns. Large result sets risk context window exhaustion. schema_list mentions 'offset' and 'limit' but no documented pagination response structure.
Tool permissions not declared. No scope annotations (e.g., 'read:partitions', 'write:legal_tags', 'delete:records'). Agents cannot be configured for least-privilege, and audit trails are unclear about what permissions each call requires.
Response field naming not documented. Tools like storage_fetch_records, legaltag_batch_retrieve return arrays but no visible contract for what fields each item contains. If response includes 'id' vs 'record_id' vs 'partition_id', downstream tool callers (storage_get_record, partition_get) cannot reliably chain outputs.
Dual write operations. storage_create_update_records and partition_update use 'properties' as generic object parameters with no schema for internal structure. Agents cannot infer valid fields without documentation.