MCP server for OpenSearch Dashboards
Server has 5 tools with complete descriptions and mostly well-defined schemas. Tool names follow verb_noun convention (ping, list_saved_objects, get_tenants, get_index_patterns, discover_search). Descriptions are detailed (100-400 chars) and explain WHAT, WHEN, and dependencies. Parameters have types and descriptions. However, output schemas are not formally documented, only inferred from code. Error handling is minimal; no guidance on recovery or retryability. No input validation or constraint enforcement visible. Missing tool annotations (readOnlyHint, idempotentHint). Pagination is present but not consistently applied.
Fetch documents like the Discover app. Runs a search against an index pattern through the internal search API that OpenSearch Dashboards' Discover uses (``/internal/search/opensearch``), so it works even when the raw OpenSearch REST API is not exposed. - ``index``: index-pattern glob, e.g. ``logs-api-*`` (discover them via ``list_saved_objects`` with ``type_="index-pattern"``) - ``query``: Lucene query_string, e.g. ``level:error AND service:api``. ``None`` matches everything. - ``time_from`` / ``time_to``: range on ``time_field``, e.g. ``now-15m`` / ``now`` or an ISO timestamp. Both optional. - ``time_field``: timestamp field to filter/sort on (default ``@timestamp``). - ``size``: max hits to return (default 10; keep small — these are logs). - ``fields``: restrict ``_source`` to these fields to avoid flooding the context. ``None`` returns the full document. - ``tenant``: ``securitytenant`` header; usually unnecessary for raw data. Returns ``{index, total, count, hits: [{_id, _index, _source}]}`` where ``total`` is the full match count (may be an estimate for large indices).
List index patterns configured in OpenSearch Dashboards. Index patterns are saved objects of type ``index-pattern``. Returns ``{id, title, time_field}`` where ``title`` is the pattern glob (e.g. ``logs-*``) and ``time_field`` its time field, if any.
List multi-tenancy tenants configured in OpenSearch Dashboards. Uses the security plugin config API (``/api/v1/configuration/tenants``), which returns a map of tenant name -> metadata. Flattened here to a list of ``{name, description, reserved, hidden}``.
List saved objects of a given type (dashboard, index-pattern, search, ...). Calls the Dashboards ``saved_objects/_find`` API and returns a compact list of ``{id, title, type}`` so the LLM is not flooded with raw fields. Saved objects are stored per multi-tenancy tenant. ``tenant`` selects which one to read via the ``securitytenant`` header: - a tenant name (e.g. "Developers Core", "Global") - "__user__" for the caller's private tenant - None (default) uses the user's configured default tenant Use the ``get_tenants`` tool to discover available tenant names.
Output schemas not formally documented. Code infers return structure (e.g., {connected, authenticated, user, tenants} for ping; {index, total, count, hits} for discover_search), but no JSON Schema or explicit schema definition visible. LLMs cannot reliably plan downstream tool calls without knowing response structure.
No input validation or error guidance. Tools accept parameters but do not validate enums, ranges, or formats. discover_search accepts arbitrary Lucene queries and time ranges with no validation. If invalid input is passed, error responses are likely raw HTTP errors rather than actionable guidance (e.g., 'Invalid time_from format: expected ISO 8601 or relative (now-15m)').
Missing tool annotations. No readOnlyHint, destructiveHint, or idempotentHint visible. All tools are read-only (safe to retry), but this is not declared. Agents cannot infer safety without explicit annotations.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 58 | 2026-07-28+ | v2 |
Check OpenSearch Dashboards connectivity and authenticate. Hits the security authinfo endpoint. If unauthenticated (HTTP 401) and credentials are configured, performs a session login and re-checks. Reports {connected, authenticated, user, tenants} or the error reason.
Pagination inconsistency. list_saved_objects and get_index_patterns accept per_page but do not return next_cursor or pagination metadata. discover_search has no pagination at all (size param only). Large result sets risk context window exhaustion.
Parameter constraints not enforced. discover_search size defaults to 10 but no min/max bounds documented. time_field defaults to '@timestamp' but no validation that it exists in the index. Lucene query parameter accepts free-form strings with no syntax validation.