weeek-mcp 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- weeek_mcp/__init__.py +3 -0
- weeek_mcp/config.py +87 -0
- weeek_mcp/kb/__init__.py +6 -0
- weeek_mcp/kb/client.py +751 -0
- weeek_mcp/kb/collab.py +311 -0
- weeek_mcp/kb/login.py +42 -0
- weeek_mcp/kb/prosemirror.py +538 -0
- weeek_mcp/kb/session.py +126 -0
- weeek_mcp/kb/tables.py +270 -0
- weeek_mcp/logging_util.py +31 -0
- weeek_mcp/py.typed +0 -0
- weeek_mcp/server.py +162 -0
- weeek_mcp/tools.py +1623 -0
- weeek_mcp/weeek_api.py +281 -0
- weeek_mcp-0.2.0.dist-info/METADATA +293 -0
- weeek_mcp-0.2.0.dist-info/RECORD +19 -0
- weeek_mcp-0.2.0.dist-info/WHEEL +4 -0
- weeek_mcp-0.2.0.dist-info/entry_points.txt +3 -0
- weeek_mcp-0.2.0.dist-info/licenses/LICENSE +21 -0
weeek_mcp/__init__.py
ADDED
weeek_mcp/config.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Runtime configuration, read from environment variables (and an optional .env file)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
from dotenv import load_dotenv
|
|
10
|
+
|
|
11
|
+
# Load .env if present; real environment variables always win.
|
|
12
|
+
load_dotenv()
|
|
13
|
+
|
|
14
|
+
DEFAULT_API_BASE = "https://api.weeek.net/public/v1"
|
|
15
|
+
DEFAULT_APP_BASE = "https://app.weeek.net"
|
|
16
|
+
# Internal (non-public) API the web app uses for the knowledge base.
|
|
17
|
+
DEFAULT_INTERNAL_API_BASE = "https://api.weeek.net"
|
|
18
|
+
# Hocuspocus server the editors sync document bodies through.
|
|
19
|
+
DEFAULT_COLLAB_BASE = "wss://collabws.weeek.net"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def _state_dir() -> Path:
|
|
23
|
+
base = os.environ.get("XDG_STATE_HOME") or (Path.home() / ".local" / "state")
|
|
24
|
+
return Path(base) / "weeek-mcp"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _default_state_path() -> Path:
|
|
28
|
+
"""Where the Playwright login session (storageState) is cached."""
|
|
29
|
+
return _state_dir() / "storage_state.json"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _default_log_path() -> Path | None:
|
|
33
|
+
"""Where diagnostic timing/step logs are written, if enabled.
|
|
34
|
+
|
|
35
|
+
Opt-in via WEEEK_DEBUG_LOG=1: MCP hosts commonly discard a locally-run
|
|
36
|
+
extension's stderr (observed with Claude Desktop: the subprocess's fd 2 is
|
|
37
|
+
wired to /dev/null), so debug output has to go to a file we control to
|
|
38
|
+
survive at all — but that shouldn't happen by default for every user.
|
|
39
|
+
"""
|
|
40
|
+
if os.environ.get("WEEEK_DEBUG_LOG", "").lower() not in ("1", "true"):
|
|
41
|
+
return None
|
|
42
|
+
return _state_dir() / "debug.log"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
@dataclass(frozen=True)
|
|
46
|
+
class Config:
|
|
47
|
+
# --- Task management (public REST API) ---
|
|
48
|
+
api_token: str | None
|
|
49
|
+
api_base: str
|
|
50
|
+
|
|
51
|
+
# --- Knowledge base (internal API + Playwright for login) ---
|
|
52
|
+
app_base: str
|
|
53
|
+
internal_api_base: str
|
|
54
|
+
collab_base: str
|
|
55
|
+
workspace_id: str | None # auto-detected via /ws when not set
|
|
56
|
+
email: str | None
|
|
57
|
+
password: str | None
|
|
58
|
+
storage_state_path: Path
|
|
59
|
+
log_path: Path | None
|
|
60
|
+
headless: bool
|
|
61
|
+
kb_cache_ttl: int # seconds to cache the KB document tree for resources/list
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def has_api(self) -> bool:
|
|
65
|
+
return bool(self.api_token)
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def has_kb_credentials(self) -> bool:
|
|
69
|
+
return bool(self.email and self.password)
|
|
70
|
+
|
|
71
|
+
@classmethod
|
|
72
|
+
def from_env(cls) -> "Config":
|
|
73
|
+
state = os.environ.get("WEEEK_STORAGE_STATE")
|
|
74
|
+
return cls(
|
|
75
|
+
api_token=os.environ.get("WEEEK_API_TOKEN"),
|
|
76
|
+
api_base=os.environ.get("WEEEK_API_BASE", DEFAULT_API_BASE).rstrip("/"),
|
|
77
|
+
app_base=os.environ.get("WEEEK_APP_BASE", DEFAULT_APP_BASE).rstrip("/"),
|
|
78
|
+
internal_api_base=os.environ.get("WEEEK_INTERNAL_API_BASE", DEFAULT_INTERNAL_API_BASE).rstrip("/"),
|
|
79
|
+
collab_base=os.environ.get("WEEEK_COLLAB_BASE", DEFAULT_COLLAB_BASE).rstrip("/"),
|
|
80
|
+
workspace_id=os.environ.get("WEEEK_WORKSPACE_ID"),
|
|
81
|
+
email=os.environ.get("WEEEK_EMAIL"),
|
|
82
|
+
password=os.environ.get("WEEEK_PASSWORD"),
|
|
83
|
+
storage_state_path=Path(state) if state else _default_state_path(),
|
|
84
|
+
log_path=_default_log_path(),
|
|
85
|
+
headless=os.environ.get("WEEEK_HEADLESS", "true").lower() != "false",
|
|
86
|
+
kb_cache_ttl=int(os.environ.get("WEEEK_KB_CACHE_TTL", "300")),
|
|
87
|
+
)
|
weeek_mcp/kb/__init__.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"""Knowledge base access for Weeek via Playwright.
|
|
2
|
+
|
|
3
|
+
Weeek has no public API for the knowledge base, so this package drives the web app.
|
|
4
|
+
All DOM-specific details live in ``selectors.py`` and are marked as requiring
|
|
5
|
+
validation against the live UI (they cannot be verified without a real login).
|
|
6
|
+
"""
|