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.
- weeek_mcp-0.2.0/.gitignore +69 -0
- weeek_mcp-0.2.0/LICENSE +21 -0
- weeek_mcp-0.2.0/PKG-INFO +293 -0
- weeek_mcp-0.2.0/README.md +241 -0
- weeek_mcp-0.2.0/pyproject.toml +78 -0
- weeek_mcp-0.2.0/weeek_mcp/__init__.py +3 -0
- weeek_mcp-0.2.0/weeek_mcp/config.py +87 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/__init__.py +6 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/client.py +751 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/collab.py +311 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/login.py +42 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/prosemirror.py +538 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/session.py +126 -0
- weeek_mcp-0.2.0/weeek_mcp/kb/tables.py +270 -0
- weeek_mcp-0.2.0/weeek_mcp/logging_util.py +31 -0
- weeek_mcp-0.2.0/weeek_mcp/py.typed +0 -0
- weeek_mcp-0.2.0/weeek_mcp/server.py +162 -0
- weeek_mcp-0.2.0/weeek_mcp/tools.py +1623 -0
- weeek_mcp-0.2.0/weeek_mcp/weeek_api.py +281 -0
|
@@ -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/
|
weeek_mcp-0.2.0/LICENSE
ADDED
|
@@ -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.
|
weeek_mcp-0.2.0/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml)
|
|
56
|
+
[](https://pypi.org/project/weeek-mcp/)
|
|
57
|
+
[](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
|
+
[](https://github.com/adalekin/weeek-mcp/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/weeek-mcp/)
|
|
5
|
+
[](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).
|