OpenSearch Agent Server
July 29, 2026 · View on GitHub
A multi-agent orchestration server for OpenSearch Dashboards with context-aware routing and Model Context Protocol (MCP) integration.
Overview
OpenSearch Agent Server enables intelligent agent-based interactions within OpenSearch Dashboards by:
- Multi-Agent Orchestration — Routes requests to specialized agents based on context
- OpenSearch Integration — Connects to OpenSearch via MCP for real-time data access
- AG-UI Protocol — Implements OpenSearch Dashboard's agent UI protocol with SSE streaming
- Flexible LLM Support — Works with AWS Bedrock, Ollama, or other LLM providers
- Production Ready — Includes authentication, rate limiting, error recovery, and observability
Demo
https://github.com/user-attachments/assets/d465d805-40c9-4158-8e4b-0805c675df45
Architecture
OpenSearch Dashboards (AG-UI)
↓
OpenSearch Agent Server
├── Router (context-based)
├── Agent Registry
│ ├── ART Agent (strands-agents)
│ └── Default Agent
└── OpenSearch MCP Server
↓
OpenSearch Cluster
Features
- Context-Aware Routing — Automatically selects the appropriate agent based on request context
- Streaming Responses — Real-time SSE streaming for interactive user experiences
- Tool Execution — Agents can execute tools and visualize results in the dashboard
- Authentication & Authorization — JWT-based auth with configurable policies
- Rate Limiting — Protects backend services from overload
- Error Recovery — Automatic retry with exponential backoff
- Observability — Structured logging with request tracking
Prerequisites
- Python 3.12+
- OpenSearch 2.x (local or remote cluster)
- LLM Provider (choose one):
- AWS Bedrock (requires AWS credentials)
- Ollama (local installation)
Installation
-
Clone the repository
git clone https://github.com/opensearch-project/opensearch-agent-server.git cd opensearch-agent-server -
Create virtual environment
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate -
Install dependencies
pip install -e . -
Configure environment
cp .env.example .env # Edit .env with your configuration
Configuration
Create a .env file with the following settings:
# OpenSearch Connection
OPENSEARCH_URL=https://localhost:9200
OPENSEARCH_USERNAME=admin
OPENSEARCH_PASSWORD=admin
# Authentication (set to false for local development)
AG_UI_AUTH_ENABLED=false
# CORS (allow OpenSearch Dashboards origin)
AG_UI_CORS_ORIGINS=http://localhost:5601
# LLM Provider — uncomment the section for the provider you want to use:
# Option 1: AWS Bedrock
# AWS_ACCESS_KEY_ID=your_access_key
# AWS_SECRET_ACCESS_KEY=your_secret_key
# AWS_REGION=us-east-1
# BEDROCK_MODEL=us.anthropic.claude-sonnet-4-20250514-v1:0
# BEDROCK_SMALL_MODEL=us.anthropic.claude-haiku-4-5-20251001-v1:0
# Option 2: Ollama
# OLLAMA_HOST=http://localhost:11434
# OLLAMA_MODEL=llama3
# OLLAMA_SMALL_MODEL=llama3
# Logging
AG_UI_LOG_FORMAT=human
AG_UI_LOG_LEVEL=INFO
# Optional: additional skill paths. Use your OS's PATH separator
# (`:` on macOS/Linux, `;` on Windows). If unset, the agent auto-discovers
# skills in ~/.config/opensearch-agent-server/skills/ when that directory exists.
# NOTE: setting this disables the default location — include it explicitly
# if you still want those skills loaded.
# AG_UI_SKILL_PATHS=/path/to/skills-a:/path/to/skills-b
Loading additional skills
The default agent ships with bundled skills (e.g., ppl-reference). You can also load skills from external open-source registries such as opensearch-project/opensearch-agent-skills without forking this repo.
Two ways to add external skills:
1. Default location (zero config): clone into ~/.config/opensearch-agent-server/skills/.
git clone https://github.com/opensearch-project/opensearch-agent-skills.git \
~/.config/opensearch-agent-server/skills/opensearch-agent-skills
2. Custom paths: set AG_UI_SKILL_PATHS to one or more directories, separated like PATH (: on POSIX, ; on Windows). When set, the default location is not scanned.
export AG_UI_SKILL_PATHS=/opt/team-skills:/opt/official-skills
Verify skills loaded:
tail -f agent-quickstart/.logs/agent-server.log | grep skill_loader
You should see one skill_loader.loaded event per skill found.
Name collisions: if a user skill has the same name: (in its SKILL.md frontmatter) as a bundled skill, the bundled version wins and the user version is skipped — logged as skill_loader.duplicate at WARN level. To override, rename your skill's name field to something unique.
Trust model: skill files become part of the system prompt the LLM sees, so loading a skill is effectively trusting its author. Only point AG_UI_SKILL_PATHS at directories you control. The default ~/.config/opensearch-agent-server/skills/ is per-user and fine for single-user setups, but is inappropriate on shared or multi-tenant hosts — on those deployments, use an operator-controlled directory that end users cannot write to.
Quick Start
./scripts/quickstart.sh
This clones, builds, and starts everything in one command:
- Clones search-relevance and OpenSearch Dashboards (with the dashboards-search-relevance plugin)
- Bootstraps OSD and starts OpenSearch via
./gradlew run - Starts MCP Server (port 3001), OSD (port 5601), and Agent Server (port 8001)
- Creates a workspace with a local data source and loads demo data
- Runs a smoke test against all services
Prerequisites: Java 21+, Node.js 20+, Python 3.12+, uv, yarn, jq, curl
Access the Chat: Open http://localhost:5601 and click the chat icon in the header.
PyPI Installation
If you already have an OpenSearch cluster running and don't need the full quickstart setup, you can install and run the agent server directly from PyPI:
pip install opensearch-agent-server
Configure your environment:
export OPENSEARCH_URL=https://localhost:9200
export OPENSEARCH_USERNAME=admin
export OPENSEARCH_PASSWORD=admin
export AG_UI_AUTH_ENABLED=false
Start the agent server and MCP server together:
opensearch-agent-server --with-mcp
This starts both the OpenSearch MCP Server (port 3001) and the Agent Server (port 8001) in a single process. Both stop together on Ctrl+C.
# Verify
curl http://localhost:8001/health # {"status": "ok"}
curl http://localhost:8001/agents # list registered agents
You can also customize the MCP server port and config:
opensearch-agent-server --with-mcp --mcp-port 3002 --mcp-config ./custom_mcp.yml
Manual Setup
To run each component separately:
Terminal 1 - OpenSearch
# Start OpenSearch on port 9200
docker run -d -p 9200:9200 -p 9600:9600 \
-e "discovery.type=single-node" \
-e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=Admin1234!" \
opensearchproject/opensearch:latest
# Verify
curl http://localhost:9200 -u admin:Admin1234!
Terminal 2 - Agent Server
cd opensearch-agent-server
cp .env.example .env
# Edit .env with your settings
source .venv/bin/activate
python run_server.py
# Server starts on http://localhost:8001
Terminal 3 - OpenSearch Dashboards
cd OpenSearch-Dashboards
# Ensure config/opensearch_dashboards.yml has chat.agUiUrl configured
yarn start --no-base-path
# Dashboard opens on http://localhost:5601
Access the Chat
- Open http://localhost:5601
- Click the chat icon in the top-right header
- Start asking questions about your data!
Usage
Start the Server
python run_server.py
Or using uvicorn directly:
uvicorn server.ag_ui_app:app --host 0.0.0.0 --port 8001
The server will start on http://localhost:8001
Verify Installation
# Check server health
curl http://localhost:8001/health
# List available agents
curl http://localhost:8001/agents
# Test agent interaction (requires OpenSearch running)
curl -X POST http://localhost:8001/runs \
-H "Content-Type: application/json" \
-d '{
"input": "Show me recent logs",
"context": [{"appId": "discover"}]
}'
Integration with OpenSearch Dashboards
-
Start OpenSearch (port 9200)
# Using Docker docker run -d -p 9200:9200 -p 9600:9600 \ -e "discovery.type=single-node" \ -e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=Admin1234!" \ opensearchproject/opensearch:latest # Or use your local OpenSearch installation -
Start OpenSearch Agent Server (port 8001)
cd opensearch-agent-server source .venv/bin/activate python run_server.py -
Configure OpenSearch Dashboards
Edit
config/opensearch_dashboards.yml:# OpenSearch connection opensearch.hosts: ["http://localhost:9200"] opensearch.ssl.verificationMode: none # Enable new UI header (required for chat button) uiSettings: overrides: "home:useNewHomePage": true # Enable context provider (sends page context to agent) contextProvider: enabled: true # Enable chat with opensearch agent server chat: enabled: true agUiUrl: "http://localhost:8001/runs" -
Start OpenSearch Dashboards (port 5601)
cd OpenSearch-Dashboards yarn start --no-base-path -
Access the Chat Interface
- Open http://localhost:5601 in your browser
- Look for the chat icon in the top-right header
- Click to open the assistant panel
- Start chatting with your data!
Development
Install Development Dependencies
pip install -e ".[dev]"
Run Tests
pytest
Code Formatting
ruff format .
ruff check .
Project Structure
opensearch-agent-server/
├── src/
│ ├── agents/ # Agent implementations
│ │ ├── art/ # ART (Search Relevance Testing) agent
│ │ │ ├── art_agent.py # ART orchestrator agent
│ │ │ └── specialized_agents.py # Hypothesis, evaluation, UBI sub-agents
│ │ ├── base.py # Agent protocol / base types
│ │ └── default_agent.py # General OpenSearch assistant
│ ├── orchestrator/ # Routing and registry
│ │ ├── router.py # Context-based routing
│ │ └── registry.py # Agent registry
│ ├── server/ # FastAPI application
│ │ ├── ag_ui_app.py # Main FastAPI app and lifespan
│ │ ├── cli.py # CLI entry point (opensearch-agent-server command)
│ │ ├── agent_orchestrator.py # Orchestrator: routes requests to agents
│ │ ├── run_routes.py # AG-UI protocol endpoints
│ │ ├── config.py # Configuration management
│ │ └── ... # Middleware, auth, rate limiting, etc.
│ ├── tools/ # Agent tools (local computation)
│ │ └── art/ # ART-specific tools
│ │ └── experiment_tools.py # Experiment results aggregation
│ └── utils/ # Shared utilities
│ ├── mcp_connection.py # OpenSearch MCP client
│ ├── logging_helpers.py # Structured logging
│ ├── monitored_tool.py # Tool instrumentation wrapper
│ └── ... # Persistence, activity monitor, etc.
├── tests/
│ ├── helpers/ # Shared test helpers
│ ├── integration/ # Integration tests
│ └── unit/ # Unit tests
├── run_server.py # Entry point
├── pyproject.toml # Project metadata and dependencies
└── .env.example # Environment template
API Endpoints
Health Check
GET /health
Returns server health status.
List Agents
GET /agents
Returns available agents and their capabilities.
Create Run (AG-UI Protocol)
POST /runs
Creates a new agent run with streaming responses via SSE.
Get Run Status
GET /runs/{run_id}
Returns the status of a specific run.
Troubleshooting
OpenSearch Connection Issues
- Verify OpenSearch is running:
curl http://localhost:9200 - Check credentials in
.env - Disable SSL verification for local development
LLM Provider Issues
- AWS Bedrock: Ensure AWS credentials are configured
- Ollama: Verify Ollama is running:
ollama list
Port Conflicts
If port 8001 is in use, modify the startup command:
uvicorn server.ag_ui_app:app --host 0.0.0.0 --port 8002
Contributing
Contributions are welcome! Check out our:
- Contributing Guidelines — how to report bugs, request features, and submit pull requests
- Developer Guide — how to set up your environment and add a new agent
License
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
Acknowledgments
- Built with strands-agents for multi-agent orchestration
- Implements AG-UI Protocol for OpenSearch Dashboards
- Uses Model Context Protocol (MCP) for OpenSearch integration