Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions GNUmakefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ ifeq ($(enable_pax), yes)
endif
$(MAKE) -C gpMgmt all
$(MAKE) -C gpcontrib all
ifeq ($(enable_mcp_server), yes)
$(MAKE) -C mcp-server all
endif
+@echo "All of Apache Cloudberry successfully made. Ready to install."

docs:
Expand Down Expand Up @@ -84,6 +87,9 @@ ifeq ($(with_openssl), yes)
endif
$(MAKE) -C gpMgmt $@
$(MAKE) -C gpcontrib $@
ifeq ($(enable_mcp_server), yes)
$(MAKE) -C mcp-server $@
endif
+@echo "Apache Cloudberry installation complete."

install-docs:
Expand Down Expand Up @@ -116,6 +122,9 @@ clean:
# gpAux/Makefile is the entry point for the enterprise build, which ends up
# calling top-level configure and this Makefile
$(MAKE) -C gpMgmt $@
ifeq ($(enable_mcp_server), yes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should set this feature in src/Makefile.global.in?

$(MAKE) -C mcp-server $@
endif

# Important: distclean `src' last, otherwise Makefile.global
# will be gone too soon.
Expand All @@ -125,6 +134,9 @@ distclean maintainer-clean:
$(MAKE) -C gpcontrib $@
$(MAKE) -C config $@
$(MAKE) -C gpMgmt $@
ifeq ($(enable_mcp_server), yes)
$(MAKE) -C mcp-server $@
endif
$(MAKE) -C src $@
rm -rf tmp_install/
# Garbage from autoconf:
Expand Down
131 changes: 130 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,6 @@ with_gssapi
with_pythonsrc_ext
PIP3
CURL
PYTHON3
with_python
with_perl
with_tcl
Expand All @@ -759,6 +758,9 @@ ZSTD_LIBS
ZSTD_CFLAGS
PROTOBUF_LIBS
PROTOBUF_CFLAGS
UV
PYTHON3
enable_mcp_server
enable_preload_ic_module
enable_ic_proxy
enable_external_fts
Expand Down Expand Up @@ -911,6 +913,7 @@ enable_gpcloud
enable_external_fts
enable_ic_proxy
enable_preload_ic_module
enable_mcp_server
enable_pax
enable_thread_safety
with_icu
Expand Down Expand Up @@ -1633,6 +1636,7 @@ Optional Features:
library)
--disable-preload-ic-module
disable preload interconnect module
--enable-mcp-server enable MCP server support
--enable-pax enable PAX support
--disable-thread-safety disable thread-safety in client libraries
--enable-openssl-redirect
Expand Down Expand Up @@ -9245,6 +9249,131 @@ fi
$as_echo "checking whether to build with preload ic module ... $enable_preload_ic_module" >&6; }


#
# mcp-server
#


# Check whether --enable-mcp-server was given.
if test "${enable_mcp_server+set}" = set; then :
enableval=$enable_mcp_server;
case $enableval in
yes)

$as_echo "#define ENABLE_MCP_SERVER 1" >>confdefs.h

;;
no)
:
;;
*)
as_fn_error $? "no argument expected for --enable-mcp-server option" "$LINENO" 5
;;
esac

else
enable_mcp_server=no

fi


{ $as_echo "$as_me:${as_lineno-$LINENO}: result: checking whether to build with MCP server... $enable_mcp_server" >&5
$as_echo "checking whether to build with MCP server... $enable_mcp_server" >&6; }


# Check for required dependencies when mcp-server is enabled
if test "$enable_mcp_server" = yes; then
# Extract the first word of "python3", so it can be a program name with args.
set dummy python3; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_PYTHON3+:} false; then :
$as_echo_n "(cached) " >&6
else
case $PYTHON3 in
[\\/]* | ?:[\\/]*)
ac_cv_path_PYTHON3="$PYTHON3" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_PYTHON3="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS

;;
esac
fi
PYTHON3=$ac_cv_path_PYTHON3
if test -n "$PYTHON3"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
$as_echo "$PYTHON3" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


if test -z "$PYTHON3"; then
as_fn_error $? "python3 is required for --enable-mcp-server but was not found" "$LINENO" 5
fi

# Check for uv (Python package manager)
# Extract the first word of "uv", so it can be a program name with args.
set dummy uv; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_path_UV+:} false; then :
$as_echo_n "(cached) " >&6
else
case $UV in
[\\/]* | ?:[\\/]*)
ac_cv_path_UV="$UV" # Let the user override the test with a path.
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_UV="$as_dir/$ac_word$ac_exec_ext"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS

;;
esac
fi
UV=$ac_cv_path_UV
if test -n "$UV"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $UV" >&5
$as_echo "$UV" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi


if test -z "$UV"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: uv not found. MCP server build will attempt to use pip as fallback." >&5
$as_echo "$as_me: WARNING: uv not found. MCP server build will attempt to use pip as fallback." >&2;}
fi
fi

