compresh-mcp 0.1.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.
- compresh_mcp-0.1.0/LICENSE +34 -0
- compresh_mcp-0.1.0/NOTICES.md +38 -0
- compresh_mcp-0.1.0/PKG-INFO +153 -0
- compresh_mcp-0.1.0/README.md +105 -0
- compresh_mcp-0.1.0/pyproject.toml +99 -0
- compresh_mcp-0.1.0/setup.cfg +4 -0
- compresh_mcp-0.1.0/src/compresh_mcp/__init__.py +26 -0
- compresh_mcp-0.1.0/src/compresh_mcp/auth.py +176 -0
- compresh_mcp-0.1.0/src/compresh_mcp/onboarding.py +95 -0
- compresh_mcp-0.1.0/src/compresh_mcp/server.py +653 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tul1/__init__.py +29 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tul1/epistemic.py +182 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tul1/q_matrix.py +500 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tul1/semantic_store.py +436 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tul1/summarizer.py +407 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/__init__.py +72 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/backfill.py +325 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/cli.py +80 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/cold_storage.py +241 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/compose.py +208 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/compression_log.py +376 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/config.py +73 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/counter.py +63 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/injection.py +525 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/main.py +59 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/modality.py +172 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/pipeline.py +403 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/provenance.py +255 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/retrieval.py +196 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/router.py +172 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/summarizer.py +244 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/system_prompts.py +96 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/tools.py +133 -0
- compresh_mcp-0.1.0/src/compresh_mcp/tulbase/turn_box.py +262 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/PKG-INFO +153 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/SOURCES.txt +39 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/dependency_links.txt +1 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/entry_points.txt +2 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/requires.txt +30 -0
- compresh_mcp-0.1.0/src/compresh_mcp.egg-info/top_level.txt +1 -0
- compresh_mcp-0.1.0/tests/test_smoke.py +90 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
License text Copyright (c) 2026 Compresh Ltd.
|
|
4
|
+
|
|
5
|
+
Parameters
|
|
6
|
+
|
|
7
|
+
Licensor: Compresh Ltd
|
|
8
|
+
Licensed Work: compresh-mcp (this distribution)
|
|
9
|
+
Additional Use Grant: You may use the Licensed Work in non-production
|
|
10
|
+
environments. Production use requires a valid
|
|
11
|
+
Compresh subscription — see https://compre.sh/pricing
|
|
12
|
+
Change Date: 2030-05-16
|
|
13
|
+
Change License: MIT License
|
|
14
|
+
|
|
15
|
+
For information about alternative licensing arrangements, contact
|
|
16
|
+
hello@compre.sh.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
Notice
|
|
21
|
+
|
|
22
|
+
The Business Source License (this document, or the "License") is not an
|
|
23
|
+
Open Source license. However, the Licensed Work will eventually be made
|
|
24
|
+
available under an Open Source License, as stated in this License.
|
|
25
|
+
|
|
26
|
+
Full BSL 1.1 text: https://mariadb.com/bsl11/
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
Patent notice
|
|
31
|
+
|
|
32
|
+
Q-protective ranking + Protection Zone are covered by TR-TPMK patent
|
|
33
|
+
application 2026/007305 (Compresh Ltd, May 2026). A valid Compresh
|
|
34
|
+
subscription includes implementation license for the covered claims.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Third-Party Notices
|
|
2
|
+
|
|
3
|
+
This package, `compresh-mcp` (BUSL-1.1), bundles third-party code.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## tulbase (MIT)
|
|
8
|
+
|
|
9
|
+
The `compresh_mcp.tulbase` subpackage is a vendored copy of
|
|
10
|
+
[tulbase](https://github.com/compresh/tulbase), a depth-aware context
|
|
11
|
+
compression library for LLM proxies.
|
|
12
|
+
|
|
13
|
+
- **License**: MIT
|
|
14
|
+
- **Copyright**: © 2026 Compresh Ltd
|
|
15
|
+
- **Upstream**: https://github.com/compresh/tulbase
|
|
16
|
+
- **Vendored version**: 0.2.0
|
|
17
|
+
- **License text**: see `src/compresh_mcp/tulbase/LICENSE`
|
|
18
|
+
|
|
19
|
+
The vendored copy is the canonical reference implementation. The standalone
|
|
20
|
+
`tulbase` PyPI package (when published) will contain identical code. Vendoring
|
|
21
|
+
exists to keep `compresh-mcp` self-contained on PyPI without forcing a
|
|
22
|
+
separate dependency.
|
|
23
|
+
|
|
24
|
+
If you only need the MIT open-core compression layer (turn-box, protection zone,
|
|
25
|
+
compose, retrieval) without the Compresh paid-tier TUL 1.0 classifiers, prefer
|
|
26
|
+
installing the standalone package once it ships:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install tulbase
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Acknowledgements
|
|
35
|
+
|
|
36
|
+
- [Model Context Protocol](https://modelcontextprotocol.io/) — Anthropic
|
|
37
|
+
- [sentence-transformers](https://www.sbert.net/) — UKPLab (MIT)
|
|
38
|
+
- [DuckDB](https://duckdb.org/) — DuckDB Foundation (MIT)
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: compresh-mcp
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: MCP server for Compresh — production-grade context compression with Q-protective ranking, epistemic markers, and depth-aware adaptation
|
|
5
|
+
Author-email: Compresh Ltd <hello@compre.sh>
|
|
6
|
+
License: BUSL-1.1
|
|
7
|
+
Project-URL: Homepage, https://compre.sh
|
|
8
|
+
Project-URL: Documentation, https://compre.sh/docs
|
|
9
|
+
Project-URL: Issues, https://github.com/compresh/compresh-mcp/issues
|
|
10
|
+
Keywords: mcp,model-context-protocol,llm,agent,context-compression,compresh,q-protective,epistemic,tulving
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: License :: Other/Proprietary License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
License-File: NOTICES.md
|
|
23
|
+
Requires-Dist: mcp>=1.0.0
|
|
24
|
+
Requires-Dist: duckdb>=0.10.0
|
|
25
|
+
Requires-Dist: httpx>=0.24.0
|
|
26
|
+
Requires-Dist: sentence-transformers>=2.2.0
|
|
27
|
+
Requires-Dist: scikit-learn>=1.3.0
|
|
28
|
+
Provides-Extra: tokenizer
|
|
29
|
+
Requires-Dist: tiktoken>=0.5.0; extra == "tokenizer"
|
|
30
|
+
Provides-Extra: summarizer
|
|
31
|
+
Requires-Dist: sumy>=0.11.0; extra == "summarizer"
|
|
32
|
+
Requires-Dist: nltk>=3.8.0; extra == "summarizer"
|
|
33
|
+
Provides-Extra: injection
|
|
34
|
+
Requires-Dist: torch>=2.0.0; extra == "injection"
|
|
35
|
+
Requires-Dist: transformers>=4.30.0; extra == "injection"
|
|
36
|
+
Provides-Extra: proxy
|
|
37
|
+
Requires-Dist: fastapi>=0.100.0; extra == "proxy"
|
|
38
|
+
Requires-Dist: uvicorn>=0.23.0; extra == "proxy"
|
|
39
|
+
Provides-Extra: verify
|
|
40
|
+
Requires-Dist: tiktoken>=0.7.0; extra == "verify"
|
|
41
|
+
Requires-Dist: transformers>=4.40.0; extra == "verify"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
44
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
45
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
46
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
48
|
+
|
|
49
|
+
# compresh-mcp
|
|
50
|
+
|
|
51
|
+
**MCP server for Compresh** — production-grade context compression for LLM agent conversations.
|
|
52
|
+
|
|
53
|
+
> Compresh adds Q-protective ranking, epistemic marker classification, and
|
|
54
|
+
> depth-aware adaptation on top of the open-source [`tulbase`](https://github.com/compresh/tulbase)
|
|
55
|
+
> compression core. This is the **paid tier** distribution.
|
|
56
|
+
|
|
57
|
+
## What's the difference vs `tulbase-mcp`?
|
|
58
|
+
|
|
59
|
+
| Feature | `tulbase-mcp` (free, open-source) | `compresh-mcp` (paid) |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| Base LexRank summarization | ✅ | ✅ |
|
|
62
|
+
| Modality elision (code, terminal, JSON, stack traces) | ✅ | ✅ |
|
|
63
|
+
| Cold storage + fetch_compressed | ✅ | ✅ |
|
|
64
|
+
| Protection Zone (Claim 1e) | ✅ | ✅ |
|
|
65
|
+
| **Q-protective sentence ranking** (Q1–Q4 categorization) | ❌ | ✅ |
|
|
66
|
+
| **Epistemic markers** (VR/HR/CR/UC) | ❌ | ✅ |
|
|
67
|
+
| **Semantic store** (cross-turn Q3 dedup) | ❌ | ✅ |
|
|
68
|
+
| Saving telemetry to Compresh dashboard | ❌ | ✅ |
|
|
69
|
+
| Multi-device sync (planned) | ❌ | ✅ |
|
|
70
|
+
|
|
71
|
+
In Compresh's bench (Compresh-bench v1, 600-turn multi-model), Q-protective
|
|
72
|
+
ranking adds **5–12 percentage points** of equivalence preservation vs
|
|
73
|
+
base LexRank at the same token savings — Pareto improvement.
|
|
74
|
+
|
|
75
|
+
## Pricing
|
|
76
|
+
|
|
77
|
+
See [https://compre.sh/pricing](https://compre.sh/pricing). Three tiers:
|
|
78
|
+
|
|
79
|
+
- **Tier-A** (integrated MCP/OAuth metadata, e.g. Cowork, Claude Code, Cursor):
|
|
80
|
+
saving-share **%25** on actual model cost
|
|
81
|
+
- **Tier-B** (family-level provider declaration):
|
|
82
|
+
saving-share **%25** on the family's cheapest model price
|
|
83
|
+
- **Tier-C** (anonymous / local LLM / free models):
|
|
84
|
+
flat **$0.20 per 1M saved input tokens**
|
|
85
|
+
|
|
86
|
+
Every new user: **$30 free credit** (90-day expiry), **$10 minimum budget**
|
|
87
|
+
(charged $7.5 after standard %25 discount).
|
|
88
|
+
|
|
89
|
+
## Installation
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
pip install compresh-mcp
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
On first run, you'll be prompted for your Compresh API key. If you don't
|
|
96
|
+
have an account, your browser opens to [compre.sh/signup](https://compre.sh/signup)
|
|
97
|
+
automatically.
|
|
98
|
+
|
|
99
|
+
## MCP client configuration
|
|
100
|
+
|
|
101
|
+
### Claude Code (`~/.claude/mcp.json`)
|
|
102
|
+
|
|
103
|
+
```json
|
|
104
|
+
{
|
|
105
|
+
"mcpServers": {
|
|
106
|
+
"compresh": {
|
|
107
|
+
"command": "compresh-mcp",
|
|
108
|
+
"env": {
|
|
109
|
+
"COMPRESH_API_KEY": "sk-comp_...",
|
|
110
|
+
"COMPRESH_API_BASE": "https://api.compre.sh"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Cursor (`~/.cursor/mcp.json`)
|
|
118
|
+
|
|
119
|
+
Same structure as Claude Code.
|
|
120
|
+
|
|
121
|
+
### Cowork
|
|
122
|
+
|
|
123
|
+
Cowork → Settings → Tools → MCP servers → Add:
|
|
124
|
+
- Command: `compresh-mcp`
|
|
125
|
+
- Environment: `COMPRESH_API_KEY=sk-comp_...`
|
|
126
|
+
|
|
127
|
+
## Tools exposed
|
|
128
|
+
|
|
129
|
+
Same four tools as `tulbase-mcp`, with enhanced behavior:
|
|
130
|
+
|
|
131
|
+
- `compress` — Q-protective compression by default (`protection_mode="balanced"`)
|
|
132
|
+
- `fetch_compressed`, `list_compressed`, `stats` — same interface
|
|
133
|
+
|
|
134
|
+
Plus paid-tier extras:
|
|
135
|
+
|
|
136
|
+
- `usage` — current cycle budget, free credit balance, savings metrics
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
Business Source License 1.1 — see [LICENSE](./LICENSE). Production use
|
|
141
|
+
permitted with valid Compresh API key. License automatically converts
|
|
142
|
+
to MIT after 4 years (Year 2030).
|
|
143
|
+
|
|
144
|
+
## Patents
|
|
145
|
+
|
|
146
|
+
Q-protective sentence ranking + Protection Zone are covered by
|
|
147
|
+
**TR-TPMK patent application 2026/007305** (Compresh Ltd, May 2026).
|
|
148
|
+
A valid Compresh subscription grants implementation license.
|
|
149
|
+
|
|
150
|
+
## Status
|
|
151
|
+
|
|
152
|
+
This repo is **private** during dogfood phase (May 2026). Public release
|
|
153
|
+
scheduled for Q3 2026 alongside the Compresh dashboard MVP.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# compresh-mcp
|
|
2
|
+
|
|
3
|
+
**MCP server for Compresh** — production-grade context compression for LLM agent conversations.
|
|
4
|
+
|
|
5
|
+
> Compresh adds Q-protective ranking, epistemic marker classification, and
|
|
6
|
+
> depth-aware adaptation on top of the open-source [`tulbase`](https://github.com/compresh/tulbase)
|
|
7
|
+
> compression core. This is the **paid tier** distribution.
|
|
8
|
+
|
|
9
|
+
## What's the difference vs `tulbase-mcp`?
|
|
10
|
+
|
|
11
|
+
| Feature | `tulbase-mcp` (free, open-source) | `compresh-mcp` (paid) |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| Base LexRank summarization | ✅ | ✅ |
|
|
14
|
+
| Modality elision (code, terminal, JSON, stack traces) | ✅ | ✅ |
|
|
15
|
+
| Cold storage + fetch_compressed | ✅ | ✅ |
|
|
16
|
+
| Protection Zone (Claim 1e) | ✅ | ✅ |
|
|
17
|
+
| **Q-protective sentence ranking** (Q1–Q4 categorization) | ❌ | ✅ |
|
|
18
|
+
| **Epistemic markers** (VR/HR/CR/UC) | ❌ | ✅ |
|
|
19
|
+
| **Semantic store** (cross-turn Q3 dedup) | ❌ | ✅ |
|
|
20
|
+
| Saving telemetry to Compresh dashboard | ❌ | ✅ |
|
|
21
|
+
| Multi-device sync (planned) | ❌ | ✅ |
|
|
22
|
+
|
|
23
|
+
In Compresh's bench (Compresh-bench v1, 600-turn multi-model), Q-protective
|
|
24
|
+
ranking adds **5–12 percentage points** of equivalence preservation vs
|
|
25
|
+
base LexRank at the same token savings — Pareto improvement.
|
|
26
|
+
|
|
27
|
+
## Pricing
|
|
28
|
+
|
|
29
|
+
See [https://compre.sh/pricing](https://compre.sh/pricing). Three tiers:
|
|
30
|
+
|
|
31
|
+
- **Tier-A** (integrated MCP/OAuth metadata, e.g. Cowork, Claude Code, Cursor):
|
|
32
|
+
saving-share **%25** on actual model cost
|
|
33
|
+
- **Tier-B** (family-level provider declaration):
|
|
34
|
+
saving-share **%25** on the family's cheapest model price
|
|
35
|
+
- **Tier-C** (anonymous / local LLM / free models):
|
|
36
|
+
flat **$0.20 per 1M saved input tokens**
|
|
37
|
+
|
|
38
|
+
Every new user: **$30 free credit** (90-day expiry), **$10 minimum budget**
|
|
39
|
+
(charged $7.5 after standard %25 discount).
|
|
40
|
+
|
|
41
|
+
## Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install compresh-mcp
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
On first run, you'll be prompted for your Compresh API key. If you don't
|
|
48
|
+
have an account, your browser opens to [compre.sh/signup](https://compre.sh/signup)
|
|
49
|
+
automatically.
|
|
50
|
+
|
|
51
|
+
## MCP client configuration
|
|
52
|
+
|
|
53
|
+
### Claude Code (`~/.claude/mcp.json`)
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"mcpServers": {
|
|
58
|
+
"compresh": {
|
|
59
|
+
"command": "compresh-mcp",
|
|
60
|
+
"env": {
|
|
61
|
+
"COMPRESH_API_KEY": "sk-comp_...",
|
|
62
|
+
"COMPRESH_API_BASE": "https://api.compre.sh"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Cursor (`~/.cursor/mcp.json`)
|
|
70
|
+
|
|
71
|
+
Same structure as Claude Code.
|
|
72
|
+
|
|
73
|
+
### Cowork
|
|
74
|
+
|
|
75
|
+
Cowork → Settings → Tools → MCP servers → Add:
|
|
76
|
+
- Command: `compresh-mcp`
|
|
77
|
+
- Environment: `COMPRESH_API_KEY=sk-comp_...`
|
|
78
|
+
|
|
79
|
+
## Tools exposed
|
|
80
|
+
|
|
81
|
+
Same four tools as `tulbase-mcp`, with enhanced behavior:
|
|
82
|
+
|
|
83
|
+
- `compress` — Q-protective compression by default (`protection_mode="balanced"`)
|
|
84
|
+
- `fetch_compressed`, `list_compressed`, `stats` — same interface
|
|
85
|
+
|
|
86
|
+
Plus paid-tier extras:
|
|
87
|
+
|
|
88
|
+
- `usage` — current cycle budget, free credit balance, savings metrics
|
|
89
|
+
|
|
90
|
+
## License
|
|
91
|
+
|
|
92
|
+
Business Source License 1.1 — see [LICENSE](./LICENSE). Production use
|
|
93
|
+
permitted with valid Compresh API key. License automatically converts
|
|
94
|
+
to MIT after 4 years (Year 2030).
|
|
95
|
+
|
|
96
|
+
## Patents
|
|
97
|
+
|
|
98
|
+
Q-protective sentence ranking + Protection Zone are covered by
|
|
99
|
+
**TR-TPMK patent application 2026/007305** (Compresh Ltd, May 2026).
|
|
100
|
+
A valid Compresh subscription grants implementation license.
|
|
101
|
+
|
|
102
|
+
## Status
|
|
103
|
+
|
|
104
|
+
This repo is **private** during dogfood phase (May 2026). Public release
|
|
105
|
+
scheduled for Q3 2026 alongside the Compresh dashboard MVP.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "compresh-mcp"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "MCP server for Compresh — production-grade context compression with Q-protective ranking, epistemic markers, and depth-aware adaptation"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "BUSL-1.1" }
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Compresh Ltd", email = "hello@compre.sh" },
|
|
13
|
+
]
|
|
14
|
+
keywords = [
|
|
15
|
+
"mcp",
|
|
16
|
+
"model-context-protocol",
|
|
17
|
+
"llm",
|
|
18
|
+
"agent",
|
|
19
|
+
"context-compression",
|
|
20
|
+
"compresh",
|
|
21
|
+
"q-protective",
|
|
22
|
+
"epistemic",
|
|
23
|
+
"tulving",
|
|
24
|
+
]
|
|
25
|
+
classifiers = [
|
|
26
|
+
"Development Status :: 3 - Alpha",
|
|
27
|
+
"License :: Other/Proprietary License",
|
|
28
|
+
"Programming Language :: Python :: 3",
|
|
29
|
+
"Programming Language :: Python :: 3.10",
|
|
30
|
+
"Programming Language :: Python :: 3.11",
|
|
31
|
+
"Programming Language :: Python :: 3.12",
|
|
32
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
33
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
34
|
+
]
|
|
35
|
+
requires-python = ">=3.10"
|
|
36
|
+
dependencies = [
|
|
37
|
+
"mcp >= 1.0.0",
|
|
38
|
+
"duckdb >= 0.10.0",
|
|
39
|
+
"httpx >= 0.24.0",
|
|
40
|
+
"sentence-transformers >= 2.2.0",
|
|
41
|
+
"scikit-learn >= 1.3.0",
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
[project.optional-dependencies]
|
|
45
|
+
# tulbase tokenizer (cost counter)
|
|
46
|
+
tokenizer = [
|
|
47
|
+
"tiktoken >= 0.5.0",
|
|
48
|
+
]
|
|
49
|
+
# tulbase summarizer (LexRank — recommended for production)
|
|
50
|
+
summarizer = [
|
|
51
|
+
"sumy >= 0.11.0",
|
|
52
|
+
"nltk >= 3.8.0",
|
|
53
|
+
]
|
|
54
|
+
# tulbase injection detector (heavy ML deps)
|
|
55
|
+
injection = [
|
|
56
|
+
"torch >= 2.0.0",
|
|
57
|
+
"transformers >= 4.30.0",
|
|
58
|
+
]
|
|
59
|
+
# tulbase FastAPI proxy mode (not needed for MCP stdio usage)
|
|
60
|
+
proxy = [
|
|
61
|
+
"fastapi >= 0.100.0",
|
|
62
|
+
"uvicorn >= 0.23.0",
|
|
63
|
+
]
|
|
64
|
+
verify = [
|
|
65
|
+
"tiktoken >= 0.7.0",
|
|
66
|
+
"transformers >= 4.40.0",
|
|
67
|
+
]
|
|
68
|
+
dev = [
|
|
69
|
+
"pytest >= 8.0",
|
|
70
|
+
"pytest-asyncio >= 0.23",
|
|
71
|
+
"ruff >= 0.4",
|
|
72
|
+
"mypy >= 1.10",
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
[project.urls]
|
|
76
|
+
Homepage = "https://compre.sh"
|
|
77
|
+
Documentation = "https://compre.sh/docs"
|
|
78
|
+
Issues = "https://github.com/compresh/compresh-mcp/issues"
|
|
79
|
+
|
|
80
|
+
[project.scripts]
|
|
81
|
+
compresh-mcp = "compresh_mcp.server:main"
|
|
82
|
+
|
|
83
|
+
[tool.setuptools.packages.find]
|
|
84
|
+
where = ["src"]
|
|
85
|
+
|
|
86
|
+
[tool.setuptools.package-data]
|
|
87
|
+
compresh_mcp = ["py.typed"]
|
|
88
|
+
|
|
89
|
+
[tool.ruff]
|
|
90
|
+
line-length = 100
|
|
91
|
+
target-version = "py310"
|
|
92
|
+
|
|
93
|
+
[tool.ruff.lint]
|
|
94
|
+
select = ["E", "F", "I", "N", "UP", "B", "C4", "SIM", "RUF"]
|
|
95
|
+
ignore = ["E501"]
|
|
96
|
+
|
|
97
|
+
[tool.pytest.ini_options]
|
|
98
|
+
asyncio_mode = "auto"
|
|
99
|
+
testpaths = ["tests"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""compresh-mcp — MCP server for Compresh paid tier.
|
|
2
|
+
|
|
3
|
+
Bundles the open-source tulbase compression core (MIT, vendored as
|
|
4
|
+
``compresh_mcp.tulbase``) and adds the proprietary TUL 1.0 layer:
|
|
5
|
+
|
|
6
|
+
- Q-protective sentence ranking (Q1-Q4 categorization)
|
|
7
|
+
- Epistemic marker classification (VR/HR/CR/UC)
|
|
8
|
+
- Semantic store (cross-turn Q3 dedup)
|
|
9
|
+
- Auth + saving telemetry to Compresh dashboard
|
|
10
|
+
|
|
11
|
+
The vendored tulbase code is the canonical reference (MIT, © Compresh Ltd 2026,
|
|
12
|
+
see ``tulbase/LICENSE``). For the standalone tulbase distribution, see
|
|
13
|
+
https://github.com/compresh/tulbase.
|
|
14
|
+
|
|
15
|
+
For pricing and account management, see https://compre.sh.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from . import tulbase
|
|
19
|
+
|
|
20
|
+
__version__ = "0.1.0"
|
|
21
|
+
__author__ = "Compresh Ltd"
|
|
22
|
+
__license__ = "BUSL-1.1"
|
|
23
|
+
|
|
24
|
+
from .server import main as run_server
|
|
25
|
+
|
|
26
|
+
__all__ = ["__version__", "run_server", "tulbase"]
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
"""Compresh API key validation + usage telemetry.
|
|
2
|
+
|
|
3
|
+
The MCP server validates the user's COMPRESH_API_KEY against the
|
|
4
|
+
Compresh production API at startup, then reports per-session savings
|
|
5
|
+
back so the dashboard reflects local usage.
|
|
6
|
+
|
|
7
|
+
The Compresh API base URL is configurable via COMPRESH_API_BASE
|
|
8
|
+
(default: https://api.compre.sh) — useful for staging/dev environments.
|
|
9
|
+
|
|
10
|
+
Validation flow:
|
|
11
|
+
|
|
12
|
+
1. Read COMPRESH_API_KEY from environment.
|
|
13
|
+
2. If missing/empty -> raise NoApiKey (caller triggers onboarding flow).
|
|
14
|
+
3. POST to /v1/auth/verify with Bearer token.
|
|
15
|
+
4. If 200 -> cache validated key + user info for session lifetime.
|
|
16
|
+
5. If 401/403 -> raise InvalidApiKey (caller may re-prompt).
|
|
17
|
+
6. If network failure -> raise AuthNetworkError (caller may proceed
|
|
18
|
+
in offline mode with a warning).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import logging
|
|
24
|
+
import os
|
|
25
|
+
from dataclasses import dataclass
|
|
26
|
+
from typing import Optional
|
|
27
|
+
|
|
28
|
+
import httpx
|
|
29
|
+
|
|
30
|
+
logger = logging.getLogger("compresh-mcp.auth")
|
|
31
|
+
|
|
32
|
+
DEFAULT_API_BASE = os.environ.get("COMPRESH_API_BASE", "https://api.compre.sh")
|
|
33
|
+
DEFAULT_TIMEOUT = float(os.environ.get("COMPRESH_AUTH_TIMEOUT", "10"))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
# ---------------------------------------------------------------------------
|
|
37
|
+
# Exceptions
|
|
38
|
+
# ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AuthError(Exception):
|
|
42
|
+
"""Base class for auth failures."""
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class NoApiKey(AuthError):
|
|
46
|
+
"""COMPRESH_API_KEY environment variable missing or empty."""
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class InvalidApiKey(AuthError):
|
|
50
|
+
"""API key was rejected by the Compresh server (401/403)."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class AuthNetworkError(AuthError):
|
|
54
|
+
"""Network or unexpected error while contacting Compresh server."""
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
# Result dataclass
|
|
59
|
+
# ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@dataclass(slots=True)
|
|
63
|
+
class AuthResult:
|
|
64
|
+
"""Outcome of a successful key validation."""
|
|
65
|
+
|
|
66
|
+
ok: bool
|
|
67
|
+
api_key: str
|
|
68
|
+
email: Optional[str] = None
|
|
69
|
+
tier: Optional[str] = None # "free" | "pro"
|
|
70
|
+
free_credit_remaining: Optional[float] = None
|
|
71
|
+
budget_remaining: Optional[float] = None
|
|
72
|
+
error: Optional[str] = None
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# ---------------------------------------------------------------------------
|
|
76
|
+
# Public API
|
|
77
|
+
# ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def get_api_key() -> Optional[str]:
|
|
81
|
+
"""Read COMPRESH_API_KEY from environment, return None if missing/empty."""
|
|
82
|
+
key = (os.environ.get("COMPRESH_API_KEY") or "").strip()
|
|
83
|
+
return key or None
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def verify_api_key(
|
|
87
|
+
api_key: Optional[str] = None,
|
|
88
|
+
*,
|
|
89
|
+
api_base: str = DEFAULT_API_BASE,
|
|
90
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
91
|
+
) -> AuthResult:
|
|
92
|
+
"""Validate an API key against the Compresh server.
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
NoApiKey: key is missing/empty.
|
|
96
|
+
InvalidApiKey: key was rejected (401/403).
|
|
97
|
+
AuthNetworkError: transport-level failure (caller decides whether
|
|
98
|
+
to proceed in offline mode).
|
|
99
|
+
"""
|
|
100
|
+
key = api_key or get_api_key()
|
|
101
|
+
if not key:
|
|
102
|
+
raise NoApiKey("COMPRESH_API_KEY environment variable is not set")
|
|
103
|
+
|
|
104
|
+
url = f"{api_base.rstrip('/')}/v1/auth/verify"
|
|
105
|
+
headers = {"Authorization": f"Bearer {key}", "Accept": "application/json"}
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
with httpx.Client(timeout=timeout) as client:
|
|
109
|
+
resp = client.get(url, headers=headers)
|
|
110
|
+
except httpx.HTTPError as e:
|
|
111
|
+
logger.warning("auth network error: %s", e)
|
|
112
|
+
raise AuthNetworkError(f"network error: {type(e).__name__}: {e}") from e
|
|
113
|
+
|
|
114
|
+
if resp.status_code in (401, 403):
|
|
115
|
+
logger.info("auth rejected: %d", resp.status_code)
|
|
116
|
+
raise InvalidApiKey(f"server rejected key (HTTP {resp.status_code})")
|
|
117
|
+
|
|
118
|
+
if resp.status_code != 200:
|
|
119
|
+
logger.warning("auth unexpected status: %d", resp.status_code)
|
|
120
|
+
raise AuthNetworkError(f"unexpected HTTP {resp.status_code}")
|
|
121
|
+
|
|
122
|
+
data = resp.json() if resp.content else {}
|
|
123
|
+
return AuthResult(
|
|
124
|
+
ok=True,
|
|
125
|
+
api_key=key,
|
|
126
|
+
email=data.get("email"),
|
|
127
|
+
tier=data.get("tier"),
|
|
128
|
+
free_credit_remaining=data.get("free_credit_remaining"),
|
|
129
|
+
budget_remaining=data.get("budget_remaining"),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def report_usage(
|
|
134
|
+
api_key: str,
|
|
135
|
+
*,
|
|
136
|
+
session_id: str,
|
|
137
|
+
saved_input_tokens: int,
|
|
138
|
+
saved_chars: int,
|
|
139
|
+
n_turns: int,
|
|
140
|
+
n_compressed_entries: int,
|
|
141
|
+
provider_hint: Optional[str] = None,
|
|
142
|
+
model_hint: Optional[str] = None,
|
|
143
|
+
api_base: str = DEFAULT_API_BASE,
|
|
144
|
+
timeout: float = DEFAULT_TIMEOUT,
|
|
145
|
+
) -> bool:
|
|
146
|
+
"""Send a per-session usage report to Compresh for billing/telemetry.
|
|
147
|
+
|
|
148
|
+
Returns True on 2xx, False otherwise. Failures are non-fatal — local
|
|
149
|
+
compression continues, telemetry catches up at the next successful
|
|
150
|
+
report.
|
|
151
|
+
"""
|
|
152
|
+
url = f"{api_base.rstrip('/')}/v1/usage/report"
|
|
153
|
+
headers = {
|
|
154
|
+
"Authorization": f"Bearer {api_key}",
|
|
155
|
+
"Content-Type": "application/json",
|
|
156
|
+
}
|
|
157
|
+
payload = {
|
|
158
|
+
"session_id": session_id,
|
|
159
|
+
"saved_input_tokens": saved_input_tokens,
|
|
160
|
+
"saved_chars": saved_chars,
|
|
161
|
+
"n_turns": n_turns,
|
|
162
|
+
"n_compressed_entries": n_compressed_entries,
|
|
163
|
+
"provider_hint": provider_hint,
|
|
164
|
+
"model_hint": model_hint,
|
|
165
|
+
"source": "compresh-mcp",
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
with httpx.Client(timeout=timeout) as client:
|
|
170
|
+
resp = client.post(url, headers=headers, json=payload)
|
|
171
|
+
if 200 <= resp.status_code < 300:
|
|
172
|
+
return True
|
|
173
|
+
logger.warning("usage report rejected: %d", resp.status_code)
|
|
174
|
+
except httpx.HTTPError as e:
|
|
175
|
+
logger.warning("usage report network error: %s", e)
|
|
176
|
+
return False
|