pdbe-mcp-server 1.0.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.
- pdbe_mcp_server-1.0.0/.coverage +0 -0
- pdbe_mcp_server-1.0.0/.github/workflows/ci.yml +97 -0
- pdbe_mcp_server-1.0.0/.gitignore +10 -0
- pdbe_mcp_server-1.0.0/.nvmrc +1 -0
- pdbe_mcp_server-1.0.0/.pre-commit-config.yaml +31 -0
- pdbe_mcp_server-1.0.0/.python-version +1 -0
- pdbe_mcp_server-1.0.0/.vscode/settings.json +11 -0
- pdbe_mcp_server-1.0.0/CONTRIBUTING.md +21 -0
- pdbe_mcp_server-1.0.0/DEVELOPMENT.md +351 -0
- pdbe_mcp_server-1.0.0/LICENSE +201 -0
- pdbe_mcp_server-1.0.0/Makefile +69 -0
- pdbe_mcp_server-1.0.0/PKG-INFO +321 -0
- pdbe_mcp_server-1.0.0/README.md +302 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/__init__.py +16 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/api_tools.py +291 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/config.yaml +8 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/graph_tools.py +224 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/helper.py +45 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/py.typed +2 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/search_tools.py +141 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/server.py +196 -0
- pdbe_mcp_server-1.0.0/pdbe_mcp_server/utils.py +172 -0
- pdbe_mcp_server-1.0.0/pyproject.toml +89 -0
- pdbe_mcp_server-1.0.0/ruff.toml +81 -0
- pdbe_mcp_server-1.0.0/tests/__init__.py +1 -0
- pdbe_mcp_server-1.0.0/tests/conftest.py +165 -0
- pdbe_mcp_server-1.0.0/tests/test_api_tools.py +262 -0
- pdbe_mcp_server-1.0.0/tests/test_graph_tools.py +214 -0
- pdbe_mcp_server-1.0.0/tests/test_helper.py +154 -0
- pdbe_mcp_server-1.0.0/tests/test_search_tools.py +191 -0
- pdbe_mcp_server-1.0.0/tests/test_server.py +113 -0
- pdbe_mcp_server-1.0.0/tests/test_utils.py +258 -0
- pdbe_mcp_server-1.0.0/uv.lock +1267 -0
|
Binary file
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [ main, develop, search ]
|
|
6
|
+
tags: [ 'v*' ]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [ main, develop ]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
test:
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
strategy:
|
|
14
|
+
matrix:
|
|
15
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
|
+
python-version: ['3.10', '3.11', '3.12']
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
- name: Install uv
|
|
22
|
+
uses: astral-sh/setup-uv@v3
|
|
23
|
+
with:
|
|
24
|
+
version: "latest"
|
|
25
|
+
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
run: uv python install ${{ matrix.python-version }}
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: |
|
|
31
|
+
uv sync --all-extras --dev
|
|
32
|
+
|
|
33
|
+
- name: Run ruff linter
|
|
34
|
+
run: uv run ruff check .
|
|
35
|
+
|
|
36
|
+
- name: Run ruff formatter
|
|
37
|
+
run: uv run ruff format --check .
|
|
38
|
+
|
|
39
|
+
- name: Run type checker
|
|
40
|
+
run: uv run pyright
|
|
41
|
+
|
|
42
|
+
- name: Run tests with coverage
|
|
43
|
+
run: |
|
|
44
|
+
uv run pytest --cov=pdbe_mcp_server --cov-report=xml --cov-report=term
|
|
45
|
+
|
|
46
|
+
- name: Upload coverage to Codecov
|
|
47
|
+
uses: codecov/codecov-action@v4
|
|
48
|
+
with:
|
|
49
|
+
file: ./coverage.xml
|
|
50
|
+
flags: unittests
|
|
51
|
+
name: codecov-umbrella
|
|
52
|
+
fail_ci_if_error: false
|
|
53
|
+
|
|
54
|
+
build:
|
|
55
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
needs: test
|
|
58
|
+
|
|
59
|
+
steps:
|
|
60
|
+
- uses: actions/checkout@v4
|
|
61
|
+
|
|
62
|
+
- name: Install uv
|
|
63
|
+
uses: astral-sh/setup-uv@v3
|
|
64
|
+
|
|
65
|
+
- name: Build package
|
|
66
|
+
run: uv build
|
|
67
|
+
|
|
68
|
+
- name: Check package
|
|
69
|
+
run: |
|
|
70
|
+
uv run twine check dist/*
|
|
71
|
+
|
|
72
|
+
- name: Upload artifacts
|
|
73
|
+
uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: dist
|
|
76
|
+
path: dist/
|
|
77
|
+
|
|
78
|
+
publish:
|
|
79
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/')
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
needs: build
|
|
82
|
+
environment: release
|
|
83
|
+
permissions:
|
|
84
|
+
id-token: write
|
|
85
|
+
|
|
86
|
+
steps:
|
|
87
|
+
- name: Download artifacts
|
|
88
|
+
uses: actions/download-artifact@v4
|
|
89
|
+
with:
|
|
90
|
+
name: dist
|
|
91
|
+
path: dist/
|
|
92
|
+
|
|
93
|
+
- name: Publish package
|
|
94
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
95
|
+
with:
|
|
96
|
+
user: ${{ secrets.PYPI_USERNAME }}
|
|
97
|
+
password: ${{ secrets.PYPI_PASSWORD }}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v20.10.0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v4.5.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: check-yaml
|
|
6
|
+
- id: check-added-large-files
|
|
7
|
+
- id: check-case-conflict
|
|
8
|
+
- id: check-docstring-first
|
|
9
|
+
- id: detect-private-key
|
|
10
|
+
- id: trailing-whitespace
|
|
11
|
+
- id: fix-byte-order-marker
|
|
12
|
+
- id: end-of-file-fixer
|
|
13
|
+
# args: ["--maxkb=3000"]
|
|
14
|
+
- id: check-ast
|
|
15
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
16
|
+
rev: v0.3.5 # Ruff version.
|
|
17
|
+
hooks:
|
|
18
|
+
- id: ruff
|
|
19
|
+
args: [--fix]
|
|
20
|
+
- id: ruff-format
|
|
21
|
+
- repo: https://github.com/dzhu/rstfmt
|
|
22
|
+
rev: v0.0.14
|
|
23
|
+
hooks:
|
|
24
|
+
- id: rstfmt
|
|
25
|
+
name: rST Formatter
|
|
26
|
+
- repo: https://github.com/pycqa/isort
|
|
27
|
+
rev: 5.12.0
|
|
28
|
+
hooks:
|
|
29
|
+
- id: isort
|
|
30
|
+
name: isort (python)
|
|
31
|
+
args: ["--profile", "black"]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Contributing to PDBe MCP Server
|
|
2
|
+
|
|
3
|
+
Thank you for your interest in contributing to the PDBe MCP Server project!
|
|
4
|
+
|
|
5
|
+
## How to Contribute
|
|
6
|
+
|
|
7
|
+
- Fork the repository and create your branch from `main`.
|
|
8
|
+
- Make your changes with clear commit messages.
|
|
9
|
+
- Ensure your code follows the style and type hints used in the project.
|
|
10
|
+
- Add or update documentation and tests as needed.
|
|
11
|
+
- Open a pull request describing your changes.
|
|
12
|
+
|
|
13
|
+
## Code of Conduct
|
|
14
|
+
|
|
15
|
+
Please be respectful and considerate in your communications and contributions.
|
|
16
|
+
|
|
17
|
+
## Initial Work
|
|
18
|
+
|
|
19
|
+
This project was initially developed by:
|
|
20
|
+
|
|
21
|
+
**Sreenath Sasidharan Nair** (<sreenath@ebi.ac.uk>)
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Development Guide
|
|
2
|
+
|
|
3
|
+
This guide is for developers working on the PDBe MCP Servers project.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
- [Setup](#setup)
|
|
7
|
+
- [Development Workflow](#development-workflow)
|
|
8
|
+
- [Testing](#testing)
|
|
9
|
+
- [Code Quality](#code-quality)
|
|
10
|
+
- [Building and Distribution](#building-and-distribution)
|
|
11
|
+
- [Architecture](#architecture)
|
|
12
|
+
|
|
13
|
+
## Setup
|
|
14
|
+
|
|
15
|
+
### Prerequisites
|
|
16
|
+
- Python 3.10 or higher
|
|
17
|
+
- [uv](https://github.com/astral-sh/uv) package manager
|
|
18
|
+
|
|
19
|
+
### Installation
|
|
20
|
+
|
|
21
|
+
1. Clone the repository:
|
|
22
|
+
```bash
|
|
23
|
+
git clone https://github.com/PDBeurope/PDBe-MCP-Servers.git
|
|
24
|
+
cd PDBe-MCP-Servers
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
2. Set up development environment:
|
|
28
|
+
```bash
|
|
29
|
+
make dev-setup
|
|
30
|
+
# Or manually:
|
|
31
|
+
uv sync --all-extras --dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Development Workflow
|
|
35
|
+
|
|
36
|
+
### Quick Commands
|
|
37
|
+
|
|
38
|
+
The project includes a Makefile for common tasks:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
make help # Show all available commands
|
|
42
|
+
make install # Install dependencies
|
|
43
|
+
make test # Run tests with coverage
|
|
44
|
+
make lint # Check code style
|
|
45
|
+
make format # Format code
|
|
46
|
+
make typecheck # Run type checker
|
|
47
|
+
make all # Run all checks (lint, format, type, test)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Manual Commands
|
|
51
|
+
|
|
52
|
+
If you prefer not to use Make:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Install dependencies
|
|
56
|
+
uv sync --dev
|
|
57
|
+
|
|
58
|
+
# Run tests
|
|
59
|
+
uv run pytest
|
|
60
|
+
|
|
61
|
+
# Run linter
|
|
62
|
+
uv run ruff check .
|
|
63
|
+
|
|
64
|
+
# Format code
|
|
65
|
+
uv run ruff format .
|
|
66
|
+
|
|
67
|
+
# Type checking
|
|
68
|
+
uv run pyright
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Testing
|
|
72
|
+
|
|
73
|
+
### Running Tests
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# All tests with coverage
|
|
77
|
+
make test
|
|
78
|
+
|
|
79
|
+
# Fast tests (no coverage)
|
|
80
|
+
make test-fast
|
|
81
|
+
|
|
82
|
+
# Specific test file
|
|
83
|
+
uv run pytest tests/test_utils.py
|
|
84
|
+
|
|
85
|
+
# Specific test class
|
|
86
|
+
uv run pytest tests/test_utils.py::TestHTMLStripper
|
|
87
|
+
|
|
88
|
+
# Specific test
|
|
89
|
+
uv run pytest tests/test_utils.py::TestHTMLStripper::test_strip_simple_tags
|
|
90
|
+
|
|
91
|
+
# With verbose output
|
|
92
|
+
uv run pytest -v
|
|
93
|
+
|
|
94
|
+
# Stop on first failure
|
|
95
|
+
uv run pytest -x
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Writing Tests
|
|
99
|
+
|
|
100
|
+
- Place tests in the `tests/` directory
|
|
101
|
+
- Name test files `test_*.py`
|
|
102
|
+
- Name test classes `Test*`
|
|
103
|
+
- Name test functions `test_*`
|
|
104
|
+
- Use fixtures from `conftest.py`
|
|
105
|
+
- Mock all external HTTP calls
|
|
106
|
+
|
|
107
|
+
Example test:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from unittest.mock import MagicMock, patch
|
|
111
|
+
|
|
112
|
+
def test_example():
|
|
113
|
+
"""Test description."""
|
|
114
|
+
# Arrange
|
|
115
|
+
mock_data = {"key": "value"}
|
|
116
|
+
|
|
117
|
+
# Act
|
|
118
|
+
result = function_under_test(mock_data)
|
|
119
|
+
|
|
120
|
+
# Assert
|
|
121
|
+
assert result == expected_value
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Test Coverage
|
|
125
|
+
|
|
126
|
+
View coverage report:
|
|
127
|
+
```bash
|
|
128
|
+
make test
|
|
129
|
+
# Open htmlcov/index.html in browser
|
|
130
|
+
open htmlcov/index.html
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Target: >80% coverage
|
|
134
|
+
|
|
135
|
+
## Code Quality
|
|
136
|
+
|
|
137
|
+
### Linting
|
|
138
|
+
|
|
139
|
+
The project uses Ruff for linting:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Check for issues
|
|
143
|
+
make lint
|
|
144
|
+
|
|
145
|
+
# Fix auto-fixable issues
|
|
146
|
+
make lint-fix
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Formatting
|
|
150
|
+
|
|
151
|
+
The project uses Ruff for formatting:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Format code
|
|
155
|
+
make format
|
|
156
|
+
|
|
157
|
+
# Check formatting without changing files
|
|
158
|
+
make format-check
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Type Checking
|
|
162
|
+
|
|
163
|
+
The project uses Pyright for type checking:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Run type checker
|
|
167
|
+
make typecheck
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
All public APIs must have type annotations.
|
|
171
|
+
|
|
172
|
+
### Pre-commit Checks
|
|
173
|
+
|
|
174
|
+
Before committing, run:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
make all
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
This runs linting, formatting checks, type checking, and tests.
|
|
181
|
+
|
|
182
|
+
## Building and Distribution
|
|
183
|
+
|
|
184
|
+
### Building the Package
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
# Build wheel and sdist
|
|
188
|
+
make build
|
|
189
|
+
|
|
190
|
+
# Check distribution files
|
|
191
|
+
make check-dist
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Publishing
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
# Test on TestPyPI first
|
|
198
|
+
make publish-test
|
|
199
|
+
|
|
200
|
+
# Publish to PyPI
|
|
201
|
+
make publish
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Architecture
|
|
205
|
+
|
|
206
|
+
### Project Structure
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
pdbe_mcp_server/
|
|
210
|
+
├── __init__.py # Configuration management
|
|
211
|
+
├── api_tools.py # OpenAPI to MCP tool conversion
|
|
212
|
+
├── config.yaml # Configuration file
|
|
213
|
+
├── graph_tools.py # Graph database tools
|
|
214
|
+
├── helper.py # Helper utilities
|
|
215
|
+
├── py.typed # PEP 561 marker
|
|
216
|
+
├── search_tools.py # Search tools
|
|
217
|
+
├── server.py # Server orchestration
|
|
218
|
+
└── utils.py # Shared utilities
|
|
219
|
+
|
|
220
|
+
tests/
|
|
221
|
+
├── conftest.py # Shared fixtures
|
|
222
|
+
├── test_api_tools.py # API tools tests
|
|
223
|
+
├── test_graph_tools.py # Graph tools tests
|
|
224
|
+
├── test_search_tools.py # Search tools tests
|
|
225
|
+
├── test_server.py # Server tests
|
|
226
|
+
└── test_utils.py # Utils tests
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Key Design Patterns
|
|
230
|
+
|
|
231
|
+
1. **Factory Pattern**: `MCPServerFactory` for creating servers
|
|
232
|
+
2. **Strategy Pattern**: Dynamic OpenAPI tool generation
|
|
233
|
+
3. **Adapter Pattern**: `HTTPClient` wrapper
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
### Adding a New Server Type
|
|
237
|
+
|
|
238
|
+
1. Create a builder function:
|
|
239
|
+
```python
|
|
240
|
+
def build_my_server() -> Server:
|
|
241
|
+
server = Server("my-server")
|
|
242
|
+
|
|
243
|
+
@server.list_tools()
|
|
244
|
+
async def list_tools() -> list[types.Tool]:
|
|
245
|
+
return [...]
|
|
246
|
+
|
|
247
|
+
@server.call_tool()
|
|
248
|
+
async def call_tool(name: str, arguments: dict[str, Any]) -> Sequence[...]:
|
|
249
|
+
# Implementation
|
|
250
|
+
pass
|
|
251
|
+
|
|
252
|
+
return server
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
2. Register with factory:
|
|
256
|
+
```python
|
|
257
|
+
factory.register("my_server", build_my_server)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
3. Update CLI options in `main()`.
|
|
261
|
+
|
|
262
|
+
### Adding Tests
|
|
263
|
+
|
|
264
|
+
1. Create test file in `tests/`
|
|
265
|
+
2. Add fixtures to `conftest.py` if reusable
|
|
266
|
+
3. Mock external dependencies
|
|
267
|
+
4. Test happy path and error cases
|
|
268
|
+
|
|
269
|
+
## Best Practices
|
|
270
|
+
|
|
271
|
+
### Code Style
|
|
272
|
+
|
|
273
|
+
- Use type hints for all public APIs
|
|
274
|
+
- Write docstrings for all public functions
|
|
275
|
+
- Use descriptive variable names
|
|
276
|
+
- Keep functions focused and small
|
|
277
|
+
- Prefer composition over inheritance
|
|
278
|
+
|
|
279
|
+
### Git Workflow
|
|
280
|
+
|
|
281
|
+
1. Create a feature branch
|
|
282
|
+
2. Make your changes
|
|
283
|
+
3. Run `make all` to check everything
|
|
284
|
+
4. Commit with descriptive message
|
|
285
|
+
5. Push and create pull request
|
|
286
|
+
|
|
287
|
+
### Commit Messages
|
|
288
|
+
|
|
289
|
+
Follow conventional commits:
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
feat: add new search filter option
|
|
293
|
+
fix: handle empty search results correctly
|
|
294
|
+
docs: update architecture documentation
|
|
295
|
+
test: add tests for graph tools
|
|
296
|
+
refactor: simplify server factory logic
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Troubleshooting
|
|
300
|
+
|
|
301
|
+
### Tests Failing
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
# Run with verbose output
|
|
305
|
+
uv run pytest -v
|
|
306
|
+
|
|
307
|
+
# Run single test to isolate issue
|
|
308
|
+
uv run pytest tests/test_utils.py::TestHTMLStripper::test_strip_simple_tags -v
|
|
309
|
+
|
|
310
|
+
# Check test isolation
|
|
311
|
+
uv run pytest --lf # Run last failed
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Type Errors
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Run type checker with verbose output
|
|
318
|
+
uv run pyright --verbose
|
|
319
|
+
|
|
320
|
+
# Check specific file
|
|
321
|
+
uv run pyright pdbe_mcp_server/server.py
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Import Errors
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
# Reinstall dependencies
|
|
328
|
+
uv sync --reinstall
|
|
329
|
+
|
|
330
|
+
# Check installed packages
|
|
331
|
+
uv pip list
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## Resources
|
|
335
|
+
|
|
336
|
+
- [Project README](README.md)
|
|
337
|
+
- [MCP Documentation](https://modelcontextprotocol.io/)
|
|
338
|
+
- [PDBe API](https://www.ebi.ac.uk/pdbe/api/)
|
|
339
|
+
|
|
340
|
+
## Contributing
|
|
341
|
+
|
|
342
|
+
1. Check existing issues/PRs
|
|
343
|
+
2. Create an issue for discussion (for large changes)
|
|
344
|
+
3. Fork and create a feature branch
|
|
345
|
+
4. Make your changes with tests
|
|
346
|
+
5. Ensure `make all` passes
|
|
347
|
+
6. Submit a pull request
|
|
348
|
+
|
|
349
|
+
## License
|
|
350
|
+
|
|
351
|
+
Apache-2.0 - See LICENSE file for details.
|