#
# pax support
#
Expand Down
24 changes: 24 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -942,6 +942,30 @@ PGAC_ARG_BOOL(enable, preload-ic-module, yes,
AC_MSG_RESULT([checking whether to build with preload ic module ... $enable_preload_ic_module])
AC_SUBST(enable_preload_ic_module)

#
# mcp-server
#
PGAC_ARG_BOOL(enable, mcp-server, no,
[enable MCP server support],
[AC_DEFINE(ENABLE_MCP_SERVER, 1,
[Define to 1 to build with MCP server support (--enable-mcp-server)])])
AC_MSG_RESULT([checking whether to build with MCP server... $enable_mcp_server])
AC_SUBST(enable_mcp_server)

# Check for required dependencies when mcp-server is enabled
if test "$enable_mcp_server" = yes; then
AC_PATH_PROG([PYTHON3], [python3])
if test -z "$PYTHON3"; then
AC_MSG_ERROR([python3 is required for --enable-mcp-server but was not found])
fi
Comment on lines +957 to +960
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we check the python version that is required by mcp-server?


# Check for uv (Python package manager)
AC_PATH_PROG([UV], [uv])
if test -z "$UV"; then
AC_MSG_WARN([uv not found. MCP server build will attempt to use pip as fallback.])
fi
fi

#
# pax support
#
Expand Down
145 changes: 145 additions & 0 deletions mcp-server/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Makefile for Apache Cloudberry MCP Server
#
# This Makefile integrates the Python-based MCP server into the
# Cloudberry build system. It uses uv (preferred) or pip for
# dependency management and installation.
#

# Get build configuration from top-level Makefile
subdir = mcp-server
top_builddir = ..
include $(top_builddir)/src/Makefile.global

# Installation directories
# Note: Use $(prefix) directly to avoid automatic /postgresql suffix added by $(datadir)
MCP_SERVER_BIN_DIR = $(prefix)/bin

# Python and package manager
# Note: fastmcp requires Python 3.10+
PYTHON3 ?= python3.11
UV ?= uv
PIP3 ?= pip3.11

# Determine which package manager to use
USE_UV := $(shell command -v $(UV) 2> /dev/null)

# Build directory
BUILD_DIR = dist
VENV_DIR = .venv

.PHONY: all build install installdirs uninstall clean distclean

all: build

# Build the MCP server package
build:
@echo "Building Apache Cloudberry MCP Server..."
ifdef USE_UV
@echo "Using uv for build..."
$(UV) build
else
@echo "Using pip for build..."
$(PYTHON3) -m pip install --upgrade build
$(PYTHON3) -m build
endif
@echo "MCP Server build complete."

# Install the MCP server
install: build installdirs
@echo "Installing Apache Cloudberry MCP Server..."
ifdef USE_UV
@echo "Installing with uv..."
$(UV) pip install --system --prefix=$(DESTDIR)$(prefix) $(BUILD_DIR)/*.whl
else
@echo "Installing with pip..."
$(PIP3) install --target=$(DESTDIR)$(prefix)/lib/python$$($(PYTHON3) -c "import sys; print('%d.%d' % (sys.version_info.major, sys.version_info.minor))")/site-packages $(BUILD_DIR)/*.whl
endif
@# Create a wrapper script for easier invocation
@echo '#!/bin/sh' > '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo '# Wrapper script for Apache Cloudberry MCP Server' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo '' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo '# Detect Python version and set PYTHONPATH' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo 'PYTHON_VERSION=$$($(PYTHON3) -c "import sys; print(\"python%d.%d\" % (sys.version_info.major, sys.version_info.minor))")' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo 'GPHOME="$$(cd "$$(dirname "$$0")/.." && pwd)"' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo 'export PYTHONPATH="$$GPHOME/lib/$$PYTHON_VERSION/site-packages:$$PYTHONPATH"' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo '' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo 'exec $(PYTHON3) -m cbmcp.server "$$@"' >> '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@chmod +x '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
@echo "MCP Server installation complete."
@echo "Installed to: $(DESTDIR)$(prefix)"
@echo "You can run it with: cloudberry-mcp-server"

# Create installation directories
installdirs:
$(MKDIR_P) '$(DESTDIR)$(MCP_SERVER_BIN_DIR)'

# Uninstall the MCP server
uninstall:
@echo "Uninstalling Apache Cloudberry MCP Server..."
rm -f '$(DESTDIR)$(MCP_SERVER_BIN_DIR)/cloudberry-mcp-server'
ifdef USE_UV
-$(UV) pip uninstall --system cloudberry-mcp-server 2>/dev/null || true
else
-$(PIP3) uninstall -y cloudberry-mcp-server 2>/dev/null || true
endif
@echo "MCP Server uninstalled."

# Clean build artifacts
clean:
@echo "Cleaning MCP Server build artifacts..."
rm -rf $(BUILD_DIR)
rm -rf $(VENV_DIR)
rm -rf build
rm -rf *.egg-info
rm -rf src/*.egg-info
find . -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
find . -type f -name '*.pyc' -delete 2>/dev/null || true
find . -type f -name '*.pyo' -delete 2>/dev/null || true
@echo "MCP Server cleaned."

# Distclean - remove all generated files
distclean: clean
@echo "Deep cleaning MCP Server..."
rm -rf .pytest_cache
rm -rf .coverage
rm -rf htmlcov
@echo "MCP Server distclean complete."

# Help target
help:
@echo "Apache Cloudberry MCP Server Makefile"
@echo ""
@echo "Available targets:"
@echo " all - Build the MCP server (default)"
@echo " build - Build the MCP server package"
@echo " install - Install the MCP server"
@echo " uninstall - Uninstall the MCP server"
@echo " clean - Remove build artifacts"
@echo " distclean - Remove all generated files"
@echo " help - Show this help message"
@echo ""
@echo "Configuration:"
@echo " PYTHON3 = $(PYTHON3)"
ifdef USE_UV
@echo " UV = $(UV) (using uv)"
else
@echo " PIP3 = $(PIP3) (using pip)"
endif
@echo " Install to = $(prefix)"
Loading