ahnlich-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.
- ahnlich_mcp-0.1.1/.dockerignore +7 -0
- ahnlich_mcp-0.1.1/.gitignore +7 -0
- ahnlich_mcp-0.1.1/.python-version +1 -0
- ahnlich_mcp-0.1.1/Dockerfile +35 -0
- ahnlich_mcp-0.1.1/LICENSE +21 -0
- ahnlich_mcp-0.1.1/PKG-INFO +331 -0
- ahnlich_mcp-0.1.1/README.md +319 -0
- ahnlich_mcp-0.1.1/docker-compose.yml +96 -0
- ahnlich_mcp-0.1.1/pyproject.toml +39 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/__init__.py +3 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/backends/__init__.py +45 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/backends/ai.py +278 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/backends/base.py +694 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/backends/db.py +233 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/config.py +148 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/models.py +27 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/server.py +216 -0
- ahnlich_mcp-0.1.1/src/ahnlich_mcp/tools.py +565 -0
- ahnlich_mcp-0.1.1/tests/__init__.py +1 -0
- ahnlich_mcp-0.1.1/tests/integration/test_ai_backend.py +496 -0
- ahnlich_mcp-0.1.1/tests/integration/test_db_backend.py +463 -0
- ahnlich_mcp-0.1.1/tests/integration/test_mcp_stdio.py +551 -0
- ahnlich_mcp-0.1.1/tests/unit/test_backend_base.py +1017 -0
- ahnlich_mcp-0.1.1/tests/unit/test_backend_factory.py +93 -0
- ahnlich_mcp-0.1.1/tests/unit/test_config.py +279 -0
- ahnlich_mcp-0.1.1/tests/unit/test_db_validation.py +80 -0
- ahnlich_mcp-0.1.1/tests/unit/test_server.py +204 -0
- ahnlich_mcp-0.1.1/tests/unit/test_tool_errors.py +96 -0
- ahnlich_mcp-0.1.1/tests/unit/test_tools.py +579 -0
- ahnlich_mcp-0.1.1/uv.lock +1286 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.11
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
FROM python:3.11-slim-bookworm AS builder
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
ENV UV_COMPILE_BYTECODE=1 \
|
|
6
|
+
UV_LINK_MODE=copy
|
|
7
|
+
|
|
8
|
+
RUN pip install --no-cache-dir uv==0.11.31
|
|
9
|
+
|
|
10
|
+
COPY pyproject.toml uv.lock README.md LICENSE ./
|
|
11
|
+
COPY src ./src
|
|
12
|
+
|
|
13
|
+
RUN uv sync --locked --no-dev --no-editable
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
FROM python:3.11-slim-bookworm AS runtime
|
|
17
|
+
|
|
18
|
+
RUN useradd \
|
|
19
|
+
--create-home \
|
|
20
|
+
--uid 10001 \
|
|
21
|
+
--shell /usr/sbin/nologin \
|
|
22
|
+
ahnlich
|
|
23
|
+
|
|
24
|
+
WORKDIR /app
|
|
25
|
+
|
|
26
|
+
ENV PATH="/app/.venv/bin:$PATH" \
|
|
27
|
+
PYTHONUNBUFFERED=1 \
|
|
28
|
+
PYTHONDONTWRITEBYTECODE=1
|
|
29
|
+
|
|
30
|
+
COPY --from=builder /app/.venv /app/.venv
|
|
31
|
+
|
|
32
|
+
USER ahnlich
|
|
33
|
+
|
|
34
|
+
ENTRYPOINT ["ahnlich-mcp"]
|
|
35
|
+
CMD ["--profile", "ai"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ahnlich 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,331 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ahnlich-mcp
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: MCP server for the Ahnlich vector database
|
|
5
|
+
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: <3.14,>=3.11
|
|
8
|
+
Requires-Dist: ahnlich-client-py==0.4.0
|
|
9
|
+
Requires-Dist: betterproto<3,>=2.0.0b7
|
|
10
|
+
Requires-Dist: mcp<2,>=1.27
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
|
|
13
|
+
# Ahnlich MCP
|
|
14
|
+
|
|
15
|
+
An MCP server that exposes [Ahnlich](https://ahnlich.dev/) vector storage and semantic search to MCP-compatible agents.
|
|
16
|
+
|
|
17
|
+
Ahnlich MCP supports two profiles:
|
|
18
|
+
|
|
19
|
+
- `db` connects directly to Ahnlich DB and accepts precomputed embeddings.
|
|
20
|
+
- `ai` sends raw text through Ahnlich AI, which generates embeddings and stores them in Ahnlich DB.
|
|
21
|
+
|
|
22
|
+
## Before you start
|
|
23
|
+
|
|
24
|
+
Ahnlich MCP connects to running Ahnlich services.
|
|
25
|
+
|
|
26
|
+
| Profile | Required services |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `ai` | Ahnlich DB on port `1369` and Ahnlich AI on port `1370` |
|
|
29
|
+
| `db` | Ahnlich DB on port `1369` |
|
|
30
|
+
|
|
31
|
+
Follow the [Ahnlich installation guide](https://ahnlich.dev/docs/getting-started/installation/) to start the required services.
|
|
32
|
+
|
|
33
|
+
The examples below use the `ai` profile. To supply your own embeddings, replace `--profile ai` with `--profile db`.
|
|
34
|
+
|
|
35
|
+
## Install from PyPI
|
|
36
|
+
|
|
37
|
+
This is the recommended installation method. Install [uv](https://docs.astral.sh/uv/getting-started/installation/), then use `uvx` to run Ahnlich MCP directly from PyPI.
|
|
38
|
+
|
|
39
|
+
Verify that the required Ahnlich services are available:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
uvx ahnlich-mcp doctor --profile ai
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Claude Desktop
|
|
46
|
+
|
|
47
|
+
Open **Settings → Developer → Edit Config** and add:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"mcpServers": {
|
|
52
|
+
"ahnlich": {
|
|
53
|
+
"command": "uvx",
|
|
54
|
+
"args": [
|
|
55
|
+
"ahnlich-mcp",
|
|
56
|
+
"--profile",
|
|
57
|
+
"ai"
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Restart Claude Desktop after saving the configuration.
|
|
65
|
+
|
|
66
|
+
If Claude Desktop cannot find `uvx`, run `command -v uvx` and use the returned absolute path as `command`.
|
|
67
|
+
|
|
68
|
+
### Codex
|
|
69
|
+
|
|
70
|
+
Add the server from your terminal:
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
codex mcp add ahnlich -- uvx ahnlich-mcp --profile ai
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Confirm that it was added:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
codex mcp list
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
You can also use `/mcp` inside Codex to inspect the connection.
|
|
83
|
+
|
|
84
|
+
## Run with Docker
|
|
85
|
+
|
|
86
|
+
Use Docker when you want the MCP server and its Python dependencies isolated in a container.
|
|
87
|
+
|
|
88
|
+
The Ahnlich services must already be running and accessible through their default host ports.
|
|
89
|
+
|
|
90
|
+
Pull the image:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
docker pull ghcr.io/deven96/ahnlich-mcp:latest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Claude Desktop
|
|
97
|
+
|
|
98
|
+
Add the following to the Claude Desktop configuration:
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"mcpServers": {
|
|
103
|
+
"ahnlich": {
|
|
104
|
+
"command": "docker",
|
|
105
|
+
"args": [
|
|
106
|
+
"run",
|
|
107
|
+
"--rm",
|
|
108
|
+
"-i",
|
|
109
|
+
"--add-host",
|
|
110
|
+
"host.docker.internal:host-gateway",
|
|
111
|
+
"-e",
|
|
112
|
+
"AHNLICH_AI_HOST=host.docker.internal",
|
|
113
|
+
"-e",
|
|
114
|
+
"AHNLICH_AI_PORT=1370",
|
|
115
|
+
"ghcr.io/deven96/ahnlich-mcp:latest",
|
|
116
|
+
"--profile",
|
|
117
|
+
"ai"
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Restart Claude Desktop after saving the configuration.
|
|
125
|
+
|
|
126
|
+
### Codex
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
codex mcp add ahnlich -- docker run --rm -i \
|
|
130
|
+
--add-host host.docker.internal:host-gateway \
|
|
131
|
+
-e AHNLICH_AI_HOST=host.docker.internal \
|
|
132
|
+
-e AHNLICH_AI_PORT=1370 \
|
|
133
|
+
ghcr.io/deven96/ahnlich-mcp:latest \
|
|
134
|
+
--profile ai
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Install from source
|
|
138
|
+
|
|
139
|
+
Use this method when developing or contributing to Ahnlich MCP.
|
|
140
|
+
|
|
141
|
+
Clone the repository and install the locked dependencies:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
git clone https://github.com/deven96/ahnlich.git
|
|
145
|
+
cd ahnlich/mcp
|
|
146
|
+
uv sync --locked --dev
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Verify the setup:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
uv run ahnlich-mcp doctor --profile ai
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The stdio command for MCP clients is:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
uv --directory /absolute/path/to/ahnlich/mcp run ahnlich-mcp --profile ai
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
For Claude Desktop:
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"mcpServers": {
|
|
166
|
+
"ahnlich": {
|
|
167
|
+
"command": "uv",
|
|
168
|
+
"args": [
|
|
169
|
+
"--directory",
|
|
170
|
+
"/absolute/path/to/ahnlich/mcp",
|
|
171
|
+
"run",
|
|
172
|
+
"ahnlich-mcp",
|
|
173
|
+
"--profile",
|
|
174
|
+
"ai"
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
For Codex:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
codex mcp add ahnlich -- \
|
|
185
|
+
uv --directory /absolute/path/to/ahnlich/mcp \
|
|
186
|
+
run ahnlich-mcp --profile ai
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Configuration
|
|
190
|
+
|
|
191
|
+
Command-line profile selection overrides `AHNLICH_PROFILE`.
|
|
192
|
+
|
|
193
|
+
| Variable | Default | Description |
|
|
194
|
+
|---|---:|---|
|
|
195
|
+
| `AHNLICH_PROFILE` | `ai` | Active profile: `ai` or `db` |
|
|
196
|
+
| `AHNLICH_DB_HOST` | `127.0.0.1` | Database host |
|
|
197
|
+
| `AHNLICH_DB_PORT` | `1369` | Database port |
|
|
198
|
+
| `AHNLICH_AI_HOST` | `127.0.0.1` | AI proxy host |
|
|
199
|
+
| `AHNLICH_AI_PORT` | `1370` | AI proxy port |
|
|
200
|
+
| `AHNLICH_AI_MODEL` | `all-minilm-l6-v2` | Model used by the AI profile |
|
|
201
|
+
| `AHNLICH_MCP_READ_ONLY` | `0` | Expose only non-modifying tools |
|
|
202
|
+
|
|
203
|
+
Supported AI models:
|
|
204
|
+
|
|
205
|
+
- `all-minilm-l6-v2`
|
|
206
|
+
- `all-minilm-l12-v2`
|
|
207
|
+
- `bge-base-en-v1.5`
|
|
208
|
+
- `bge-large-en-v1.5`
|
|
209
|
+
- `jina-embeddings-v2-base-code`
|
|
210
|
+
|
|
211
|
+
The selected model must also be enabled in `ahnlich-ai` through its
|
|
212
|
+
`--supported-models` option. The bundled Compose configuration enables
|
|
213
|
+
`all-minilm-l6-v2`.
|
|
214
|
+
|
|
215
|
+
The bundled Compose configuration uses Ahnlich DB `0.3.2` and Ahnlich AI
|
|
216
|
+
`0.4.1` by default. Override `AHNLICH_DB_VERSION` or
|
|
217
|
+
`AHNLICH_AI_VERSION` only when testing another compatible release.
|
|
218
|
+
|
|
219
|
+
Example:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
AHNLICH_PROFILE=db \
|
|
223
|
+
AHNLICH_DB_HOST=127.0.0.1 \
|
|
224
|
+
AHNLICH_DB_PORT=1369 \
|
|
225
|
+
uv run ahnlich-mcp
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Read-only mode
|
|
229
|
+
|
|
230
|
+
Enable strict read-only mode when the MCP client must not modify Ahnlich:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
AHNLICH_MCP_READ_ONLY=1 uv run ahnlich-mcp --profile ai
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
Only these tools are exposed:
|
|
237
|
+
|
|
238
|
+
- `ping`
|
|
239
|
+
- `server_info`
|
|
240
|
+
- `list_stores`
|
|
241
|
+
- `similarity_search`
|
|
242
|
+
- `get_by_metadata`
|
|
243
|
+
|
|
244
|
+
Mutating tools are omitted from the MCP tool registry.
|
|
245
|
+
|
|
246
|
+
## Tools
|
|
247
|
+
|
|
248
|
+
Both profiles expose the same tool names by default. Input schemas differ where embeddings are involved.
|
|
249
|
+
|
|
250
|
+
| Tool | Description |
|
|
251
|
+
|---|---|
|
|
252
|
+
| `ping` | Check the configured Ahnlich service |
|
|
253
|
+
| `server_info` | Get information about the configured service |
|
|
254
|
+
| `create_store` | Create a vector store |
|
|
255
|
+
| `list_stores` | List stores |
|
|
256
|
+
| `drop_store` | Delete a store and its entries |
|
|
257
|
+
| `store_entries` | Store raw text or precomputed embeddings |
|
|
258
|
+
| `similarity_search` | Search using raw text or a query embedding |
|
|
259
|
+
| `get_by_metadata` | Retrieve entries matching indexed metadata |
|
|
260
|
+
| `delete_by_metadata` | Delete entries matching indexed metadata |
|
|
261
|
+
| `create_predicate_index` | Index metadata keys |
|
|
262
|
+
| `drop_predicate_index` | Remove metadata indexes |
|
|
263
|
+
|
|
264
|
+
The `db` profile requires `dimension` when creating a store. Its `store_entries` and `similarity_search` tools accept embeddings.
|
|
265
|
+
|
|
266
|
+
The `ai` profile accepts raw text and uses the configured Ahnlich model to generate embeddings.
|
|
267
|
+
|
|
268
|
+
Metadata filters use the `metadata_filter` argument. Filtered metadata keys must have predicate indexes.
|
|
269
|
+
|
|
270
|
+
## Result controls
|
|
271
|
+
|
|
272
|
+
`list_stores` and `get_by_metadata` accept a `limit` between `1` and `1024`. The default is `50`.
|
|
273
|
+
|
|
274
|
+
They return a bounded response:
|
|
275
|
+
|
|
276
|
+
```json
|
|
277
|
+
{
|
|
278
|
+
"results": [],
|
|
279
|
+
"truncated": false
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
`similarity_search` accepts `top_k` up to `1024`.
|
|
284
|
+
|
|
285
|
+
Stored embeddings are omitted from DB search and metadata responses by default. Pass `include_embeddings: true` when the vectors are required.
|
|
286
|
+
|
|
287
|
+
## AI preprocessing
|
|
288
|
+
|
|
289
|
+
The AI profile supports the following preprocessing modes for `store_entries` and `similarity_search`:
|
|
290
|
+
|
|
291
|
+
| Value | Behaviour |
|
|
292
|
+
|---|---|
|
|
293
|
+
| `none` | Send input without model preprocessing |
|
|
294
|
+
| `truncate` | Allow Ahnlich to truncate input for the selected model |
|
|
295
|
+
|
|
296
|
+
The default is `none`.
|
|
297
|
+
|
|
298
|
+
## Development
|
|
299
|
+
|
|
300
|
+
Run unit tests:
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
uv run pytest tests/unit -v
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Run integration tests:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
docker compose up -d --wait
|
|
310
|
+
uv run pytest tests/integration -v
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Run the complete test suite:
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
uv run pytest -v
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Run MCP Inspector:
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
npx -y @modelcontextprotocol/inspector \
|
|
323
|
+
uv \
|
|
324
|
+
--directory "$(pwd)" \
|
|
325
|
+
run ahnlich-mcp \
|
|
326
|
+
--profile ai
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## License
|
|
330
|
+
|
|
331
|
+
MIT
|