Skip to content

Commit 75132a7

Browse files
Merge pull request #40 from openapi/dev
Update packaging and documentation for PyPI release 0.3.1
2 parents 3e86952 + 769e8ea commit 75132a7

3 files changed

Lines changed: 168 additions & 10 deletions

File tree

docs/readme-pypi.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ Use it in two ways:
99
- **Python library** — import `openapi_mcp_sdk` in your own project to build a
1010
custom MCP server on top of openapi.com APIs.
1111

12-
---
1312

1413
## Run the server
1514

@@ -31,7 +30,6 @@ pipx run openapi-mcp-sdk server
3130
pip install openapi-mcp-sdk && openapi-mcp-sdk server
3231
```
3332

34-
---
3533

3634
## Local launcher script
3735

@@ -59,7 +57,6 @@ Next time, just run:
5957
bash mcp-server.sh
6058
```
6159

62-
---
6360

6461
## CLI reference
6562

@@ -72,7 +69,6 @@ Commands:
7269
token Generate or inspect an openapi.com Bearer token [coming soon]
7370
```
7471

75-
---
7672

7773
## MCP client configuration
7874

@@ -110,7 +106,6 @@ Get your Bearer Token at [console.openapi.com](https://console.openapi.com/oauth
110106
The server automatically promotes `?token=` to an `Authorization: Bearer` header,
111107
so both methods behave identically.
112108

113-
---
114109

115110
## Links
116111

pyproject.toml

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,44 @@
11
[project]
22
name = "openapi-mcp-sdk"
3-
version = "0.3.0"
4-
description = "Openapi.com official mcp server implementation"
3+
version = "0.3.1"
4+
description = "Openapi.com official MCP server — ready-to-use gateway and Python SDK for AI agents"
55
readme = "docs/readme-pypi.md"
66
requires-python = ">=3.13"
77
license = "MIT"
8+
license-files = ["LICENSE"]
9+
keywords = [
10+
"mcp",
11+
"model-context-protocol",
12+
"openapi",
13+
"ai",
14+
"llm",
15+
"agent",
16+
"fastapi",
17+
"sdk",
18+
"gateway",
19+
"claude",
20+
"anthropic",
21+
"tools",
22+
"api",
23+
]
824
classifiers = [
9-
"License :: OSI Approved :: MIT License",
25+
"Development Status :: 4 - Beta",
26+
"Intended Audience :: Developers",
27+
"Topic :: Software Development :: Libraries :: Python Modules",
28+
"Topic :: Internet :: WWW/HTTP :: HTTP Servers",
29+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
30+
"Operating System :: OS Independent",
1031
"Programming Language :: Python :: 3",
1132
"Programming Language :: Python :: 3.13",
1233
]
34+
authors = [
35+
{ name = "Francesco Bianco", email = "info.francescobianco@gmail.com" },
36+
{ name = "Marco Prosperi", email = "m.prosperi@openapi.com" },
37+
{ name = "Simone Desantis", email = "s.desantis@openapi.com" },
38+
]
39+
maintainers = [
40+
{ name = "openapi.com", email = "support@openapi.com" },
41+
]
1342
dependencies = [
1443
"expiringdict>=1.2.2",
1544
"fastmcp>=2.9.1",
@@ -21,8 +50,11 @@ dependencies = [
2150
"fastapi>=0.110.0",
2251
]
2352

24-
[tool.setuptools]
25-
license-files = ["LICENSE"]
53+
[project.urls]
54+
Homepage = "https://openapi.com/"
55+
Repository = "https://github.com/openapi/mcp-server"
56+
"Bug Tracker" = "https://github.com/openapi/mcp-server/issues"
57+
Changelog = "https://github.com/openapi/mcp-server/releases"
2658

2759
[tool.pytest.ini_options]
2860
testpaths = ["tests/pytest"]

tests/env/test-mcp-port.sh

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#!/usr/bin/env bash
2+
# =============================================================================
3+
# tests/env/test-mcp-port.sh
4+
# =============================================================================
5+
# Verifies that the MCP_PORT environment variable actually changes the port
6+
# the server binds to. Starts the server twice:
7+
# 1. default (no MCP_PORT) → expects port 8080
8+
# 2. custom (MCP_PORT=19876) → expects port 19876, NOT 8080
9+
#
10+
# Does NOT require an OPENAPI_TOKEN — only checks TCP connectivity.
11+
#
12+
# Usage:
13+
# bash tests/env/test-mcp-port.sh
14+
#
15+
# Exit code: 0 if all tests pass, 1 if any fail.
16+
# =============================================================================
17+
set -euo pipefail
18+
19+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20+
ROOT_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
21+
SRC_DIR="$ROOT_DIR/src"
22+
23+
CUSTOM_PORT=19876
24+
DEFAULT_PORT=8080
25+
WAIT_TIMEOUT=20
26+
27+
PASS=0
28+
FAIL=0
29+
SERVER_PID=""
30+
31+
# --- Colors ---
32+
GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; NC='\033[0m'
33+
34+
pass() { printf "${GREEN}[PASS]${NC} %s\n" "$1"; PASS=$((PASS+1)); }
35+
fail() { printf "${RED}[FAIL]${NC} %s\n" "$1"; FAIL=$((FAIL+1)); }
36+
info() { printf "${YELLOW}[INFO]${NC} %s\n" "$1"; }
37+
section() { printf "\n${CYAN}=== %s ===${NC}\n" "$1"; }
38+
39+
kill_server() {
40+
if [ -n "$SERVER_PID" ] && kill -0 "$SERVER_PID" 2>/dev/null; then
41+
kill "$SERVER_PID" 2>/dev/null || true
42+
wait "$SERVER_PID" 2>/dev/null || true
43+
SERVER_PID=""
44+
fi
45+
}
46+
47+
cleanup() {
48+
kill_server
49+
}
50+
trap cleanup EXIT
51+
52+
# Wait up to $WAIT_TIMEOUT seconds for a TCP port to be reachable.
53+
wait_for_port() {
54+
local port="$1"
55+
for i in $(seq 1 "$WAIT_TIMEOUT"); do
56+
if curl -s --max-time 1 -o /dev/null "http://localhost:${port}/" 2>/dev/null; then
57+
info "Port ${port} ready after ${i}s"
58+
return 0
59+
fi
60+
sleep 1
61+
done
62+
return 1
63+
}
64+
65+
# Check that a port is NOT listening (give it a moment to confirm absence).
66+
port_is_closed() {
67+
local port="$1"
68+
! curl -s --max-time 1 -o /dev/null "http://localhost:${port}/" 2>/dev/null
69+
}
70+
71+
start_server() {
72+
local port="$1"
73+
MCP_PORT="$port" PYTHONPATH="$SRC_DIR" \
74+
python3 -m openapi_mcp_sdk.main \
75+
> /dev/null 2>&1 &
76+
SERVER_PID=$!
77+
}
78+
79+
# =============================================================================
80+
# STEP 1 — Custom port (MCP_PORT=19876)
81+
# =============================================================================
82+
section "MCP_PORT=${CUSTOM_PORT} — server binds on custom port"
83+
84+
info "Starting server with MCP_PORT=${CUSTOM_PORT}..."
85+
start_server "$CUSTOM_PORT"
86+
87+
if wait_for_port "$CUSTOM_PORT"; then
88+
pass "Server is reachable on port ${CUSTOM_PORT}"
89+
else
90+
fail "Server did not come up on port ${CUSTOM_PORT} within ${WAIT_TIMEOUT}s"
91+
fi
92+
93+
if port_is_closed "$DEFAULT_PORT"; then
94+
pass "Port ${DEFAULT_PORT} (default) is NOT open — custom port was used"
95+
else
96+
fail "Port ${DEFAULT_PORT} (default) is also open — MCP_PORT was ignored"
97+
fi
98+
99+
kill_server
100+
101+
# Give the OS a moment to release the ports before the next step.
102+
sleep 2
103+
104+
# =============================================================================
105+
# STEP 2 — Default port (no MCP_PORT set)
106+
# =============================================================================
107+
section "No MCP_PORT — server binds on default port ${DEFAULT_PORT}"
108+
109+
info "Starting server without MCP_PORT..."
110+
start_server "$DEFAULT_PORT"
111+
112+
if wait_for_port "$DEFAULT_PORT"; then
113+
pass "Server is reachable on default port ${DEFAULT_PORT}"
114+
else
115+
fail "Server did not come up on default port ${DEFAULT_PORT} within ${WAIT_TIMEOUT}s"
116+
fi
117+
118+
if port_is_closed "$CUSTOM_PORT"; then
119+
pass "Port ${CUSTOM_PORT} (custom) is NOT open — default port was used"
120+
else
121+
fail "Port ${CUSTOM_PORT} (custom) is also open — unexpected"
122+
fi
123+
124+
kill_server
125+
126+
# =============================================================================
127+
# Summary
128+
# =============================================================================
129+
printf "\n"
130+
printf "Results: ${GREEN}%d passed${NC}, ${RED}%d failed${NC}\n" "$PASS" "$FAIL"
131+
[ "$FAIL" -eq 0 ]

0 commit comments

Comments
 (0)