Skip to content

Commit 41ca43d

Browse files
authored
Add 2nd Dockerfile for port 8000 (#144)
1 parent 51e9bdf commit 41ca43d

File tree

8 files changed

+62
-19
lines changed

8 files changed

+62
-19
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "elasticsearch-core-mcp-server"
3-
version = "0.4.2"
3+
version = "0.4.3"
44
edition = "2024"
55
authors = ["Elastic.co"]
66
license-file = "LICENSE"
@@ -22,7 +22,7 @@ serde = { version = "1.0", features = ["derive"] }
2222
serde_json = "1"
2323

2424
# CLI, config
25-
clap = { version = "4", features = ["derive"] }
25+
clap = { version = "4", features = ["derive", "env"] }
2626
dotenvy = "0.15"
2727
serde-aux = "4"
2828
serde_json5 = "0.2"

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ FROM cgr.dev/chainguard/wolfi-base:latest
2727

2828
COPY --from=builder /app/target/release/elasticsearch-core-mcp-server /usr/local/bin/elasticsearch-core-mcp-server
2929

30-
EXPOSE 8000/tcp
30+
EXPOSE 8080/tcp
3131
ENTRYPOINT ["/usr/local/bin/elasticsearch-core-mcp-server"]

Dockerfile-8000

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright Elasticsearch B.V. and contributors
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
# Custom image to start
5+
# To create a multi-arch image, run:
6+
# docker buildx build --platform linux/amd64,linux/arm64 --tag elasticsearch-core-mcp-server .
7+
8+
FROM rust:1.88 AS builder
9+
10+
WORKDIR /app
11+
12+
COPY Cargo.toml Cargo.lock ./
13+
14+
# Cache dependencies
15+
RUN --mount=type=cache,target=/usr/local/cargo/registry \
16+
--mount=type=cache,target=/app/target \
17+
mkdir -p ./src/bin && \
18+
echo "pub fn main() {}" > ./src/bin/elasticsearch-core-mcp-server.rs && \
19+
cargo build --release
20+
21+
COPY src ./src/
22+
23+
RUN cargo build --release
24+
25+
#--------------------------------------------------------------------------------------------------
26+
27+
FROM debian:stable-slim
28+
29+
RUN apt-get update && apt install -y libssl-dev && apt clean && rm -rf /var/lib/apt/lists/*
30+
31+
COPY --from=builder /app/target/release/elasticsearch-core-mcp-server /usr/local/bin/elasticsearch-core-mcp-server
32+
33+
ENV HTTP_ADDRESS="0.0.0.0:8000"
34+
35+
EXPOSE 8000/tcp
36+
ENTRYPOINT ["/usr/local/bin/elasticsearch-core-mcp-server"]
37+
CMD ["http"]

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ cluster's API key
9898
The MCP server is started in http mode with this command:
9999

100100
```bash
101-
docker run --rm -e ES_URL -p 8000:8000 docker.elastic.co/mcp/elasticsearch http
101+
docker run --rm -e ES_URL -p 8080:8080 docker.elastic.co/mcp/elasticsearch http
102102
```
103103

104104
If for some reason your execution environment doesn't allow passing parameters to the container, they can be passed
105-
using the `CLI_ARGS` environment variable: `docker run --rm -e ES_URL -e CLI_ARGS=http -p 8000:8000...`
105+
using the `CLI_ARGS` environment variable: `docker run --rm -e ES_URL -e CLI_ARGS=http -p 8080:8080...`
106106

107-
The streamable-HTTP endpoint is at `http:<host>:8000/mcp`. There's also a health check at `http:<host>:8000/ping`
107+
The streamable-HTTP endpoint is at `http:<host>:8080/mcp`. There's also a health check at `http:<host>:8080/ping`
108108

109109
Configuration for Claude Desktop (free edition that only supports the stdio protocol).
110110

src/bin/elasticsearch-core-mcp-server.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,22 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18+
use std::io::ErrorKind;
1819
use clap::Parser;
1920
use elasticsearch_core_mcp_server::cli::Cli;
2021
use tracing_subscriber::EnvFilter;
2122
// To test with stdio, use npx @modelcontextprotocol/inspector cargo run -p elastic-mcp
2223

2324
#[tokio::main]
2425
async fn main() -> anyhow::Result<()> {
26+
27+
// Also accept .env files
28+
match dotenvy::dotenv() {
29+
Err(dotenvy::Error::Io(io_err)) if io_err.kind() == ErrorKind::NotFound => {}
30+
Err(err) => return Err(err)?,
31+
Ok(_) => {}
32+
}
33+
2534
let env_args = std::env::vars().find(|(k, _v)| k == "CLI_ARGS").map(|(_k, v)| v);
2635

2736
let cli = if let Some(env_args) = env_args {
@@ -43,7 +52,7 @@ async fn main() -> anyhow::Result<()> {
4352
.with_ansi(false)
4453
.init();
4554

46-
tracing::info!("Starting MCP server");
55+
tracing::info!("Elasticsearch MCP server, version {}", env!("CARGO_PKG_VERSION"));
4756

4857
cli.run().await
4958
}

src/cli.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ pub struct HttpCommand {
4242
#[clap(short, long)]
4343
pub config: Option<PathBuf>,
4444

45-
/// Address to listen to [default: 127.0.0.1:8000]
46-
#[clap(long, value_name = "IP_ADDRESS:PORT")]
45+
/// Address to listen to [default: 127.0.0.1:8080]
46+
#[clap(long, value_name = "IP_ADDRESS:PORT", env = "HTTP_ADDRESS")]
4747
pub address: Option<std::net::SocketAddr>,
4848

4949
/// Also start an SSE server on '/sse'

src/lib.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ use is_container::is_container;
2828
use rmcp::transport::stdio;
2929
use rmcp::transport::streamable_http_server::session::never::NeverSessionManager;
3030
use rmcp::{RoleServer, Service, ServiceExt};
31-
use std::io::ErrorKind;
3231
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
3332
use std::path::PathBuf;
3433
use std::sync::Arc;
@@ -45,6 +44,7 @@ impl Cli {
4544
}
4645

4746
pub async fn run_stdio(cmd: StdioCommand) -> anyhow::Result<()> {
47+
tracing::info!("Starting stdio server");
4848
let handler = setup_services(&cmd.config).await?;
4949
let service = handler.serve(stdio()).await.inspect_err(|e| {
5050
tracing::error!("serving error: {:?}", e);
@@ -64,9 +64,9 @@ pub async fn run_http(cmd: HttpCommand) -> anyhow::Result<()> {
6464
let address: SocketAddr = if let Some(addr) = cmd.address {
6565
addr
6666
} else if is_container() {
67-
SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8000)
67+
SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 8080)
6868
} else {
69-
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8000)
69+
SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 8080)
7070
};
7171

7272
let ct = HttpProtocol::serve_with_config(
@@ -82,18 +82,15 @@ pub async fn run_http(cmd: HttpCommand) -> anyhow::Result<()> {
8282
)
8383
.await?;
8484

85+
tracing::info!("Starting http server at address {}", address);
86+
8587
tokio::signal::ctrl_c().await?;
8688
ct.cancel();
8789
Ok(())
8890
}
8991

9092
pub async fn setup_services(config: &Option<PathBuf>) -> anyhow::Result<impl Service<RoleServer> + Clone> {
91-
// Read config file and expand variables, also accepting .env files
92-
match dotenvy::dotenv() {
93-
Err(dotenvy::Error::Io(io_err)) if io_err.kind() == ErrorKind::NotFound => {}
94-
Err(err) => return Err(err)?,
95-
Ok(_) => {}
96-
}
93+
// Read config file and expand variables
9794

9895
let config = if let Some(path) = config {
9996
std::fs::read_to_string(path)?

0 commit comments

Comments
 (0)