This server has severe structural deficiencies. Of 17 tools, 8 lack ANY parameter descriptions (scoring 0 on description). All tools lack documented output schemas. Parameter names are bare (e.g., 'id', 'limit') without type guidance in descriptions. Most critically, destructive operations (delete_gpu_instance, delete_ssh_key) lack idempotency hints, confirmation patterns, or error recovery guidance. Naming is consistent (verb-first), but descriptions are thin and don't explain WHEN to use each tool vs. alternatives. This is well below production quality.
Tools (17)
create_gpu_instancewriteauthsource verified53/100
Create GPU Instances.
Create an instance with the specified custom configuration and features provided in the request body.
8 of 17 tools completely lack parameter descriptions. Parameters like 'id', 'limit', 'offset' have no type guidance, format hints, or constraints in tool docstrings. LLMs cannot infer whether 'id' should be a UUID, numeric, or alphanumeric string.
No tool defines or documents output schema. Callers cannot predict response structure, required fields, or chaining IDs. This prevents LLMs from confidently composing downstream operations (e.g., get_user_instances returns id, but create_gpu_instance expects 'id' as instance reference, unclear if they are compatible).
Add complete docstrings to all 8 tools that lack descriptions. Each must be 50 - 200 chars and explain WHAT the tool does, WHEN to use it, and any prerequisites. Example for get_user_instances: 'Retrieve a paginated list of your compute instances. Use this to discover available instances before starting, stopping, or rebooting them.'
Document output schemas for all tools. Create a JSON response model showing required fields (e.g., 'get_user_instances returns {instances: [{id: string, name: string, status: enum[running|stopped|error], created_at: ISO8601}], total: integer, next_cursor?: string}'). This is critical for tool chaining.
Add parameter descriptions to all 8 undescribed parameters. For each of 'id', 'limit', 'offset', 'instance_name', 'product_id', 'image_id', 'ssh_key_id', 'key_name', 'key_data': describe the type, format, range, and constraints. Example: 'instance_id: UUID format (e.g. 550e8400-e29b-41d4-a716-446655440000) of the instance to delete. This action is irreversible.'
Rename bare 'id' parameters to fully-qualified names: 'instance_id', 'ssh_key_id'. This removes ambiguity for LLMs and matches other tools' conventions.
Add destructive operation guards: implement a dry-run mode or confirmation step for delete_gpu_instance and delete_ssh_key. Alternatively, return a clear response structure like {status: 'scheduled_for_deletion', confirmation_token: '...', expires_in: 3600} requiring a second call with the token. Document this pattern in tool descriptions.
Document pagination for list_* tools. Add: 'Results are paginated (max 50 items per page). Pass limit (1 - 100, default 20) and offset (0-based index) to navigate. Response includes total_count and has_next_page for discovery.'
List Available OS Images.
Return a list of all available operating system images, including details about each image's version and driver, if applicable.
Destructive tools (delete_gpu_instance, delete_ssh_key) lack confirmation/dry-run patterns, idempotency hints, or error recovery guidance. LLMs cannot safely invoke these without risk of irreversible accidents. No documentation of what 'delete' actually does (soft vs. hard delete), whether it can be undone, or failure modes.
Parameters lack type and range constraints in descriptions. 'limit' and 'offset' appear in 4 tools with no documented ranges (e.g., 'limit must be 1 - 100, default 20'). This invites LLMs to pass absurd values (0, -1, 999999) that may break pagination or cause timeouts.
No documented error handling or recovery guidance. Code calls response.raise_for_status() and returns response.json(), but tool descriptions never explain what errors can occur (401 auth failure, 404 instance not found, 422 invalid instance ID format, timeout, rate limit). LLMs lack guidance on retryability or next steps.
No output pagination documented. Tools like list_user_instances and list_user_invoices accept limit/offset but descriptions never state result cap, total count return, or how to fetch next page. LLMs may miss that results could be truncated.
Tool descriptions under 20 characters for 8 tools (e.g., no description at all, or only function name). Examples: get_user_instances, list_api_keys, list_ssh_keys have no docstring at all.
Parameters named 'id' without type suffix. Best practice is 'instance_id', 'ssh_key_id' to disambiguate. Using bare 'id' leaves LLMs uncertain whether the value is a UUID, numeric, or alphanumeric string. See delete_gpu_instance, delete_ssh_key, get_user_instance_detail.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) in schema. Modern MCP requires these to help clients identify risky operations. All 17 tools lack @mcp.tool(...) annotations with hint metadata.
API credentials (NEBULA_BLOCK_API_KEY) are loaded via environment variables and used directly in tool implementations, which is correct. However, there is no documentation in tool descriptions explaining authentication requirements or permission scopes (e.g., 'Requires read:computing', 'Requires write:instances'). This limits auditability and least-privilege configuration.
Add error recovery guidance to all write/destructive tools. Example for delete_gpu_instance: 'Errors: 401 Unauthorized (invalid API key), 404 Instance not found (verify ID via get_user_instances), 422 Instance is currently running (stop it first), 429 Rate limited (wait 60s). See get_user_instances to verify the instance exists before retrying.'
Add tool annotations (readOnlyHint, destructiveHint, idempotentHint) to fastmcp tool registration. Example: @mcp.tool('delete_gpu_instance', hints={'destructiveHint': True, 'idempotentHint': False}). This signals clients to warn before executing.
Document idempotency. For write tools, state: 'Idempotent: Multiple calls with the same instance_id (if instance still exists) return the same result. If instance has already been deleted, returns 404.' This guides LLM retry behavior.
Add scope declarations to all tools. Prepend descriptions with scope hints: 'Scope: read:computing' for read tools, 'Scope: write:instances' for write tools, 'Scope: admin:billing' for billing tools. This enables least-privilege agent configs.
Validate inputs early and return actionable errors. Instead of letting requests.get() raise a 500 error, catch common failures and return: {'error': 'Invalid instance_id format. Expected UUID (e.g. 550e8400-e29b-41d4-a716-446655440000), got: abc123. Call list_user_instances() to find valid IDs.'}
Cap result sets: list_* tools should return max 50 items by default, with pagination. Update descriptions: 'Returns up to 50 instances. Use offset to fetch additional pages.'
Enriched error responses: when delete_gpu_instance fails with 'instance not found', return alternatives: {'error': 'Instance xyz not found', 'suggestion': 'Call get_user_instances() to see available instances: [list of 5 running instances]'}. This prevents dead-ending.