Skip to content

Commit 18c4efa

Browse files
authored
Merge pull request #40 from CogStack/doc-n-reorg
Improve READMEs and refactor the OAuth flow
2 parents de5e049 + 876b8fb commit 18c4efa

11 files changed

Lines changed: 123 additions & 609 deletions

File tree

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
Cogstack ModelServe (CMS) is a model-serving and model-governance system created for a range of CogStack NLP tasks. Targeting language models with NER and entity linking capabilities, CMS provides a one-stop shop for serving and fine-tuning models, training lifecycle management, as well as monitoring and end-to-end observability.
44

5+
[![build](https://img.shields.io/github/actions/workflow/status/CogStack/CogStack-ModelServe/main.yaml)](https://github.com/CogStack/CogStack-ModelServe/actions)
6+
[![release](https://img.shields.io/github/v/release/CogStack/CogStack-ModelServe)](https://github.com/CogStack/CogStack-ModelServe/releases)
7+
[![docker](https://img.shields.io/docker/v/cogstacksystems/cogstack-modelserve?sort=semver&label=docker)](https://hub.docker.com/r/cogstacksystems/cogstack-modelserve)
8+
[![python](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue)](https://www.python.org/)
9+
[![license](https://img.shields.io/badge/license-Apache%20License%202.0-blue)](https://github.com/CogStack/CogStack-ModelServe/blob/main/LICENSE)
10+
511
## Install Dependencies
612
A virtual environment is highly recommended prior to installation. To install the dependencies, run:
713
```commandline
@@ -254,6 +260,15 @@ Note that to enable quantization and training features, you need to install the
254260
```commandline
255261
pip install '.[llm]'
256262
```
263+
264+
### CMS MCP server
265+
You can run an MCP server to expose local or remote CMS capabilities to your preferred MCP client.
266+
To that end, install the following extra dependencies:
267+
```commandline
268+
pip install '.[mcp]'
269+
```
270+
For detailed configuration, please refer to the [CMS MCP Server docs](./app/mcp/README.md).
271+
257272
#### Chat with served models
258273
You can also "chat" with the running model using the `/stream/ws` endpoint. For example:
259274
```html

app/api/utils.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -323,8 +323,8 @@ async def init_vllm_engine(app: FastAPI,
323323
)
324324
from vllm import SamplingParams, TokensPrompt
325325
except ImportError:
326-
logger.error("Cannot import the vLLM engine. Please install it with `pip install cms[llm]`.")
327-
raise ExtraDependencyRequiredException("Cannot import the vLLM engine. Please install it with `pip install cms[llm]`.")
326+
logger.error("Cannot import the vLLM engine. Please install it with `pip install '.[llm]'`.")
327+
raise ExtraDependencyRequiredException("Cannot import the vLLM engine. Please install it with `pip install '.[llm]'`.")
328328

329329
parser = FlexibleArgumentParser()
330330
parser = make_arg_parser(parser)

app/cli/cli.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ def run_mcp_server(
599599
transport: str = typer.Option("http", help="The transport type (either 'stdio', 'sse' or 'http')"),
600600
cms_base_url: str = typer.Option("http://127.0.0.1:8000", help="The base URL of the CMS API"),
601601
cms_api_key: str = typer.Option("Bearer", help="The API key for authenticating with the CMS API"),
602-
mcp_api_keys: str = typer.Option("", help="Comma-separated API keys for authenticating MCP clients"),
602+
cms_mcp_api_keys: str = typer.Option("", help="Comma-separated API keys for authenticating CMS MCP clients"),
603603
cms_mcp_oauth_enabled: Optional[bool] = typer.Option(None, help="Whether to enable OAuth2 authentication for MCP clients"),
604604
github_client_id: str = typer.Option("", help="The GitHub OAuth2 client ID"),
605605
github_client_secret: str = typer.Option("", help="The GitHub OAuth2 client secret"),
@@ -618,6 +618,13 @@ def run_mcp_server(
618618
port (int): The port of the MCP server. Defaults to 8080.
619619
transport (str): The transport type for the MCP server. Can be "stdio" or "http". Defaults to "stdio".
620620
cms_base_url (str): The base URL of the CMS API endpoint. Defaults to "http://localhost:8000".
621+
cms_api_key (str): The API key for authenticating with the CMS API. Defaults to "Bearer".
622+
cms_mcp_api_keys (str): Comma-separated API keys for authenticating CMS MCP clients. Defaults to "".
623+
cms_mcp_oauth_enabled (Optional[bool]): Whether to enable OAuth2 authentication for MCP clients. Defaults to None.
624+
github_client_id (str): The GitHub OAuth2 client ID, required if cms_mcp_oauth_enabled is True. Defaults to "".
625+
github_client_secret (str): The GitHub OAuth2 client secret, required if cms_mcp_oauth_enabled is True. Defaults to an "".
626+
google_client_id (str): The Google OAuth2 client ID, required if cms_mcp_oauth_enabled is True. Defaults to an "".
627+
google_client_secret (str): The Google OAuth2 client secret, required if cms_mcp_oauth_enabled is True. Defaults to an "".
621628
debug (Optional[bool]): Run in debug mode if set to True.
622629
"""
623630

@@ -629,7 +636,7 @@ def run_mcp_server(
629636
os.environ["CMS_MCP_SERVER_PORT"] = str(port)
630637
os.environ["CMS_MCP_TRANSPORT"] = transport.lower()
631638
os.environ["CMS_API_KEY"] = cms_api_key
632-
os.environ["MCP_API_KEYS"] = mcp_api_keys
639+
os.environ["CMS_MCP_API_KEYS"] = cms_mcp_api_keys
633640
os.environ["CMS_MCP_OAUTH_ENABLED"] = "true" if cms_mcp_oauth_enabled else "false"
634641
os.environ["GITHUB_CLIENT_ID"] = github_client_id
635642
os.environ["GITHUB_CLIENT_SECRET"] = github_client_secret
@@ -645,9 +652,9 @@ def run_mcp_server(
645652
logger.info(f"Connected to CMS API at {cms_base_url}")
646653
main()
647654
except ImportError as e:
648-
logger.error(f"Cannot import MCP. Please install it with `pip install cms[mcp]`: {e}")
655+
logger.error(f"Cannot import MCP. Please install it with `pip install '.[mcp]'`: {e}")
649656
typer.echo(f"ERROR: Cannot import MCP: {e}")
650-
typer.echo("Please install it with `pip install cms[mcp]`.")
657+
typer.echo("Please install it with `pip install '.[mcp]'`.")
651658
raise typer.Exit(code=1)
652659
except KeyboardInterrupt:
653660
logger.info("MCP server stopped by the user")

app/mcp/README.md

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ pip install '.[mcp]'
1212
### 2. Set Environment Variables
1313
```bash
1414
export CMS_BASE_URL="http://127.0.0.1:8000" # CogStack ModelServe API base URL
15-
export MCP_API_KEYS="key1,key2,...keyN" # Optional: The API key(s) for authentication
15+
export CMS_MCP_API_KEYS="key1,key2,...keyN" # Optional: The API key(s) for authentication
1616
```
1717

1818
### 3. Run the Server
@@ -23,10 +23,84 @@ cms mcp run
2323

2424
```bash
2525
# HTTP transport
26-
export CMS_MCP_TRANSPORT=http
2726
cms mcp run --transport http
2827
```
29-
Once the above succeeds, the MCP server will be running on http://127.0.0.1:8080/mcp
28+
Once the above succeeds, the MCP server will be running at http://127.0.0.1:8080/mcp
29+
30+
```bash
31+
# SSE transport
32+
cms mcp run --transport sse
33+
```
34+
Once the above succeeds, the MCP server will be running at http://127.0.0.1:8080/sse
35+
36+
## Claude Desktop Configuration
37+
38+
To use this MCP server with Claude Desktop, add the following configuration to your `claude_desktop_config.json` file:
39+
40+
```json
41+
{
42+
"mcpServers": {
43+
"cms-mcp-server": {
44+
"command": "npx",
45+
"args": [
46+
"mcp-remote",
47+
"http://127.0.0.1:8080/sse"
48+
]
49+
}
50+
}
51+
}
52+
```
53+
54+
With API-key-based authentication:
55+
```bash
56+
cms mcp run --transport sse --cms-mcp-api-keys "key1,key2,...keyN"
57+
```
58+
```json
59+
{
60+
"mcpServers": {
61+
"cms-mcp-server": {
62+
"command": "npx",
63+
"args": [
64+
"mcp-remote",
65+
"http://127.0.0.1:8080/sse",
66+
"--header",
67+
"X-API-Key:${API_KEY_HEADER}"
68+
],
69+
"env": {
70+
"API_KEY_HEADER": "ONE_OF_THE_API_KEYS"
71+
}
72+
}
73+
}
74+
}
75+
```
76+
77+
With OAuth2-based authentication:
78+
```bash
79+
cms mcp run --transport sse
80+
--cms-mcp-oauth-enabled \
81+
--github-client-id <GITHUB_CLIENT_ID> \
82+
--github-client-secret <GITHUB_CLIENT_SECRET> \
83+
--google-client-id <GOOGLE_CLIENT_ID> \
84+
--google-client-secret <GOOGLE_CLIENT_SECRET>
85+
```
86+
```json
87+
{
88+
"mcpServers": {
89+
"cms-mcp-server": {
90+
"command": "npx",
91+
"args": [
92+
"mcp-remote",
93+
"http://127.0.0.1:8080/sse",
94+
"--header",
95+
"X-API-Key:${AUTH_HEADER}"
96+
],
97+
"env": {
98+
"AUTH_HEADER": "Bearer <ACCESS_TOKEN>"
99+
}
100+
}
101+
}
102+
}
103+
```
30104

31105
## Available Tools
32106

@@ -40,27 +114,27 @@ Once the above succeeds, the MCP server will be running on http://127.0.0.1:8080
40114

41115
## Configuration
42116

43-
| Environment Variable | Default | Description |
44-
|---------------------|---------|-------------|
117+
| Environment Variable | Default | Description |
118+
|---------------------|-------------------------|-------------|
45119
| `CMS_BASE_URL` | `http://127.0.0.1:8000` | ModelServe API base URL |
46120
| `CMS_MCP_SERVER_HOST` | `127.0.0.1` | MCP server host |
47121
| `CMS_MCP_SERVER_PORT` | `8080` | MCP server port |
48122
| `CMS_MCP_TRANSPORT` | `stdio` | Transport type (`stdio`, `http` or `sse`) |
49123
| `CMS_ACCESS_TOKEN` | Empty | Bearer token for ModelServe API |
50124
| `CMS_API_KEY` | `Bearer` | API key for ModelServe API |
51-
| `MCP_API_KEYS` | None | Comma-separated API keys for authentication |
52-
| `CMS_MCP_OAUTH_ENABLED` | `true` | Enable OAuth authentication |
53-
| `CMS_MCP_BASE_URL` | `http://<host>:<port>` | Base URL for OAuth callback |
54-
| `CMS_MCP_DEV` | `0` | Run in development mode (creates server instance) |
125+
| `CMS_MCP_API_KEYS` | None | Comma-separated API keys for authentication |
126+
| `CMS_MCP_OAUTH_ENABLED` | `false` | Enable OAuth authentication |
127+
| `CMS_MCP_BASE_URL` | `http://<host>:<port>` | Base URL for OAuth callback |
128+
| `CMS_MCP_DEV` | `0` | Run in development mode |
55129

56130

57131
## Authentication
58132

59133
The server supports two authentication methods:
60134

61135
### 1. API Key Authentication
62-
When `MCP_API_KEYS` is set, clients must authenticate using:
63-
- **Header**: `x-api-key: your-key`
136+
When `CMS_MCP_API_KEYS` is set, clients must authenticate using:
137+
- **Header**: `X-API-Key: your-key`
64138

65139
### 2. OAuth Authentication (SSE Transport)
66140
When `CMS_MCP_OAUTH_ENABLED=true`, the server provides a built-in OAuth 2.0 login flow for SSE transport.
@@ -80,7 +154,7 @@ When `CMS_MCP_OAUTH_ENABLED=true`, the server provides a built-in OAuth 2.0 logi
80154
| `GOOGLE_CLIENT_ID` | Google OAuth client ID |
81155
| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret |
82156

83-
**Note:** OAuth credentials can also be set via environment variables or `.env` file. If not configured, the server will log a warning but continue running.
157+
**Note:** If OAuth credentials are not configured, the server will log a warning but continue running.
84158

85159
**Session Authentication:**
86160
After OAuth login, a session cookie (`cms_mcp_session`) is set. Subsequent MCP requests should include this cookie for authentication.

0 commit comments

Comments
 (0)