Spaces:
Sleeping
Sleeping
bigwolfe
commited on
Commit
·
8378c97
1
Parent(s):
24137a8
Update MCP server and config for ChatGPT Apps SDK integration
Browse files
backend/src/mcp/server.py
CHANGED
|
@@ -51,8 +51,14 @@ def _current_user_id() -> str:
|
|
| 51 |
request = None
|
| 52 |
if request is not None:
|
| 53 |
header = request.headers.get("Authorization")
|
|
|
|
|
|
|
| 54 |
if not header:
|
|
|
|
|
|
|
|
|
|
| 55 |
raise PermissionError("Authorization header required")
|
|
|
|
| 56 |
scheme, _, token = header.partition(" ")
|
| 57 |
if scheme.lower() != "bearer" or not token:
|
| 58 |
raise PermissionError("Authorization header must be 'Bearer <token>'")
|
|
|
|
| 51 |
request = None
|
| 52 |
if request is not None:
|
| 53 |
header = request.headers.get("Authorization")
|
| 54 |
+
|
| 55 |
+
# Check for No-Auth mode if header is missing
|
| 56 |
if not header:
|
| 57 |
+
config = get_config()
|
| 58 |
+
if config.enable_noauth_mcp:
|
| 59 |
+
return "demo-user"
|
| 60 |
raise PermissionError("Authorization header required")
|
| 61 |
+
|
| 62 |
scheme, _, token = header.partition(" ")
|
| 63 |
if scheme.lower() != "bearer" or not token:
|
| 64 |
raise PermissionError("Authorization header must be 'Bearer <token>'")
|
backend/src/services/config.py
CHANGED
|
@@ -38,6 +38,10 @@ class AppConfig(BaseModel):
|
|
| 38 |
default="https://chatgpt.com",
|
| 39 |
description="Allowed CORS origin for ChatGPT",
|
| 40 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 41 |
vault_base_path: Path = Field(..., description="Base directory for per-user vaults")
|
| 42 |
hf_oauth_client_id: Optional[str] = Field(
|
| 43 |
None, description="Hugging Face OAuth client ID (optional)"
|
|
@@ -96,6 +100,7 @@ def get_config() -> AppConfig:
|
|
| 96 |
local_dev_token = _read_env("LOCAL_DEV_TOKEN", "local-dev-token")
|
| 97 |
chatgpt_service_token = _read_env("CHATGPT_SERVICE_TOKEN")
|
| 98 |
chatgpt_cors_origin = _read_env("CHATGPT_CORS_ORIGIN", "https://chatgpt.com")
|
|
|
|
| 99 |
|
| 100 |
config = AppConfig(
|
| 101 |
jwt_secret_key=jwt_secret,
|
|
@@ -103,6 +108,7 @@ def get_config() -> AppConfig:
|
|
| 103 |
local_dev_token=local_dev_token,
|
| 104 |
chatgpt_service_token=chatgpt_service_token,
|
| 105 |
chatgpt_cors_origin=chatgpt_cors_origin,
|
|
|
|
| 106 |
vault_base_path=vault_base,
|
| 107 |
hf_oauth_client_id=hf_client_id,
|
| 108 |
hf_oauth_client_secret=hf_client_secret,
|
|
|
|
| 38 |
default="https://chatgpt.com",
|
| 39 |
description="Allowed CORS origin for ChatGPT",
|
| 40 |
)
|
| 41 |
+
enable_noauth_mcp: bool = Field(
|
| 42 |
+
default=False,
|
| 43 |
+
description="DANGEROUS: Allow unauthenticated MCP access as demo-user (for hackathon)",
|
| 44 |
+
)
|
| 45 |
vault_base_path: Path = Field(..., description="Base directory for per-user vaults")
|
| 46 |
hf_oauth_client_id: Optional[str] = Field(
|
| 47 |
None, description="Hugging Face OAuth client ID (optional)"
|
|
|
|
| 100 |
local_dev_token = _read_env("LOCAL_DEV_TOKEN", "local-dev-token")
|
| 101 |
chatgpt_service_token = _read_env("CHATGPT_SERVICE_TOKEN")
|
| 102 |
chatgpt_cors_origin = _read_env("CHATGPT_CORS_ORIGIN", "https://chatgpt.com")
|
| 103 |
+
enable_noauth_mcp = _read_env("ENABLE_NOAUTH_MCP", "false").lower() in {"true", "1", "yes"}
|
| 104 |
|
| 105 |
config = AppConfig(
|
| 106 |
jwt_secret_key=jwt_secret,
|
|
|
|
| 108 |
local_dev_token=local_dev_token,
|
| 109 |
chatgpt_service_token=chatgpt_service_token,
|
| 110 |
chatgpt_cors_origin=chatgpt_cors_origin,
|
| 111 |
+
enable_noauth_mcp=enable_noauth_mcp,
|
| 112 |
vault_base_path=vault_base,
|
| 113 |
hf_oauth_client_id=hf_client_id,
|
| 114 |
hf_oauth_client_secret=hf_client_secret,
|
specs/003-chatgpt-app-integration/spec.md
CHANGED
|
@@ -22,11 +22,11 @@ Transform the Document-MCP project into a "ChatGPT App" compatible with the Open
|
|
| 22 |
- Note Viewing (with Markdown rendering and Wikilink support)
|
| 23 |
- Search Results (clean list with snippets)
|
| 24 |
- **Dual-Mode Operation**: Ensure the application continues to function as a standalone web app and standard MCP server while supporting the ChatGPT App mode.
|
| 25 |
-
- **Hackathon Readiness**: Prioritize a functional
|
| 26 |
|
| 27 |
### Non-Goals
|
| 28 |
- **Full Obsidian UI in Chat**: We will not iframe the entire application (sidebar, graph view, settings) into ChatGPT.
|
| 29 |
-
- **Production OAuth**: We will not implement a full OIDC provider
|
| 30 |
- **Complex Graph Viz**: The Graph View widget is out of scope for the initial V1 integration.
|
| 31 |
|
| 32 |
## 4. User Scenarios
|
|
@@ -49,7 +49,7 @@ Transform the Document-MCP project into a "ChatGPT App" compatible with the Open
|
|
| 49 |
### 5.1 Backend & MCP
|
| 50 |
- **Metadata Injection**: The `read_note` and `search_notes` tools must return a `CallToolResult` containing the `_meta.openai.outputTemplate` field to trigger widgets.
|
| 51 |
- **CORS**: The API must allow requests from `https://chatgpt.com` to support iframe loading.
|
| 52 |
-
- **
|
| 53 |
|
| 54 |
### 5.2 Frontend Widgets
|
| 55 |
- **Widget Entry Point**: A new build target (`widget.html` + `widget.tsx`) must be created to serve simplified UI components.
|
|
|
|
| 22 |
- Note Viewing (with Markdown rendering and Wikilink support)
|
| 23 |
- Search Results (clean list with snippets)
|
| 24 |
- **Dual-Mode Operation**: Ensure the application continues to function as a standalone web app and standard MCP server while supporting the ChatGPT App mode.
|
| 25 |
+
- **Hackathon Readiness**: Prioritize a functional integration. We will use "No Authentication" mode for the hackathon submission to bypass OAuth complexity, securing it via obscurity (hidden URL) and "demo-user" isolation.
|
| 26 |
|
| 27 |
### Non-Goals
|
| 28 |
- **Full Obsidian UI in Chat**: We will not iframe the entire application (sidebar, graph view, settings) into ChatGPT.
|
| 29 |
+
- **Production OAuth**: We will not implement a full OIDC provider. **Future Work**: Implement a "Headless OAuth" provider to secure the endpoint properly using Client Credentials semantics wrapped in Authorization Code flow.
|
| 30 |
- **Complex Graph Viz**: The Graph View widget is out of scope for the initial V1 integration.
|
| 31 |
|
| 32 |
## 4. User Scenarios
|
|
|
|
| 49 |
### 5.1 Backend & MCP
|
| 50 |
- **Metadata Injection**: The `read_note` and `search_notes` tools must return a `CallToolResult` containing the `_meta.openai.outputTemplate` field to trigger widgets.
|
| 51 |
- **CORS**: The API must allow requests from `https://chatgpt.com` to support iframe loading.
|
| 52 |
+
- **No Auth Mode**: The backend must support a configured `ENABLE_NOAUTH_MCP` flag. When enabled, MCP tools will default to the "demo-user" context if no Authorization header is present, bypassing strict checks.
|
| 53 |
|
| 54 |
### 5.2 Frontend Widgets
|
| 55 |
- **Widget Entry Point**: A new build target (`widget.html` + `widget.tsx`) must be created to serve simplified UI components.
|