plugvan-mcp 0.1.1__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.
- plugvan_mcp-0.1.1/.gitignore +43 -0
- plugvan_mcp-0.1.1/CHANGELOG.md +272 -0
- plugvan_mcp-0.1.1/LICENSE +21 -0
- plugvan_mcp-0.1.1/PKG-INFO +466 -0
- plugvan_mcp-0.1.1/README.md +433 -0
- plugvan_mcp-0.1.1/plugvan/__init__.py +0 -0
- plugvan_mcp-0.1.1/plugvan/cli.py +54 -0
- plugvan_mcp-0.1.1/plugvan/todoist/__init__.py +22 -0
- plugvan_mcp-0.1.1/plugvan/todoist/__main__.py +15 -0
- plugvan_mcp-0.1.1/plugvan/todoist/client.py +17 -0
- plugvan_mcp-0.1.1/plugvan/todoist/docstrings.py +25 -0
- plugvan_mcp-0.1.1/plugvan/todoist/language.py +32 -0
- plugvan_mcp-0.1.1/plugvan/todoist/limits.py +12 -0
- plugvan_mcp-0.1.1/plugvan/todoist/messages.py +427 -0
- plugvan_mcp-0.1.1/plugvan/todoist/resolvers.py +233 -0
- plugvan_mcp-0.1.1/plugvan/todoist/server.py +42 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/__init__.py +0 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/comments.py +120 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/labels.py +248 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/projects.py +372 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/sections.py +298 -0
- plugvan_mcp-0.1.1/plugvan/todoist/tools/tasks.py +786 -0
- plugvan_mcp-0.1.1/pyproject.toml +57 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Çevre değişkenleri ve Gizli Anahtarlar (API Tokens)
|
|
2
|
+
.env
|
|
3
|
+
*.env
|
|
4
|
+
.env.*
|
|
5
|
+
!.env.example
|
|
6
|
+
|
|
7
|
+
# Google OAuth kimlik, oturum ve token dosyaları
|
|
8
|
+
credentials.json
|
|
9
|
+
credentials*.json
|
|
10
|
+
client_secret*.json
|
|
11
|
+
client_secrets.json
|
|
12
|
+
token.json
|
|
13
|
+
token*.json
|
|
14
|
+
*.token
|
|
15
|
+
*.pickle
|
|
16
|
+
|
|
17
|
+
# Kişisel / Yerel görev ve veri dosyaları
|
|
18
|
+
tasks.json
|
|
19
|
+
debug_tasks.py
|
|
20
|
+
debug_*.py
|
|
21
|
+
scratch/
|
|
22
|
+
*.log
|
|
23
|
+
|
|
24
|
+
# Python ortamı, bytecode ve cache
|
|
25
|
+
venv/
|
|
26
|
+
.venv/
|
|
27
|
+
env/
|
|
28
|
+
__pycache__/
|
|
29
|
+
*.py[cod]
|
|
30
|
+
*$py.class
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.coverage
|
|
33
|
+
htmlcov/
|
|
34
|
+
|
|
35
|
+
# IDE, Editör ve İşletim Sistemi dosyaları
|
|
36
|
+
.vscode/
|
|
37
|
+
.idea/
|
|
38
|
+
*.swp
|
|
39
|
+
*.swo
|
|
40
|
+
.DS_Store
|
|
41
|
+
Thumbs.db
|
|
42
|
+
# Claude Code kişisel ayarları
|
|
43
|
+
.claude/settings.local.json
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
4
|
+
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Backlog
|
|
8
|
+
- `update_section`: expose `order` and `collapsed` (supported by the SDK).
|
|
9
|
+
- `project_move`: needs the Sync API's separate command.
|
|
10
|
+
|
|
11
|
+
## [0.1.1] - 2026-10-20
|
|
12
|
+
|
|
13
|
+
The first release published to PyPI: `plugvan-mcp` 0.1.1 installs from
|
|
14
|
+
PyPI as well as from the GitHub Release assets. It contains the changes
|
|
15
|
+
tested in 0.1.1rc1.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- Final releases are published to PyPI with trusted publishing (#78): a
|
|
19
|
+
`vX.Y.Z` tag uploads the sdist and wheel that CI built and tested, with
|
|
20
|
+
no API token or secret, after the maintainer approves the `pypi`
|
|
21
|
+
deployment, then checks that PyPI serves exactly those files, with the
|
|
22
|
+
same names and sha256 digests.
|
|
23
|
+
- Release candidates are published the same way to TestPyPI only (#77),
|
|
24
|
+
to rehearse a release before it reaches PyPI.
|
|
25
|
+
- Release checks ahead of publishing (#76): the release checks that both
|
|
26
|
+
archive file names carry exactly the tag's version, and every PR runs
|
|
27
|
+
`twine check --strict`, so the README must render as the PyPI project
|
|
28
|
+
description.
|
|
29
|
+
|
|
30
|
+
### Changed
|
|
31
|
+
- Release versions must be canonical, `X.Y.Z` or `X.Y.ZrcN` (#76); other
|
|
32
|
+
spellings, and `a`, `b`, `dev`, `post` and local versions, are
|
|
33
|
+
rejected before anything is published. Only an `X.Y.ZrcN` version is a
|
|
34
|
+
prerelease.
|
|
35
|
+
- The README reads the same on GitHub and on PyPI, where it is the
|
|
36
|
+
project description: the architecture diagram is plain text, warnings
|
|
37
|
+
are plain quotes, the LICENSE links are absolute, and the navigation
|
|
38
|
+
links point at headings.
|
|
39
|
+
|
|
40
|
+
### Fixed
|
|
41
|
+
- README: the install step finds `uvx` with `where.exe uvx`, which also
|
|
42
|
+
works in PowerShell (there, plain `where` is an alias of `Where-Object`
|
|
43
|
+
and prints nothing).
|
|
44
|
+
|
|
45
|
+
## [0.1.1rc1] - 2026-10-20
|
|
46
|
+
|
|
47
|
+
Release candidate for 0.1.1, published to TestPyPI only to rehearse the
|
|
48
|
+
PyPI release; it is not uploaded to PyPI.
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- Release candidates are published to TestPyPI with trusted publishing
|
|
52
|
+
(#77): a `vX.Y.ZrcN` tag uploads the sdist and wheel that CI built and
|
|
53
|
+
tested, with no API token or secret, then checks that TestPyPI serves
|
|
54
|
+
exactly those files, with the same names and sha256 digests.
|
|
55
|
+
- Release checks ahead of PyPI publishing (#76): the release checks that
|
|
56
|
+
both archive file names carry exactly the tag's version, and every PR
|
|
57
|
+
runs `twine check --strict`, so the README must render as the PyPI
|
|
58
|
+
project description.
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
- Release versions must be canonical, `X.Y.Z` or `X.Y.ZrcN` (#76); other
|
|
62
|
+
spellings, and `a`, `b`, `dev`, `post` and local versions, are
|
|
63
|
+
rejected before anything is published. Only an `X.Y.ZrcN` version is a
|
|
64
|
+
prerelease.
|
|
65
|
+
- The README reads the same on GitHub and on PyPI, where it is the
|
|
66
|
+
project description: the architecture diagram is plain text, warnings
|
|
67
|
+
are plain quotes, the LICENSE links are absolute, and the navigation
|
|
68
|
+
links point at headings.
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
- README: the install step finds `uvx` with `where.exe uvx`, which also
|
|
72
|
+
works in PowerShell (there, plain `where` is an alias of `Where-Object`
|
|
73
|
+
and prints nothing).
|
|
74
|
+
|
|
75
|
+
## [0.1.0] - 2026-10-19
|
|
76
|
+
|
|
77
|
+
First public release of Plugvan: Todoist tools for Claude Desktop as an
|
|
78
|
+
MCP server over STDIO. It runs locally; Claude Desktop starts it as a
|
|
79
|
+
subprocess, so no web server or deployment is needed.
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
- Todoist tools for tasks (with subtasks and deadlines), projects (with
|
|
83
|
+
subprojects), sections, labels and comments.
|
|
84
|
+
- Validated inputs and clear errors. Project, section and label names
|
|
85
|
+
are matched case-insensitively, with Turkish/Unicode normalization. An
|
|
86
|
+
unknown name returns an error and nothing is written; when several
|
|
87
|
+
items match, the tool lists up to 5 candidates as `name (ID)` and asks
|
|
88
|
+
for the ID. The delete and update tools for projects, sections and
|
|
89
|
+
labels accept only an ID or an exact name. Names are limited to 120
|
|
90
|
+
characters for projects and sections and 60 for labels.
|
|
91
|
+
- Tool results in English (default) or Turkish, selected with the
|
|
92
|
+
`PLUGVAN_LANG` environment variable (`en` or `tr`). Tool descriptions
|
|
93
|
+
and logs are always English.
|
|
94
|
+
- Install without cloning (#63): the `plugvan-mcp` distribution (Python
|
|
95
|
+
3.10+) installs from the release wheel with uvx or with pip into a
|
|
96
|
+
virtual environment, and `plugvan-mcp todoist` starts the server. The
|
|
97
|
+
README has the Claude Desktop configs. `plugvan-mcp --version` prints
|
|
98
|
+
the installed version.
|
|
99
|
+
- Configuration in the Claude Desktop config's `env` block:
|
|
100
|
+
`TODOIST_API_TOKEN` and the optional `PLUGVAN_LANG`. `plugvan-mcp`
|
|
101
|
+
does not read a `.env` file.
|
|
102
|
+
- Each release ships a wheel and an sdist as assets.
|
|
103
|
+
|
|
104
|
+
### Security
|
|
105
|
+
- HTTP response bodies of failed Todoist API calls are logged only at
|
|
106
|
+
DEBUG level (#57); the HTTP status is still logged at ERROR. Response
|
|
107
|
+
bodies can echo user content and account data, so they stay out of the
|
|
108
|
+
default (INFO) logs.
|
|
109
|
+
- The token in the `env` block is stored in plain text in
|
|
110
|
+
`claude_desktop_config.json`; keep that file private and never commit
|
|
111
|
+
it to a repository.
|
|
112
|
+
|
|
113
|
+
### Removed
|
|
114
|
+
- The legacy Bridge code (webhook server, Google Tasks sync worker,
|
|
115
|
+
Gemini tool schema) is removed; it is preserved at the tag
|
|
116
|
+
`legacy-bridge-final`.
|
|
117
|
+
|
|
118
|
+
### Upgrading from a checkout
|
|
119
|
+
- If you ran the server from a checkout before, update a Claude Desktop
|
|
120
|
+
config that runs `todoist_mcp.py` to `"args": ["-m", "plugvan.todoist"]`
|
|
121
|
+
with `"PYTHONPATH": "<REPO_PATH>"` in `env`, then restart Claude
|
|
122
|
+
Desktop.
|
|
123
|
+
- Tool results now default to English. To keep Turkish output, set
|
|
124
|
+
`PLUGVAN_LANG=tr` in `.env` or in the `env` block of the Claude Desktop
|
|
125
|
+
config, then restart Claude Desktop.
|
|
126
|
+
- `requirements.txt` is replaced by `pip install -e ".[test]"`: in an
|
|
127
|
+
existing checkout venv, run it instead of
|
|
128
|
+
`pip install -r requirements.txt`.
|
|
129
|
+
|
|
130
|
+
## [0.1.0rc1] - 2026-10-19
|
|
131
|
+
|
|
132
|
+
Release candidate for 0.1.0.
|
|
133
|
+
|
|
134
|
+
## Development history (before 0.1.0)
|
|
135
|
+
|
|
136
|
+
Detailed entries from development before the first release, kept for reference.
|
|
137
|
+
|
|
138
|
+
### Changed
|
|
139
|
+
- README: install Plugvan for Claude Desktop without a clone, with uvx
|
|
140
|
+
or pip from the release wheel; the token goes in the config's `env`
|
|
141
|
+
block (#63).
|
|
142
|
+
- HTTP response bodies of failed Todoist API calls are logged only at
|
|
143
|
+
DEBUG level (#57). The HTTP status is still logged at ERROR. Response
|
|
144
|
+
bodies can echo user content and account data, so they no longer appear
|
|
145
|
+
in the default (INFO) logs.
|
|
146
|
+
- The sdist now contains only what is needed to build and describe the
|
|
147
|
+
package: `plugvan/`, `pyproject.toml`, `PKG-INFO`, `README.md`, `LICENSE`,
|
|
148
|
+
`CHANGELOG.md` and `.gitignore` (which hatchling always adds). Tests,
|
|
149
|
+
docs, CI files, `CLAUDE.md` and `.env.example` are no longer included
|
|
150
|
+
(#61). The wheel is unchanged.
|
|
151
|
+
- **`.env` is read only by `python -m plugvan.todoist` (#59).** The new
|
|
152
|
+
`plugvan-mcp todoist` console script never reads `.env`; it takes
|
|
153
|
+
`TODOIST_API_TOKEN` and `PLUGVAN_LANG` from the environment, i.e. the
|
|
154
|
+
`env` block of the MCP client config, which is the supported way to
|
|
155
|
+
configure it. `python -m plugvan.todoist` keeps loading `.env` as
|
|
156
|
+
before, and variables from the client's `env` block still win over it.
|
|
157
|
+
- **Breaking: tool results are now in English by default (#37).**
|
|
158
|
+
- Every MCP tool result and error message now defaults to English. The
|
|
159
|
+
new optional `PLUGVAN_LANG` environment variable selects the language:
|
|
160
|
+
`en` (default) or `tr`. An unsupported value falls back to English and
|
|
161
|
+
is logged once.
|
|
162
|
+
- **Migration:** to keep the previous Turkish output, set
|
|
163
|
+
`PLUGVAN_LANG=tr` in `.env` or in the `env` block of the Claude Desktop
|
|
164
|
+
config, then restart Claude Desktop. With `PLUGVAN_LANG=tr` the tool
|
|
165
|
+
results are the same as before.
|
|
166
|
+
- Tool descriptions and logs are always English, in both languages.
|
|
167
|
+
- Tool surface: `create_task`'s `project_name` default is now `"Inbox"`
|
|
168
|
+
(was `"Gelen Kutusu"`); a task without a project still goes to the
|
|
169
|
+
Inbox. The `parent_id` description is now English, and the
|
|
170
|
+
`project_name` description and the tool description say `'Inbox'`.
|
|
171
|
+
- **Breaking: safer name resolution in the MCP tools (#9).**
|
|
172
|
+
- `delete_project`, `update_project`, `delete_section`, `update_section`,
|
|
173
|
+
`delete_label` and `update_label` no longer use partial matching or the
|
|
174
|
+
Inbox alias. They accept only an ID or an exact name.
|
|
175
|
+
- An unknown project, section or label name now returns an error, and
|
|
176
|
+
nothing is written. Previously `create_task` silently created the task in
|
|
177
|
+
the Inbox.
|
|
178
|
+
- Sections are matched only by ID or exact name, and only inside the
|
|
179
|
+
resolved project. In `update_task` without `project_name`, that is the
|
|
180
|
+
task's current project.
|
|
181
|
+
- `update_task` validates the target project and section before writing.
|
|
182
|
+
The old "Görev güncellendi fakat hedef proje bulunamadı" and "…hedef
|
|
183
|
+
bölüm bulunamadı" messages are gone, because nothing is updated any more
|
|
184
|
+
when the target is missing.
|
|
185
|
+
- When several items match, the tool returns an ambiguity error that lists
|
|
186
|
+
at most 5 candidates as `name (ID)` and asks for the ID.
|
|
187
|
+
- Labels: a leading `@` is stripped, and two labels whose names differ only
|
|
188
|
+
by case are treated as ambiguous.
|
|
189
|
+
- A project name that partially matches exactly one project is still
|
|
190
|
+
accepted by `create_task`, `update_task`, `create_project` (parent),
|
|
191
|
+
`create_section` and `list_sections`. The message shows the project's
|
|
192
|
+
real name instead of the input.
|
|
193
|
+
- A failed lookup (Todoist API error while listing) returns the tool's
|
|
194
|
+
generic error instead of "not found". Only the error type is logged.
|
|
195
|
+
- The Todoist MCP server moved from the single-file `todoist_mcp.py` into
|
|
196
|
+
the `plugvan.todoist` package (server, client, limits, resolvers, and one
|
|
197
|
+
tools module per domain). No behavior change: same 22 tools, names,
|
|
198
|
+
descriptions and schemas.
|
|
199
|
+
- Entry point is now `python -m plugvan.todoist` (the old script is removed,
|
|
200
|
+
no shim).
|
|
201
|
+
- Tests patch a single target: `plugvan.todoist.client.get_api_client`
|
|
202
|
+
(renamed from the private helper). MCP tests now live in `tests/todoist/`.
|
|
203
|
+
- **Action required:** Claude Desktop configs that run the old
|
|
204
|
+
`todoist_mcp.py` path must be updated to `"args": ["-m", "plugvan.todoist"]`
|
|
205
|
+
with `"PYTHONPATH": "<REPO_PATH>"` in `env`, then restart Claude Desktop.
|
|
206
|
+
|
|
207
|
+
### Added
|
|
208
|
+
- Tag-triggered GitHub Releases (#62): pushing a `v<version>` tag on a
|
|
209
|
+
commit on `main` creates a GitHub Release with the sdist and wheel that
|
|
210
|
+
the `package (ubuntu-24.04, Python 3.10)` job built and tested in the
|
|
211
|
+
same run, after every test and package job passed. The tag must be
|
|
212
|
+
exactly `v` + the `pyproject.toml` version, and the release notes are
|
|
213
|
+
that version's CHANGELOG section. Tags containing `rc` are published
|
|
214
|
+
as prereleases.
|
|
215
|
+
- CI package jobs (#61): `package (ubuntu-24.04, Python 3.10)` builds the
|
|
216
|
+
sdist and wheel once, checks their contents against an allowlist and a
|
|
217
|
+
ban list, installs the wheel into a clean venv and runs the
|
|
218
|
+
installed-mode tests (the STDIO server check and the `.env` rules)
|
|
219
|
+
before uploading the files as an artifact.
|
|
220
|
+
`package (windows-2025, Python 3.14)` installs and tests that same
|
|
221
|
+
artifact on Windows.
|
|
222
|
+
- `plugvan-mcp` console script (#59): `plugvan-mcp todoist` starts the
|
|
223
|
+
Todoist MCP server over STDIO, like `python -m plugvan.todoist`.
|
|
224
|
+
`plugvan-mcp --version` prints the installed version. A missing or
|
|
225
|
+
unknown integration prints usage on stderr and exits with status 2.
|
|
226
|
+
- `pyproject.toml`: the project is now the Python distribution `plugvan-mcp`
|
|
227
|
+
(import package `plugvan`, Python 3.10+), and `pyproject.toml` is the
|
|
228
|
+
single source of its dependencies. Test-only dependencies are in the
|
|
229
|
+
`test` extra (#58).
|
|
230
|
+
- Name-resolution tests: the four resolver outcomes, ambiguity and the
|
|
231
|
+
5-candidate cap, no write on any error, and no exception text or HTTP
|
|
232
|
+
response in tool output or logs.
|
|
233
|
+
- MCP tool surface snapshot test: all 22 tools' name, description,
|
|
234
|
+
input and output schema are compared against a fixture recorded before
|
|
235
|
+
the move.
|
|
236
|
+
- `update_section` MCP tool: rename a Todoist section by ID or name.
|
|
237
|
+
Optional `project_name_or_id` scopes name resolution so same-named
|
|
238
|
+
sections in different projects can't be confused.
|
|
239
|
+
- Tests for `update_section` (rename by name/ID, project scoping,
|
|
240
|
+
not-found, empty/too-long input, sanitized error).
|
|
241
|
+
|
|
242
|
+
### Removed
|
|
243
|
+
- **The legacy Bridge surface.** The repository is now only the
|
|
244
|
+
`plugvan.todoist` MCP server; MCP tools and behavior are unchanged.
|
|
245
|
+
Removed: the FastAPI webhook server (`app.py`), the webhook client
|
|
246
|
+
(`send_to_bridge.py`), the standalone CLI (`main.py`), the Google Tasks
|
|
247
|
+
sync worker (`sync_worker.py`), the shared legacy core (`parser.py`,
|
|
248
|
+
`models.py`, `config.py`, `todoist_client.py`), the Gemini tool schema
|
|
249
|
+
(`gemini_tool_schema.json`), the sample tasks file (`tasks_sample.json`),
|
|
250
|
+
`Dockerfile` / `.dockerignore`, and their tests.
|
|
251
|
+
- The last commit with this code is tagged `legacy-bridge-final`; recover
|
|
252
|
+
it with `git checkout legacy-bridge-final`.
|
|
253
|
+
- Dropped dependencies: `requests`, `pydantic-settings`, `colorama`,
|
|
254
|
+
`fastapi`, `uvicorn`, `google-auth`, `google-auth-oauthlib`,
|
|
255
|
+
`google-auth-httplib2`, `google-api-python-client`, `pytest-asyncio`.
|
|
256
|
+
- `WEBHOOK_SECRET_TOKEN` and `ALLOWED_ORIGINS` are no longer read; only
|
|
257
|
+
`TODOIST_API_TOKEN` is needed.
|
|
258
|
+
- `requirements.txt` (#58). **Migration:** in an existing checkout venv,
|
|
259
|
+
run `pip install -e ".[test]"` instead of `pip install -r requirements.txt`.
|
|
260
|
+
The `python -m plugvan.todoist` Claude Desktop config keeps working
|
|
261
|
+
unchanged.
|
|
262
|
+
- The unused standalone `fastmcp` dependency (#58). The server uses the
|
|
263
|
+
MCP SDK's built-in FastMCP; standalone `fastmcp` will be added back
|
|
264
|
+
with the tool-name namespacing migration.
|
|
265
|
+
|
|
266
|
+
### Fixed
|
|
267
|
+
- MCP clients on Python 3.10–3.12 received indented tool descriptions: the
|
|
268
|
+
3.13+ compiler strips docstring indentation, and older versions did not.
|
|
269
|
+
Descriptions are now normalized at tool registration with a port of the
|
|
270
|
+
3.13 compiler's docstring cleaning, so every supported version publishes
|
|
271
|
+
the same descriptions as 3.13+. Tool docstrings, names and schemas are
|
|
272
|
+
unchanged.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nuri Kağan Kurubaş
|
|
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.
|