weeek-mcp 0.2.0__tar.gz

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.
@@ -0,0 +1,69 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ build/
9
+ dist/
10
+ wheels/
11
+ MANIFEST
12
+
13
+ # Unit test / coverage reports
14
+ htmlcov/
15
+ .tox/
16
+ .nox/
17
+ .coverage
18
+ .coverage.*
19
+ .cache
20
+ nosetests.xml
21
+ coverage.xml
22
+ *.cover
23
+ *.py,cover
24
+ .hypothesis/
25
+ .pytest_cache/
26
+
27
+ # PyBuilder
28
+ target/
29
+
30
+ # pyenv
31
+ .python-version
32
+
33
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
34
+ __pypackages__/
35
+
36
+ # Environments
37
+ .env
38
+ .venv
39
+ venv/
40
+
41
+ # Rope project settings
42
+ .ropeproject
43
+
44
+ # mypy
45
+ .mypy_cache/
46
+ .dmypy.json
47
+ dmypy.json
48
+
49
+ # Pyre type checker
50
+ .pyre/
51
+
52
+ # Ruff
53
+ .ruff_cache/
54
+
55
+ # PyCharm
56
+ .idea
57
+
58
+ # VS Code
59
+ .vscode/
60
+
61
+ # macOS
62
+ .DS_Store
63
+
64
+ # Weeek MCP: cached Playwright login session
65
+ storage_state.json
66
+
67
+ # Playwright
68
+ /test-results/
69
+ /playwright-report/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Weeek MCP contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,293 @@
1
+ Metadata-Version: 2.5
2
+ Name: weeek-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP server for Weeek: task management via the public API, knowledge base via its internal API and collaborative editor channel.
5
+ Project-URL: Homepage, https://github.com/adalekin/weeek-mcp
6
+ Project-URL: Repository, https://github.com/adalekin/weeek-mcp
7
+ Project-URL: Issues, https://github.com/adalekin/weeek-mcp/issues
8
+ Project-URL: Changelog, https://github.com/adalekin/weeek-mcp/releases
9
+ Author-email: Aleksey Dalekin <adalekin@gmail.com>
10
+ License: MIT License
11
+
12
+ Copyright (c) 2026 Weeek MCP contributors
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining a copy
15
+ of this software and associated documentation files (the "Software"), to deal
16
+ in the Software without restriction, including without limitation the rights
17
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
+ copies of the Software, and to permit persons to whom the Software is
19
+ furnished to do so, subject to the following conditions:
20
+
21
+ The above copyright notice and this permission notice shall be included in all
22
+ copies or substantial portions of the Software.
23
+
24
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
+ SOFTWARE.
31
+ License-File: LICENSE
32
+ Keywords: knowledge-base,mcp,playwright,task-manager,weeek
33
+ Classifier: Development Status :: 4 - Beta
34
+ Classifier: Intended Audience :: Developers
35
+ Classifier: License :: OSI Approved :: MIT License
36
+ Classifier: Operating System :: OS Independent
37
+ Classifier: Programming Language :: Python :: 3
38
+ Classifier: Programming Language :: Python :: 3.10
39
+ Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
41
+ Classifier: Programming Language :: Python :: 3.13
42
+ Classifier: Typing :: Typed
43
+ Requires-Python: >=3.10
44
+ Requires-Dist: httpx>=0.27.0
45
+ Requires-Dist: mcp>=1.2.0
46
+ Requires-Dist: python-dotenv>=1.0.0
47
+ Provides-Extra: kb
48
+ Requires-Dist: playwright>=1.44.0; extra == 'kb'
49
+ Requires-Dist: pycrdt>=0.10.0; extra == 'kb'
50
+ Requires-Dist: websockets>=12.0; extra == 'kb'
51
+ Description-Content-Type: text/markdown
52
+
53
+ # weeek-mcp
54
+
55
+ [![CI](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml)
56
+ [![PyPI version](https://img.shields.io/pypi/v/weeek-mcp.svg)](https://pypi.org/project/weeek-mcp/)
57
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/adalekin/weeek-mcp/blob/main/LICENSE)
58
+
59
+ **Language:** English · [Русский](https://github.com/adalekin/weeek-mcp/blob/main/README.ru.md)
60
+
61
+ An [MCP](https://modelcontextprotocol.io) server for [Weeek](https://weeek.net): manage **tasks** through the public REST API and browse the **knowledge base** through Weeek's internal API, exposed as MCP **Resources** so you can search and select KB documents as content (not links) from your MCP client.
62
+
63
+ ## Contents
64
+
65
+ - [Features](#features)
66
+ - [Requirements](#requirements)
67
+ - [Installation](#installation)
68
+ - [Configuration](#configuration)
69
+ - [Usage](#usage)
70
+ - [Tools](#tools)
71
+ - [Knowledge base in Claude context](#knowledge-base-in-claude-context)
72
+ - [Status & limitations](#status--limitations)
73
+ - [Development](#development)
74
+ - [License](#license)
75
+
76
+ ## Features
77
+
78
+ ### Tasks and boards
79
+
80
+ Public REST API — projects, boards, board columns, and the full task lifecycle: create, update, complete, move between columns, assign and unassign members.
81
+
82
+ ### Knowledge base
83
+
84
+ Full CRUD. Weeek has no public KB API, so the server calls Weeek's **internal JSON API** (`api.weeek.net/ws/{id}/kb/...`) using cookies from a saved browser login. Documents are rendered to Markdown and published as MCP **Resources** (`weeek-kb://<id>`). Read/list/search/create/rename/delete go over the JSON API; **in-place body editing** speaks Weeek's collaborative protocol directly (Hocuspocus/Yjs), because bodies live in a shared document the REST API only serves a snapshot of. Content is converted between Markdown and Weeek's ProseMirror format automatically.
85
+
86
+ ### Capability-aware
87
+
88
+ Task tools appear when an API token is set; KB tools and resources appear when login credentials or a cached session are present.
89
+
90
+ ## Requirements
91
+
92
+ - Python 3.10+
93
+ - A Weeek **API token** for task tools (Weeek → Settings → API).
94
+ - For the knowledge base: `weeek-mcp[kb]` plus the Chromium runtime (used for login only), and either login credentials or a session seeded once with `weeek-mcp-login`.
95
+
96
+ ## Installation
97
+
98
+ ```bash
99
+ pip install weeek-mcp # task tools only
100
+ pip install "weeek-mcp[kb]" # + knowledge base
101
+ playwright install chromium # KB runtime
102
+ ```
103
+
104
+ With [uv](https://docs.astral.sh/uv/) in your own project:
105
+
106
+ ```bash
107
+ uv add "weeek-mcp[kb]"
108
+ ```
109
+
110
+ ## Configuration
111
+
112
+ Set environment variables (or copy `.env.example` to `.env`). Use just the task API,
113
+ just the knowledge base, or both.
114
+
115
+ | Variable | Purpose |
116
+ | --- | --- |
117
+ | `WEEEK_API_TOKEN` | Task API token. Required for task tools. |
118
+ | `WEEEK_EMAIL` / `WEEEK_PASSWORD` | First automated KB login. Optional (skip if 2FA/SSO — use `weeek-mcp-login`). |
119
+ | `WEEEK_WORKSPACE_ID` | KB workspace id. Optional — auto-detected via `/ws` when unset. |
120
+ | `WEEEK_STORAGE_STATE` | Where the browser session is cached (defaults under `~/.local/state`). |
121
+ | `WEEEK_HEADLESS` | `false` to watch the browser during login. |
122
+ | `WEEEK_KB_CACHE_TTL` | Seconds to cache the KB document list (default `300`). |
123
+ | `WEEEK_DEBUG_LOG` | `1`/`true` to write diagnostic timing/step logs to `~/.local/state/weeek-mcp/debug.log` (some MCP hosts discard stderr). Off by default. |
124
+
125
+ ### Knowledge base first login
126
+
127
+ If your account has 2FA or a captcha, automated login won't work. Seed the session
128
+ once, interactively — it opens a browser, you sign in, then it caches the session for
129
+ headless reuse:
130
+
131
+ ```bash
132
+ weeek-mcp-login
133
+ ```
134
+
135
+ ## Usage
136
+
137
+ Run the stdio server:
138
+
139
+ ```bash
140
+ weeek-mcp
141
+ ```
142
+
143
+ ### Claude Desktop
144
+
145
+ Add to `claude_desktop_config.json`:
146
+
147
+ ```json
148
+ {
149
+ "mcpServers": {
150
+ "weeek": {
151
+ "command": "weeek-mcp",
152
+ "env": {
153
+ "WEEEK_API_TOKEN": "...",
154
+ "WEEEK_STORAGE_STATE": "/absolute/path/to/storage_state.json"
155
+ }
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ ### Other MCP clients
162
+
163
+ `weeek-mcp` is a plain stdio server, so it works with any MCP client that launches
164
+ servers as a local subprocess: Cursor, Windsurf, Cline, Continue, Zed, VS Code
165
+ (Copilot agent mode), Gemini CLI, Goose, LibreChat, and others, plus your own agents
166
+ built on an MCP SDK. The command and environment variables are the same as above —
167
+ only the config format and its location differ.
168
+
169
+ Cursor (`~/.cursor/mcp.json`, or `.cursor/mcp.json` in a project) uses the same shape
170
+ as Claude Desktop:
171
+
172
+ ```json
173
+ {
174
+ "mcpServers": {
175
+ "weeek": {
176
+ "command": "weeek-mcp",
177
+ "env": { "WEEEK_API_TOKEN": "..." }
178
+ }
179
+ }
180
+ }
181
+ ```
182
+
183
+ VS Code (`.vscode/mcp.json`) uses a `servers` key and an explicit `type`:
184
+
185
+ ```json
186
+ {
187
+ "servers": {
188
+ "weeek": {
189
+ "type": "stdio",
190
+ "command": "weeek-mcp",
191
+ "env": { "WEEEK_API_TOKEN": "..." }
192
+ }
193
+ }
194
+ }
195
+ ```
196
+
197
+ > **On the knowledge base:** task tools and `weeek_kb_*` are ordinary MCP tools and
198
+ > work almost everywhere. Pulling documents in through an attachment menu relies on MCP
199
+ > **Resources**, which fewer clients surface. Where they aren't supported, read the KB
200
+ > with `weeek_kb_read`/`weeek_kb_search` — the content still lands in context. MCP and
201
+ > resources support moves fast per client; check the client's docs before relying on it.
202
+
203
+ ## Tools
204
+
205
+ ### Tasks
206
+
207
+ | Group | Tools |
208
+ | --- | --- |
209
+ | Reading & navigation | `weeek_whoami`, `weeek_list_members`, `weeek_list_projects`, `weeek_list_boards`, `weeek_list_board_columns`, `weeek_list_tasks`, `weeek_get_task` |
210
+ | Task lifecycle | `weeek_create_task`, `weeek_update_task`, `weeek_complete_task`, `weeek_uncomplete_task`, `weeek_delete_task`, `weeek_move_task` |
211
+ | Assignees, watchers, hierarchy | `weeek_set_assignees`, `weeek_remove_assignees`, `weeek_set_watchers`, `weeek_remove_watchers`, `weeek_set_task_parent`, `weeek_add_task_to_project`, `weeek_remove_task_from_project` |
212
+ | Time & attachments | `weeek_task_timer`, `weeek_manage_time_entry`, `weeek_upload_attachment`, `weeek_get_attachment` |
213
+ | Fields & comments | `weeek_list_custom_fields`, `weeek_list_task_comments`, `weeek_add_task_comment`, `weeek_update_task_comment`, `weeek_delete_task_comment` |
214
+
215
+ ### Workspace admin
216
+
217
+ `weeek_manage_tags`, `weeek_manage_projects`, `weeek_manage_boards`, `weeek_manage_board_columns`, `weeek_manage_portfolios`, `weeek_manage_custom_fields`.
218
+
219
+ These take an `action` (create/update/delete/…) rather than one tool per operation — the CRUD is regular and the tool list stays readable. Custom fields live per board, per project or workspace-wide, so that tool takes a `scope` (`global`/`project`/`board`) plus `scope_id`.
220
+
221
+ ### Knowledge base
222
+
223
+ | Group | Tools |
224
+ | --- | --- |
225
+ | Reading | `weeek_kb_search`, `weeek_kb_list`, `weeek_kb_read` |
226
+ | Writing | `weeek_kb_create`, `weeek_kb_update`, `weeek_kb_delete` |
227
+ | Formatting | `weeek_kb_table_widths`, `weeek_kb_icons` |
228
+
229
+ > `weeek_kb_update` with new content writes into the document's shared Yjs document over
230
+ > Weeek's collaborative websocket, because that — not REST — is where bodies are saved.
231
+ > No browser is involved and the document id is preserved.
232
+
233
+ ### Behavior
234
+
235
+ **Priorities.** Take either Weeek's number or its label:
236
+
237
+ | Number | Label |
238
+ | --- | --- |
239
+ | `0` | low (Низкий) |
240
+ | `1` | medium (Средний) |
241
+ | `2` | high (Высокий) |
242
+ | `3` | hold (Замороженный) |
243
+
244
+ **Custom fields.** Set with `custom_fields`: on an existing task by field name or id (`{"Ссылка на фичу": "https://…"}`, `null` clears a field, a select takes the option name or id), on `weeek_create_task` by id only — `weeek_list_custom_fields` lists them. A field belongs to the projects it was added to, and Weeek stores nothing when you write to one it doesn't cover, so the write is verified and reported.
245
+
246
+ **Descriptions.** Editable on an existing task: `weeek_update_task` takes `description` as Markdown (empty string clears it). Weeek's REST API only accepts a description on create — `PUT /tm/tasks/{id}` has no such field — because descriptions sync through the same collaborative channel as KB document bodies, so this writes into that channel and needs the knowledge base session. `weeek_create_task` still takes its `description` as HTML, which is what that endpoint stores.
247
+
248
+ **Comments.** Read with `weeek_list_task_comments`, written with `weeek_add_task_comment` and rewritten in place with `weeek_update_task_comment` (all Markdown) — an edited comment beats posting a correction under the original. `weeek_delete_task_comment` removes one for good; Weeek keeps no trash for comments. Weeek's public API has no comments at all, so these go through its web API on the knowledge base session; no browser is launched, only the saved cookies.
249
+
250
+ **Tables.** One size to set: the pixel width of each column (minimum 90). New tables are fitted to the document's content column (~676px) instead of Weeek's 180px-per-column default, and existing widths are carried across a `weeek_kb_update` — a table that gains or loses a column is re-fitted. `weeek_kb_table_widths` sets them explicitly: `widths: [300, 200, 176]` for exact sizes, or `fit: true` to spread a table across the content column.
251
+
252
+ **Icons.** Pass `icon` to `weeek_kb_create`/`weeek_kb_update` as a single emoji (`🚀`) or as one of Weeek's built-in icon names (`weeek_kb_icons` lists them); an empty `icon` removes it. Listings report the icon a document currently has.
253
+
254
+ ## Knowledge base in Claude context
255
+
256
+ Each KB document is published as an MCP **Resource** (`weeek-kb://<id>`). In Claude
257
+ Desktop you add them from the attachment (**+**) menu of the connected server — browse
258
+ the list or narrow it with `weeek_kb_search` — and the client pulls in the **document
259
+ content**, not a link.
260
+
261
+ > **Note on Project Context:** Claude Desktop surfaces MCP resources as attachments.
262
+ > Whether a selected resource persists inside a Project's *Context* panel (vs. a single
263
+ > conversation) depends on your Claude Desktop version. The content-not-a-link behavior
264
+ > works regardless.
265
+
266
+ ## Status & limitations
267
+
268
+ - **Task tools** follow Weeek's published OpenAPI spec.
269
+ - **Knowledge base** uses Weeek's **internal, undocumented** API (`/ws/{id}/kb/...`). It is
270
+ not covered by any stability guarantee and may change without notice; if KB calls start
271
+ failing, the endpoints in [`weeek_mcp/kb/client.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/client.py) are the place
272
+ to look. Login automation targets Weeek's two-step web form
273
+ ([`weeek_mcp/kb/session.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/session.py)); accounts with 2FA/captcha/SSO
274
+ should seed the session with `weeek-mcp-login` instead.
275
+ - Document content is ProseMirror/TipTap JSON, converted to/from Markdown by
276
+ [`weeek_mcp/kb/prosemirror.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/prosemirror.py). Editing an existing body
277
+ goes through Weeek's collaborative channel (there is no REST content-write):
278
+ [`weeek_mcp/kb/collab.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/collab.py) speaks the Hocuspocus protocol,
279
+ authenticates with a per-socket ticket, and replaces the `prosemirror` fragment of the
280
+ document's Y.Doc. Authoring covers the common Markdown subset (headings, paragraphs, lists,
281
+ bold/inline code, code blocks, quotes, rules); rich cases like nested lists and tables
282
+ are simplified.
283
+ - Table column widths live on the `table_body` node, as a JSON string, and are written
284
+ with the body rather than after it ([`weeek_mcp/kb/tables.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/tables.py)). Cell colors and per-column colors
285
+ are stored alongside the widths but are not exposed as tools yet.
286
+
287
+ ## Development
288
+
289
+ See [CONTRIBUTING.md](https://github.com/adalekin/weeek-mcp/blob/main/CONTRIBUTING.md) for setup, tests, and pull requests.
290
+
291
+ ## License
292
+
293
+ This project is licensed under the MIT License — see [LICENSE](https://github.com/adalekin/weeek-mcp/blob/main/LICENSE).
@@ -0,0 +1,241 @@
1
+ # weeek-mcp
2
+
3
+ [![CI](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml)
4
+ [![PyPI version](https://img.shields.io/pypi/v/weeek-mcp.svg)](https://pypi.org/project/weeek-mcp/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/adalekin/weeek-mcp/blob/main/LICENSE)
6
+
7
+ **Language:** English · [Русский](https://github.com/adalekin/weeek-mcp/blob/main/README.ru.md)
8
+
9
+ An [MCP](https://modelcontextprotocol.io) server for [Weeek](https://weeek.net): manage **tasks** through the public REST API and browse the **knowledge base** through Weeek's internal API, exposed as MCP **Resources** so you can search and select KB documents as content (not links) from your MCP client.
10
+
11
+ ## Contents
12
+
13
+ - [Features](#features)
14
+ - [Requirements](#requirements)
15
+ - [Installation](#installation)
16
+ - [Configuration](#configuration)
17
+ - [Usage](#usage)
18
+ - [Tools](#tools)
19
+ - [Knowledge base in Claude context](#knowledge-base-in-claude-context)
20
+ - [Status & limitations](#status--limitations)
21
+ - [Development](#development)
22
+ - [License](#license)
23
+
24
+ ## Features
25
+
26
+ ### Tasks and boards
27
+
28
+ Public REST API — projects, boards, board columns, and the full task lifecycle: create, update, complete, move between columns, assign and unassign members.
29
+
30
+ ### Knowledge base
31
+
32
+ Full CRUD. Weeek has no public KB API, so the server calls Weeek's **internal JSON API** (`api.weeek.net/ws/{id}/kb/...`) using cookies from a saved browser login. Documents are rendered to Markdown and published as MCP **Resources** (`weeek-kb://<id>`). Read/list/search/create/rename/delete go over the JSON API; **in-place body editing** speaks Weeek's collaborative protocol directly (Hocuspocus/Yjs), because bodies live in a shared document the REST API only serves a snapshot of. Content is converted between Markdown and Weeek's ProseMirror format automatically.
33
+
34
+ ### Capability-aware
35
+
36
+ Task tools appear when an API token is set; KB tools and resources appear when login credentials or a cached session are present.
37
+
38
+ ## Requirements
39
+
40
+ - Python 3.10+
41
+ - A Weeek **API token** for task tools (Weeek → Settings → API).
42
+ - For the knowledge base: `weeek-mcp[kb]` plus the Chromium runtime (used for login only), and either login credentials or a session seeded once with `weeek-mcp-login`.
43
+
44
+ ## Installation
45
+
46
+ ```bash
47
+ pip install weeek-mcp # task tools only
48
+ pip install "weeek-mcp[kb]" # + knowledge base
49
+ playwright install chromium # KB runtime
50
+ ```
51
+
52
+ With [uv](https://docs.astral.sh/uv/) in your own project:
53
+
54
+ ```bash
55
+ uv add "weeek-mcp[kb]"
56
+ ```
57
+
58
+ ## Configuration
59
+
60
+ Set environment variables (or copy `.env.example` to `.env`). Use just the task API,
61
+ just the knowledge base, or both.
62
+
63
+ | Variable | Purpose |
64
+ | --- | --- |
65
+ | `WEEEK_API_TOKEN` | Task API token. Required for task tools. |
66
+ | `WEEEK_EMAIL` / `WEEEK_PASSWORD` | First automated KB login. Optional (skip if 2FA/SSO — use `weeek-mcp-login`). |
67
+ | `WEEEK_WORKSPACE_ID` | KB workspace id. Optional — auto-detected via `/ws` when unset. |
68
+ | `WEEEK_STORAGE_STATE` | Where the browser session is cached (defaults under `~/.local/state`). |
69
+ | `WEEEK_HEADLESS` | `false` to watch the browser during login. |
70
+ | `WEEEK_KB_CACHE_TTL` | Seconds to cache the KB document list (default `300`). |
71
+ | `WEEEK_DEBUG_LOG` | `1`/`true` to write diagnostic timing/step logs to `~/.local/state/weeek-mcp/debug.log` (some MCP hosts discard stderr). Off by default. |
72
+
73
+ ### Knowledge base first login
74
+
75
+ If your account has 2FA or a captcha, automated login won't work. Seed the session
76
+ once, interactively — it opens a browser, you sign in, then it caches the session for
77
+ headless reuse:
78
+
79
+ ```bash
80
+ weeek-mcp-login
81
+ ```
82
+
83
+ ## Usage
84
+
85
+ Run the stdio server:
86
+
87
+ ```bash
88
+ weeek-mcp
89
+ ```
90
+
91
+ ### Claude Desktop
92
+
93
+ Add to `claude_desktop_config.json`:
94
+
95
+ ```json
96
+ {
97
+ "mcpServers": {
98
+ "weeek": {
99
+ "command": "weeek-mcp",
100
+ "env": {
101
+ "WEEEK_API_TOKEN": "...",
102
+ "WEEEK_STORAGE_STATE": "/absolute/path/to/storage_state.json"
103
+ }
104
+ }
105
+ }
106
+ }
107
+ ```
108
+
109
+ ### Other MCP clients
110
+
111
+ `weeek-mcp` is a plain stdio server, so it works with any MCP client that launches
112
+ servers as a local subprocess: Cursor, Windsurf, Cline, Continue, Zed, VS Code
113
+ (Copilot agent mode), Gemini CLI, Goose, LibreChat, and others, plus your own agents
114
+ built on an MCP SDK. The command and environment variables are the same as above —
115
+ only the config format and its location differ.
116
+
117
+ Cursor (`~/.cursor/mcp.json`, or `.cursor/mcp.json` in a project) uses the same shape
118
+ as Claude Desktop:
119
+
120
+ ```json
121
+ {
122
+ "mcpServers": {
123
+ "weeek": {
124
+ "command": "weeek-mcp",
125
+ "env": { "WEEEK_API_TOKEN": "..." }
126
+ }
127
+ }
128
+ }
129
+ ```
130
+
131
+ VS Code (`.vscode/mcp.json`) uses a `servers` key and an explicit `type`:
132
+
133
+ ```json
134
+ {
135
+ "servers": {
136
+ "weeek": {
137
+ "type": "stdio",
138
+ "command": "weeek-mcp",
139
+ "env": { "WEEEK_API_TOKEN": "..." }
140
+ }
141
+ }
142
+ }
143
+ ```
144
+
145
+ > **On the knowledge base:** task tools and `weeek_kb_*` are ordinary MCP tools and
146
+ > work almost everywhere. Pulling documents in through an attachment menu relies on MCP
147
+ > **Resources**, which fewer clients surface. Where they aren't supported, read the KB
148
+ > with `weeek_kb_read`/`weeek_kb_search` — the content still lands in context. MCP and
149
+ > resources support moves fast per client; check the client's docs before relying on it.
150
+
151
+ ## Tools
152
+
153
+ ### Tasks
154
+
155
+ | Group | Tools |
156
+ | --- | --- |
157
+ | Reading & navigation | `weeek_whoami`, `weeek_list_members`, `weeek_list_projects`, `weeek_list_boards`, `weeek_list_board_columns`, `weeek_list_tasks`, `weeek_get_task` |
158
+ | Task lifecycle | `weeek_create_task`, `weeek_update_task`, `weeek_complete_task`, `weeek_uncomplete_task`, `weeek_delete_task`, `weeek_move_task` |
159
+ | Assignees, watchers, hierarchy | `weeek_set_assignees`, `weeek_remove_assignees`, `weeek_set_watchers`, `weeek_remove_watchers`, `weeek_set_task_parent`, `weeek_add_task_to_project`, `weeek_remove_task_from_project` |
160
+ | Time & attachments | `weeek_task_timer`, `weeek_manage_time_entry`, `weeek_upload_attachment`, `weeek_get_attachment` |
161
+ | Fields & comments | `weeek_list_custom_fields`, `weeek_list_task_comments`, `weeek_add_task_comment`, `weeek_update_task_comment`, `weeek_delete_task_comment` |
162
+
163
+ ### Workspace admin
164
+
165
+ `weeek_manage_tags`, `weeek_manage_projects`, `weeek_manage_boards`, `weeek_manage_board_columns`, `weeek_manage_portfolios`, `weeek_manage_custom_fields`.
166
+
167
+ These take an `action` (create/update/delete/…) rather than one tool per operation — the CRUD is regular and the tool list stays readable. Custom fields live per board, per project or workspace-wide, so that tool takes a `scope` (`global`/`project`/`board`) plus `scope_id`.
168
+
169
+ ### Knowledge base
170
+
171
+ | Group | Tools |
172
+ | --- | --- |
173
+ | Reading | `weeek_kb_search`, `weeek_kb_list`, `weeek_kb_read` |
174
+ | Writing | `weeek_kb_create`, `weeek_kb_update`, `weeek_kb_delete` |
175
+ | Formatting | `weeek_kb_table_widths`, `weeek_kb_icons` |
176
+
177
+ > `weeek_kb_update` with new content writes into the document's shared Yjs document over
178
+ > Weeek's collaborative websocket, because that — not REST — is where bodies are saved.
179
+ > No browser is involved and the document id is preserved.
180
+
181
+ ### Behavior
182
+
183
+ **Priorities.** Take either Weeek's number or its label:
184
+
185
+ | Number | Label |
186
+ | --- | --- |
187
+ | `0` | low (Низкий) |
188
+ | `1` | medium (Средний) |
189
+ | `2` | high (Высокий) |
190
+ | `3` | hold (Замороженный) |
191
+
192
+ **Custom fields.** Set with `custom_fields`: on an existing task by field name or id (`{"Ссылка на фичу": "https://…"}`, `null` clears a field, a select takes the option name or id), on `weeek_create_task` by id only — `weeek_list_custom_fields` lists them. A field belongs to the projects it was added to, and Weeek stores nothing when you write to one it doesn't cover, so the write is verified and reported.
193
+
194
+ **Descriptions.** Editable on an existing task: `weeek_update_task` takes `description` as Markdown (empty string clears it). Weeek's REST API only accepts a description on create — `PUT /tm/tasks/{id}` has no such field — because descriptions sync through the same collaborative channel as KB document bodies, so this writes into that channel and needs the knowledge base session. `weeek_create_task` still takes its `description` as HTML, which is what that endpoint stores.
195
+
196
+ **Comments.** Read with `weeek_list_task_comments`, written with `weeek_add_task_comment` and rewritten in place with `weeek_update_task_comment` (all Markdown) — an edited comment beats posting a correction under the original. `weeek_delete_task_comment` removes one for good; Weeek keeps no trash for comments. Weeek's public API has no comments at all, so these go through its web API on the knowledge base session; no browser is launched, only the saved cookies.
197
+
198
+ **Tables.** One size to set: the pixel width of each column (minimum 90). New tables are fitted to the document's content column (~676px) instead of Weeek's 180px-per-column default, and existing widths are carried across a `weeek_kb_update` — a table that gains or loses a column is re-fitted. `weeek_kb_table_widths` sets them explicitly: `widths: [300, 200, 176]` for exact sizes, or `fit: true` to spread a table across the content column.
199
+
200
+ **Icons.** Pass `icon` to `weeek_kb_create`/`weeek_kb_update` as a single emoji (`🚀`) or as one of Weeek's built-in icon names (`weeek_kb_icons` lists them); an empty `icon` removes it. Listings report the icon a document currently has.
201
+
202
+ ## Knowledge base in Claude context
203
+
204
+ Each KB document is published as an MCP **Resource** (`weeek-kb://<id>`). In Claude
205
+ Desktop you add them from the attachment (**+**) menu of the connected server — browse
206
+ the list or narrow it with `weeek_kb_search` — and the client pulls in the **document
207
+ content**, not a link.
208
+
209
+ > **Note on Project Context:** Claude Desktop surfaces MCP resources as attachments.
210
+ > Whether a selected resource persists inside a Project's *Context* panel (vs. a single
211
+ > conversation) depends on your Claude Desktop version. The content-not-a-link behavior
212
+ > works regardless.
213
+
214
+ ## Status & limitations
215
+
216
+ - **Task tools** follow Weeek's published OpenAPI spec.
217
+ - **Knowledge base** uses Weeek's **internal, undocumented** API (`/ws/{id}/kb/...`). It is
218
+ not covered by any stability guarantee and may change without notice; if KB calls start
219
+ failing, the endpoints in [`weeek_mcp/kb/client.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/client.py) are the place
220
+ to look. Login automation targets Weeek's two-step web form
221
+ ([`weeek_mcp/kb/session.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/session.py)); accounts with 2FA/captcha/SSO
222
+ should seed the session with `weeek-mcp-login` instead.
223
+ - Document content is ProseMirror/TipTap JSON, converted to/from Markdown by
224
+ [`weeek_mcp/kb/prosemirror.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/prosemirror.py). Editing an existing body
225
+ goes through Weeek's collaborative channel (there is no REST content-write):
226
+ [`weeek_mcp/kb/collab.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/collab.py) speaks the Hocuspocus protocol,
227
+ authenticates with a per-socket ticket, and replaces the `prosemirror` fragment of the
228
+ document's Y.Doc. Authoring covers the common Markdown subset (headings, paragraphs, lists,
229
+ bold/inline code, code blocks, quotes, rules); rich cases like nested lists and tables
230
+ are simplified.
231
+ - Table column widths live on the `table_body` node, as a JSON string, and are written
232
+ with the body rather than after it ([`weeek_mcp/kb/tables.py`](https://github.com/adalekin/weeek-mcp/blob/main/weeek_mcp/kb/tables.py)). Cell colors and per-column colors
233
+ are stored alongside the widths but are not exposed as tools yet.
234
+
235
+ ## Development
236
+
237
+ See [CONTRIBUTING.md](https://github.com/adalekin/weeek-mcp/blob/main/CONTRIBUTING.md) for setup, tests, and pull requests.
238
+
239
+ ## License
240
+
241
+ This project is licensed under the MIT License — see [LICENSE](https://github.com/adalekin/weeek-mcp/blob/main/LICENSE).