jaraco-website-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.
- jaraco_website_mcp_server-1.0.0/PKG-INFO +442 -0
- jaraco_website_mcp_server-1.0.0/README.md +408 -0
- jaraco_website_mcp_server-1.0.0/jaraco_website_mcp_server.egg-info/PKG-INFO +442 -0
- jaraco_website_mcp_server-1.0.0/jaraco_website_mcp_server.egg-info/SOURCES.txt +10 -0
- jaraco_website_mcp_server-1.0.0/jaraco_website_mcp_server.egg-info/dependency_links.txt +1 -0
- jaraco_website_mcp_server-1.0.0/jaraco_website_mcp_server.egg-info/requires.txt +9 -0
- jaraco_website_mcp_server-1.0.0/jaraco_website_mcp_server.egg-info/top_level.txt +1 -0
- jaraco_website_mcp_server-1.0.0/pyproject.toml +69 -0
- jaraco_website_mcp_server-1.0.0/setup.cfg +4 -0
- jaraco_website_mcp_server-1.0.0/tests/test_content_loader.py +131 -0
- jaraco_website_mcp_server-1.0.0/tests/test_email_templates.py +141 -0
- jaraco_website_mcp_server-1.0.0/tests/test_server.py +289 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: jaraco-website-mcp-server
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: MCP Server for Jaraco GmbH website - provides programmatic access to blog posts, services, and categories
|
|
5
|
+
Author-email: Jaraco GmbH <info@jaraco.de>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://jarakube.eu/mcp-server/mcp-server.html
|
|
8
|
+
Project-URL: Documentation, https://jarakube.eu/mcp-server/mcp-server.html
|
|
9
|
+
Project-URL: Repository, https://github.com/jaracogmbh/jarakube-jaraco-app/tree/develop/jarasite-website/mcp_server
|
|
10
|
+
Project-URL: Issues, https://github.com/jaracogmbh/jarakube-jaraco-app/issues
|
|
11
|
+
Keywords: mcp,model-context-protocol,jaraco,website,api
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
23
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: mcp>=2.2.0
|
|
27
|
+
Requires-Dist: fastmcp>=4.0.0
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
|
|
31
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.4; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
34
|
+
|
|
35
|
+
<!-- mcp-name: io.github.jaracogmbh/jaraco-website -->
|
|
36
|
+
|
|
37
|
+
# Jaraco Website MCP Server
|
|
38
|
+
|
|
39
|
+
This directory contains the MCP (Model Context Protocol) server implementation for the Jaraco website. The server provides programmatic access to website content including blog posts, services, and categories, with read-only access and email drafting capabilities.
|
|
40
|
+
|
|
41
|
+
## Features
|
|
42
|
+
|
|
43
|
+
- **Read Blog Posts**: Access all blog posts in multiple languages (EN, DE, FR, ES, NL)
|
|
44
|
+
- **Read Services**: Access all service descriptions and details
|
|
45
|
+
- **Browse Categories**: Explore content organized by categories
|
|
46
|
+
- **Draft Emails**: Generate service-specific email templates with appropriate default text
|
|
47
|
+
- **Read-Only Access**: All content access is read-only
|
|
48
|
+
- **Multi-Language Support**: All content available in 5 languages
|
|
49
|
+
|
|
50
|
+
## Quick Start
|
|
51
|
+
|
|
52
|
+
### Prerequisites
|
|
53
|
+
|
|
54
|
+
- Python 3.10 or higher (required for MCP SDK v2)
|
|
55
|
+
- pip package manager
|
|
56
|
+
|
|
57
|
+
### Installation
|
|
58
|
+
|
|
59
|
+
1. Install dependencies:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pip install -r requirements.txt
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
2. Run the server:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python -m mcp_server.server
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The server will start on `localhost:8081` by default with the `/mcp` endpoint.
|
|
72
|
+
|
|
73
|
+
### Test the Server
|
|
74
|
+
|
|
75
|
+
You can test the server using curl or any MCP client:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# List all resources
|
|
79
|
+
curl http://localhost:8081/mcp -X POST -H "Content-Type: application/json" -d '{"method": "list_resources"}'
|
|
80
|
+
|
|
81
|
+
# Read a specific blog post
|
|
82
|
+
curl http://localhost:8081/mcp -X POST -H "Content-Type: application/json" -d '{"method": "read_resource", "params": {"uri": "blog_posts/from-data-chaos-to-efficient-automation"}}'
|
|
83
|
+
|
|
84
|
+
# Or use the MCP CLI (if installed)
|
|
85
|
+
mcp dev mcp_server.server
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Configuration
|
|
89
|
+
|
|
90
|
+
The server can be configured using environment variables. In MCP SDK v2, transport settings are passed to the `run()` method, but can still be configured via environment variables for convenience.
|
|
91
|
+
|
|
92
|
+
| Variable | Default | Description |
|
|
93
|
+
|----------|---------|-------------|
|
|
94
|
+
| `MCP_HOST` | `0.0.0.0` | Host to bind to (used by run()) |
|
|
95
|
+
| `MCP_PORT` | `8081` | Port to listen on (used by run()) |
|
|
96
|
+
| `CONTENT_ROOT` | Project root | Root directory for website content |
|
|
97
|
+
| `CACHE_ENABLED` | `true` | Enable content caching |
|
|
98
|
+
| `CACHE_TTL` | `300` | Cache time-to-live in seconds |
|
|
99
|
+
| `LOG_LEVEL` | `INFO` | Logging level (DEBUG, INFO, WARNING, ERROR) |
|
|
100
|
+
|
|
101
|
+
Example:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Configure via environment variables
|
|
105
|
+
MCP_PORT=9090 CONTENT_ROOT=/path/to/content LOG_LEVEL=DEBUG python -m mcp_server.server
|
|
106
|
+
|
|
107
|
+
# Or use default configuration
|
|
108
|
+
python -m mcp_server.server
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Transport Configuration
|
|
112
|
+
|
|
113
|
+
The server uses **Streamable HTTP transport** by default, which is the recommended transport for MCP v2. The endpoint will be available at:
|
|
114
|
+
- `http://localhost:8081/mcp`
|
|
115
|
+
|
|
116
|
+
For production deployments behind a proxy, you may need to configure transport security settings.
|
|
117
|
+
|
|
118
|
+
## Docker
|
|
119
|
+
|
|
120
|
+
### Build the Image
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
docker build -t jaraco-mcp-server -f mcp_server/Dockerfile .
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Run the Container
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
docker run -p 8081:8081 -v $(pwd):/app jaraco-mcp-server
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Docker Compose
|
|
133
|
+
|
|
134
|
+
Add to your `docker-compose.yml`:
|
|
135
|
+
|
|
136
|
+
```yaml
|
|
137
|
+
version: '3.8'
|
|
138
|
+
|
|
139
|
+
services:
|
|
140
|
+
mcp-server:
|
|
141
|
+
build:
|
|
142
|
+
context: .
|
|
143
|
+
dockerfile: mcp_server/Dockerfile
|
|
144
|
+
ports:
|
|
145
|
+
- "8081:8081"
|
|
146
|
+
volumes:
|
|
147
|
+
- .:/app
|
|
148
|
+
environment:
|
|
149
|
+
- MCP_PORT=8081
|
|
150
|
+
- CONTENT_ROOT=/app
|
|
151
|
+
- LOG_LEVEL=INFO
|
|
152
|
+
restart: unless-stopped
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Usage Examples
|
|
156
|
+
|
|
157
|
+
### Python Client
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from mcp.client import Client
|
|
161
|
+
|
|
162
|
+
async def main():
|
|
163
|
+
client = Client("jaraco-website", url="http://localhost:8081")
|
|
164
|
+
await client.connect()
|
|
165
|
+
|
|
166
|
+
# List all resources
|
|
167
|
+
resources = await client.list_resources()
|
|
168
|
+
print(f"Found {len(resources)} resources")
|
|
169
|
+
|
|
170
|
+
# Read a blog post
|
|
171
|
+
post = await client.read_resource("blog_posts/from-data-chaos-to-efficient-automation")
|
|
172
|
+
print(post)
|
|
173
|
+
|
|
174
|
+
# Draft an email
|
|
175
|
+
email = await client.call_tool(
|
|
176
|
+
"draft_email",
|
|
177
|
+
{
|
|
178
|
+
"service_slug": "software-development",
|
|
179
|
+
"language": "en",
|
|
180
|
+
"sender_name": "John Doe",
|
|
181
|
+
"sender_email": "john@example.com",
|
|
182
|
+
"custom_text": "I need help with a custom web application."
|
|
183
|
+
}
|
|
184
|
+
)
|
|
185
|
+
print(email)
|
|
186
|
+
|
|
187
|
+
await client.disconnect()
|
|
188
|
+
|
|
189
|
+
# Run with asyncio
|
|
190
|
+
import asyncio
|
|
191
|
+
asyncio.run(main())
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### JavaScript/Node.js Client
|
|
195
|
+
|
|
196
|
+
```javascript
|
|
197
|
+
const { Client } = require('@modelcontextprotocol/sdk');
|
|
198
|
+
|
|
199
|
+
async function main() {
|
|
200
|
+
const client = new Client('jaraco-website', { url: 'http://localhost:8081' });
|
|
201
|
+
await client.connect();
|
|
202
|
+
|
|
203
|
+
// List resources
|
|
204
|
+
const resources = await client.listResources();
|
|
205
|
+
console.log(`Found ${resources.length} resources`);
|
|
206
|
+
|
|
207
|
+
// Read a resource
|
|
208
|
+
const post = await client.readResource('blog_posts/from-data-chaos-to-efficient-automation');
|
|
209
|
+
console.log(post);
|
|
210
|
+
|
|
211
|
+
// Draft an email
|
|
212
|
+
const email = await client.callTool('draft_email', {
|
|
213
|
+
service_slug: 'software-development',
|
|
214
|
+
language: 'en',
|
|
215
|
+
sender_name: 'John Doe',
|
|
216
|
+
sender_email: 'john@example.com',
|
|
217
|
+
custom_text: 'I need help with a custom web application.'
|
|
218
|
+
});
|
|
219
|
+
console.log(email);
|
|
220
|
+
|
|
221
|
+
await client.disconnect();
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
main().catch(console.error);
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## API Reference
|
|
228
|
+
|
|
229
|
+
The MCP server uses the **Streamable HTTP transport** with the following endpoint:
|
|
230
|
+
- **Base URL**: `http://localhost:8081/mcp`
|
|
231
|
+
- **Transport**: Streamable HTTP (MCP v2 recommended)
|
|
232
|
+
|
|
233
|
+
### MCP Protocol
|
|
234
|
+
|
|
235
|
+
This server implements the MCP (Model Context Protocol) v2 specification. Clients should use an MCP client library for their language.
|
|
236
|
+
|
|
237
|
+
### list_resources
|
|
238
|
+
|
|
239
|
+
List all available resources or filter by type.
|
|
240
|
+
|
|
241
|
+
**MCP Request**:
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"method": "list_resources",
|
|
245
|
+
"params": {
|
|
246
|
+
"uri": "blog_posts/"
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
**MCP Response**:
|
|
252
|
+
```json
|
|
253
|
+
{
|
|
254
|
+
"resources": [
|
|
255
|
+
{
|
|
256
|
+
"uri": "blog_posts/from-data-chaos-to-efficient-automation",
|
|
257
|
+
"name": "From Data Chaos to Efficient Automation",
|
|
258
|
+
"description": "How to transform...",
|
|
259
|
+
"mimeType": "text/markdown"
|
|
260
|
+
}
|
|
261
|
+
]
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### read_resource
|
|
266
|
+
|
|
267
|
+
Read a specific resource by URI.
|
|
268
|
+
|
|
269
|
+
**MCP Request**:
|
|
270
|
+
```json
|
|
271
|
+
{
|
|
272
|
+
"method": "read_resource",
|
|
273
|
+
"params": {
|
|
274
|
+
"uri": "blog_posts/from-data-chaos-to-efficient-automation"
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**MCP Response**:
|
|
280
|
+
```json
|
|
281
|
+
{
|
|
282
|
+
"contents": [
|
|
283
|
+
{
|
|
284
|
+
"type": "text",
|
|
285
|
+
"text": "# From Data Chaos to Efficient Automation\n\n...",
|
|
286
|
+
"mimeType": "text/markdown"
|
|
287
|
+
}
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### call_tool (draft_email)
|
|
293
|
+
|
|
294
|
+
Draft an email for a service.
|
|
295
|
+
|
|
296
|
+
**MCP Request**:
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"method": "call_tool",
|
|
300
|
+
"params": {
|
|
301
|
+
"name": "draft_email",
|
|
302
|
+
"arguments": {
|
|
303
|
+
"service_slug": "software-development",
|
|
304
|
+
"language": "en",
|
|
305
|
+
"sender_name": "John Doe",
|
|
306
|
+
"sender_email": "john@example.com",
|
|
307
|
+
"custom_text": "I need help with..."
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
**MCP Response**:
|
|
314
|
+
```json
|
|
315
|
+
{
|
|
316
|
+
"content": [
|
|
317
|
+
{
|
|
318
|
+
"type": "text",
|
|
319
|
+
"text": "{\"subject\": \"Inquiry: Software Development Services\", \"body\": \"Dear Jaraco Team...\", ...}",
|
|
320
|
+
"mimeType": "application/json"
|
|
321
|
+
}
|
|
322
|
+
],
|
|
323
|
+
"isError": false
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Using MCP CLI
|
|
328
|
+
|
|
329
|
+
If you have the MCP CLI installed, you can test the server directly:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
# Install MCP CLI
|
|
333
|
+
pip install "mcp[cli]>=2.2.0,<3"
|
|
334
|
+
|
|
335
|
+
# Run the server in dev mode
|
|
336
|
+
mcp dev mcp_server.server
|
|
337
|
+
|
|
338
|
+
# Or run and connect
|
|
339
|
+
mcp run mcp_server.server
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
The MCP CLI will automatically use the correct protocol and transport settings.
|
|
343
|
+
|
|
344
|
+
## Available Services
|
|
345
|
+
|
|
346
|
+
The following services are available through the MCP server:
|
|
347
|
+
|
|
348
|
+
| Service Slug | Description |
|
|
349
|
+
|--------------|-------------|
|
|
350
|
+
| `software-development` | Custom software development services |
|
|
351
|
+
| `consulting` | IT consulting and advisory services |
|
|
352
|
+
| `it-architecture` | IT architecture design and review |
|
|
353
|
+
| `linux-consulting` | Linux system consulting |
|
|
354
|
+
| `code-review` | Code review and quality assessment |
|
|
355
|
+
| `technology-assessment` | Technology stack evaluation |
|
|
356
|
+
|
|
357
|
+
## Available Categories
|
|
358
|
+
|
|
359
|
+
Content is organized into the following categories:
|
|
360
|
+
|
|
361
|
+
| Category Slug | Description |
|
|
362
|
+
|---------------|-------------|
|
|
363
|
+
| `software-engineering` | Software development and engineering |
|
|
364
|
+
| `consulting` | Consulting services |
|
|
365
|
+
| `linux` | Linux and infrastructure services |
|
|
366
|
+
| `automation` | Automation and workflow improvement |
|
|
367
|
+
|
|
368
|
+
## Project Structure
|
|
369
|
+
|
|
370
|
+
```
|
|
371
|
+
mcp_server/
|
|
372
|
+
├── __init__.py # Package initialization
|
|
373
|
+
├── server.py # Main MCP server implementation
|
|
374
|
+
├── content_loader.py # Content loading and caching
|
|
375
|
+
├── email_templates.py # Email template definitions
|
|
376
|
+
├── config.py # Server configuration
|
|
377
|
+
├── requirements.txt # Python dependencies
|
|
378
|
+
├── Dockerfile # Docker configuration
|
|
379
|
+
└── README.md # This file
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## Development
|
|
383
|
+
|
|
384
|
+
### Running Tests
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
# Install test dependencies
|
|
388
|
+
pip install pytest pytest-asyncio
|
|
389
|
+
|
|
390
|
+
# Run tests
|
|
391
|
+
pytest tests/test_mcp_server.py -v
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
### Code Style
|
|
395
|
+
|
|
396
|
+
This project follows PEP 8 style guidelines. Use `black` and `isort` for formatting:
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
pip install black isort
|
|
400
|
+
black mcp_server/
|
|
401
|
+
isort mcp_server/
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## Security
|
|
405
|
+
|
|
406
|
+
- The MCP server provides **read-only access** to content
|
|
407
|
+
- No authentication is required by default (can be added if needed)
|
|
408
|
+
- All inputs are validated before processing
|
|
409
|
+
- Rate limiting is configured to prevent abuse
|
|
410
|
+
- The server runs as a non-root user in Docker
|
|
411
|
+
|
|
412
|
+
## Troubleshooting
|
|
413
|
+
|
|
414
|
+
### Common Issues
|
|
415
|
+
|
|
416
|
+
1. **Content not found**: Ensure `CONTENT_ROOT` points to the correct directory
|
|
417
|
+
2. **Connection refused**: Check that the server is running and the port is correct
|
|
418
|
+
3. **Rate limiting**: Reduce request frequency if you hit rate limits
|
|
419
|
+
|
|
420
|
+
### Debug Mode
|
|
421
|
+
|
|
422
|
+
Enable debug logging for troubleshooting:
|
|
423
|
+
|
|
424
|
+
```bash
|
|
425
|
+
LOG_LEVEL=DEBUG python -m mcp_server.server
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## License
|
|
429
|
+
|
|
430
|
+
This MCP server is part of the Jaraco website and is licensed under the same terms as the main project.
|
|
431
|
+
|
|
432
|
+
## Support
|
|
433
|
+
|
|
434
|
+
For questions or issues:
|
|
435
|
+
|
|
436
|
+
- **Email**: info@jaraco.de
|
|
437
|
+
- **Website**: https://jaraco-gmbh.de
|
|
438
|
+
- **GitHub**: https://github.com/jaracogmbh/jaraco-website
|
|
439
|
+
|
|
440
|
+
## Version History
|
|
441
|
+
|
|
442
|
+
- **1.0.0**: Initial release with blog posts, services, categories, and email drafting
|