globkurier-api-mcp 0.2.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.
Files changed (70) hide show
  1. globkurier_api_mcp-0.2.0/PKG-INFO +96 -0
  2. globkurier_api_mcp-0.2.0/README.md +71 -0
  3. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/PKG-INFO +96 -0
  4. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/SOURCES.txt +68 -0
  5. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/dependency_links.txt +1 -0
  6. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/entry_points.txt +2 -0
  7. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/requires.txt +5 -0
  8. globkurier_api_mcp-0.2.0/globkurier_api_mcp.egg-info/top_level.txt +1 -0
  9. globkurier_api_mcp-0.2.0/globkurier_mcp/__init__.py +16 -0
  10. globkurier_api_mcp-0.2.0/globkurier_mcp/__main__.py +6 -0
  11. globkurier_api_mcp-0.2.0/globkurier_mcp/application/__init__.py +1 -0
  12. globkurier_api_mcp-0.2.0/globkurier_mcp/application/bus/__init__.py +3 -0
  13. globkurier_api_mcp-0.2.0/globkurier_mcp/application/bus/dispatcher.py +112 -0
  14. globkurier_api_mcp-0.2.0/globkurier_mcp/application/commands/__init__.py +2 -0
  15. globkurier_api_mcp-0.2.0/globkurier_mcp/application/dto/__init__.py +3 -0
  16. globkurier_api_mcp-0.2.0/globkurier_mcp/application/dto/countries_dto.py +26 -0
  17. globkurier_api_mcp-0.2.0/globkurier_mcp/application/dto/product_dto.py +138 -0
  18. globkurier_api_mcp-0.2.0/globkurier_mcp/application/dto/shipping_dto.py +65 -0
  19. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/__init__.py +6 -0
  20. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/get_countries.py +146 -0
  21. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/get_product_addons.py +172 -0
  22. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/get_prompts.py +103 -0
  23. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/get_search_url.py +89 -0
  24. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/get_shipment_status.py +109 -0
  25. globkurier_api_mcp-0.2.0/globkurier_mcp/application/queries/search_products.py +190 -0
  26. globkurier_api_mcp-0.2.0/globkurier_mcp/config/__init__.py +3 -0
  27. globkurier_api_mcp-0.2.0/globkurier_mcp/config/settings.py +49 -0
  28. globkurier_api_mcp-0.2.0/globkurier_mcp/core/__init__.py +1 -0
  29. globkurier_api_mcp-0.2.0/globkurier_mcp/core/countries/__init__.py +6 -0
  30. globkurier_api_mcp-0.2.0/globkurier_mcp/core/countries/models.py +31 -0
  31. globkurier_api_mcp-0.2.0/globkurier_mcp/core/countries/ports.py +30 -0
  32. globkurier_api_mcp-0.2.0/globkurier_mcp/core/products/__init__.py +21 -0
  33. globkurier_api_mcp-0.2.0/globkurier_mcp/core/products/models.py +296 -0
  34. globkurier_api_mcp-0.2.0/globkurier_mcp/core/products/ports.py +91 -0
  35. globkurier_api_mcp-0.2.0/globkurier_mcp/core/prompts/__init__.py +13 -0
  36. globkurier_api_mcp-0.2.0/globkurier_mcp/core/prompts/models.py +55 -0
  37. globkurier_api_mcp-0.2.0/globkurier_mcp/core/prompts/ports.py +42 -0
  38. globkurier_api_mcp-0.2.0/globkurier_mcp/core/shipping/__init__.py +17 -0
  39. globkurier_api_mcp-0.2.0/globkurier_mcp/core/shipping/models.py +99 -0
  40. globkurier_api_mcp-0.2.0/globkurier_mcp/core/shipping/ports.py +48 -0
  41. globkurier_api_mcp-0.2.0/globkurier_mcp/core/shipping/services.py +32 -0
  42. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/__init__.py +1 -0
  43. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/cache/__init__.py +7 -0
  44. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/cache/cached_country_repository.py +82 -0
  45. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/http/__init__.py +3 -0
  46. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/http/countries_client.py +127 -0
  47. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/http/globkurier_client.py +278 -0
  48. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/http/products_client.py +413 -0
  49. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/logging/__init__.py +5 -0
  50. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/logging/config.py +91 -0
  51. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/__init__.py +3 -0
  52. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/prompts/__init__.py +11 -0
  53. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/prompts/prompt_registry.py +165 -0
  54. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/server.py +408 -0
  55. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/__init__.py +5 -0
  56. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/get_countries_tool.py +29 -0
  57. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/get_product_addons_tool.py +97 -0
  58. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/get_search_url_tool.py +62 -0
  59. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/search_products_tool.py +67 -0
  60. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/mcp/tools/shipment_status_tool.py +46 -0
  61. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/prompts/__init__.py +9 -0
  62. globkurier_api_mcp-0.2.0/globkurier_mcp/infrastructure/prompts/json_prompt_repository.py +129 -0
  63. globkurier_api_mcp-0.2.0/globkurier_mcp/main.py +138 -0
  64. globkurier_api_mcp-0.2.0/pyproject.toml +62 -0
  65. globkurier_api_mcp-0.2.0/setup.cfg +4 -0
  66. globkurier_api_mcp-0.2.0/tests/test_domain_models.py +94 -0
  67. globkurier_api_mcp-0.2.0/tests/test_prompts_domain_models.py +179 -0
  68. globkurier_api_mcp-0.2.0/tests/test_prompts_query_handler.py +194 -0
  69. globkurier_api_mcp-0.2.0/tests/test_prompts_repository.py +252 -0
  70. globkurier_api_mcp-0.2.0/tests/test_query_handler.py +61 -0
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: globkurier-api-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP server for GlobKurier API - Hexagonal Architecture with CQRS
5
+ Author-email: GlobKurier <it@globkurier.pl>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/GlobKurier-pl/mcp-server
8
+ Project-URL: Repository, https://github.com/GlobKurier-pl/mcp-server
9
+ Project-URL: Documentation, https://github.com/GlobKurier-pl/mcp-server#readme
10
+ Keywords: mcp,shipping,logistics,globkurier,dpd,inpost,courier
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: Internet
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: fastmcp>=2.0.0
21
+ Requires-Dist: httpx>=0.27.0
22
+ Requires-Dist: python-dotenv>=1.0.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: pydantic-settings>=2.0.0
25
+
26
+ <!-- mcp-name: io.github.globkurier-pl/mcp-server -->
27
+
28
+ # GlobKurier MCP Server
29
+
30
+ > [Polska wersja dokumentacji](./README.pl.md)
31
+
32
+ [Model Context Protocol](https://modelcontextprotocol.io/) server for the [GlobKurier](https://www.globkurier.pl) API. Enables AI assistants (Claude, Cursor, Cline and others) to track shipments, search shipping products and generate purchase links.
33
+
34
+ ## Installation
35
+
36
+ ### Recommended: Hosted server (no local installation)
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "globkurier": {
42
+ "type": "http",
43
+ "url": "https://mcp.globkurier.pl/mcp"
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ### Alternative: Run locally via `uvx`
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "globkurier": {
55
+ "command": "uvx",
56
+ "args": ["globkurier-api-mcp"]
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ Paste the configuration into your MCP client settings file:
63
+
64
+ | Client | Settings file |
65
+ |---|---|
66
+ | **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
67
+ | **Cursor** | `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally |
68
+ | **Cline** | Extension settings in VS Code |
69
+
70
+ ## Available Tools
71
+
72
+ | Tool | Description |
73
+ |---|---|
74
+ | `get_shipment_status` | Track a shipment by order number |
75
+ | `search_products` | Search shipping products (DPD, InPost, DHL, FedEx, UPS, GLS and more) |
76
+ | `get_product_addons` | Get available add-ons for a product |
77
+ | `get_search_url` | Generate a purchase link for a shipment |
78
+
79
+ ## Available Resources
80
+
81
+ | Resource | Description |
82
+ |---|---|
83
+ | `globkurier://countries` | List of supported countries |
84
+ | `globkurier://countries/{iso_code}` | Country details by ISO code |
85
+
86
+ ---
87
+
88
+ For developer documentation see [CONTRIBUTING.md](./CONTRIBUTING.md).
89
+
90
+ ## License
91
+
92
+ MIT
93
+
94
+ ## Author
95
+
96
+ it@globkurier.pl
@@ -0,0 +1,71 @@
1
+ <!-- mcp-name: io.github.globkurier-pl/mcp-server -->
2
+
3
+ # GlobKurier MCP Server
4
+
5
+ > [Polska wersja dokumentacji](./README.pl.md)
6
+
7
+ [Model Context Protocol](https://modelcontextprotocol.io/) server for the [GlobKurier](https://www.globkurier.pl) API. Enables AI assistants (Claude, Cursor, Cline and others) to track shipments, search shipping products and generate purchase links.
8
+
9
+ ## Installation
10
+
11
+ ### Recommended: Hosted server (no local installation)
12
+
13
+ ```json
14
+ {
15
+ "mcpServers": {
16
+ "globkurier": {
17
+ "type": "http",
18
+ "url": "https://mcp.globkurier.pl/mcp"
19
+ }
20
+ }
21
+ }
22
+ ```
23
+
24
+ ### Alternative: Run locally via `uvx`
25
+
26
+ ```json
27
+ {
28
+ "mcpServers": {
29
+ "globkurier": {
30
+ "command": "uvx",
31
+ "args": ["globkurier-api-mcp"]
32
+ }
33
+ }
34
+ }
35
+ ```
36
+
37
+ Paste the configuration into your MCP client settings file:
38
+
39
+ | Client | Settings file |
40
+ |---|---|
41
+ | **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
42
+ | **Cursor** | `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally |
43
+ | **Cline** | Extension settings in VS Code |
44
+
45
+ ## Available Tools
46
+
47
+ | Tool | Description |
48
+ |---|---|
49
+ | `get_shipment_status` | Track a shipment by order number |
50
+ | `search_products` | Search shipping products (DPD, InPost, DHL, FedEx, UPS, GLS and more) |
51
+ | `get_product_addons` | Get available add-ons for a product |
52
+ | `get_search_url` | Generate a purchase link for a shipment |
53
+
54
+ ## Available Resources
55
+
56
+ | Resource | Description |
57
+ |---|---|
58
+ | `globkurier://countries` | List of supported countries |
59
+ | `globkurier://countries/{iso_code}` | Country details by ISO code |
60
+
61
+ ---
62
+
63
+ For developer documentation see [CONTRIBUTING.md](./CONTRIBUTING.md).
64
+
65
+ ## License
66
+
67
+ MIT
68
+
69
+ ## Author
70
+
71
+ it@globkurier.pl
@@ -0,0 +1,96 @@
1
+ Metadata-Version: 2.4
2
+ Name: globkurier-api-mcp
3
+ Version: 0.2.0
4
+ Summary: MCP server for GlobKurier API - Hexagonal Architecture with CQRS
5
+ Author-email: GlobKurier <it@globkurier.pl>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/GlobKurier-pl/mcp-server
8
+ Project-URL: Repository, https://github.com/GlobKurier-pl/mcp-server
9
+ Project-URL: Documentation, https://github.com/GlobKurier-pl/mcp-server#readme
10
+ Keywords: mcp,shipping,logistics,globkurier,dpd,inpost,courier
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
17
+ Classifier: Topic :: Internet
18
+ Requires-Python: >=3.12
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: fastmcp>=2.0.0
21
+ Requires-Dist: httpx>=0.27.0
22
+ Requires-Dist: python-dotenv>=1.0.0
23
+ Requires-Dist: pydantic>=2.0.0
24
+ Requires-Dist: pydantic-settings>=2.0.0
25
+
26
+ <!-- mcp-name: io.github.globkurier-pl/mcp-server -->
27
+
28
+ # GlobKurier MCP Server
29
+
30
+ > [Polska wersja dokumentacji](./README.pl.md)
31
+
32
+ [Model Context Protocol](https://modelcontextprotocol.io/) server for the [GlobKurier](https://www.globkurier.pl) API. Enables AI assistants (Claude, Cursor, Cline and others) to track shipments, search shipping products and generate purchase links.
33
+
34
+ ## Installation
35
+
36
+ ### Recommended: Hosted server (no local installation)
37
+
38
+ ```json
39
+ {
40
+ "mcpServers": {
41
+ "globkurier": {
42
+ "type": "http",
43
+ "url": "https://mcp.globkurier.pl/mcp"
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ### Alternative: Run locally via `uvx`
50
+
51
+ ```json
52
+ {
53
+ "mcpServers": {
54
+ "globkurier": {
55
+ "command": "uvx",
56
+ "args": ["globkurier-api-mcp"]
57
+ }
58
+ }
59
+ }
60
+ ```
61
+
62
+ Paste the configuration into your MCP client settings file:
63
+
64
+ | Client | Settings file |
65
+ |---|---|
66
+ | **Claude Desktop** | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) / `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
67
+ | **Cursor** | `.cursor/mcp.json` in your project or `~/.cursor/mcp.json` globally |
68
+ | **Cline** | Extension settings in VS Code |
69
+
70
+ ## Available Tools
71
+
72
+ | Tool | Description |
73
+ |---|---|
74
+ | `get_shipment_status` | Track a shipment by order number |
75
+ | `search_products` | Search shipping products (DPD, InPost, DHL, FedEx, UPS, GLS and more) |
76
+ | `get_product_addons` | Get available add-ons for a product |
77
+ | `get_search_url` | Generate a purchase link for a shipment |
78
+
79
+ ## Available Resources
80
+
81
+ | Resource | Description |
82
+ |---|---|
83
+ | `globkurier://countries` | List of supported countries |
84
+ | `globkurier://countries/{iso_code}` | Country details by ISO code |
85
+
86
+ ---
87
+
88
+ For developer documentation see [CONTRIBUTING.md](./CONTRIBUTING.md).
89
+
90
+ ## License
91
+
92
+ MIT
93
+
94
+ ## Author
95
+
96
+ it@globkurier.pl
@@ -0,0 +1,68 @@
1
+ README.md
2
+ pyproject.toml
3
+ globkurier_api_mcp.egg-info/PKG-INFO
4
+ globkurier_api_mcp.egg-info/SOURCES.txt
5
+ globkurier_api_mcp.egg-info/dependency_links.txt
6
+ globkurier_api_mcp.egg-info/entry_points.txt
7
+ globkurier_api_mcp.egg-info/requires.txt
8
+ globkurier_api_mcp.egg-info/top_level.txt
9
+ globkurier_mcp/__init__.py
10
+ globkurier_mcp/__main__.py
11
+ globkurier_mcp/main.py
12
+ globkurier_mcp/application/__init__.py
13
+ globkurier_mcp/application/bus/__init__.py
14
+ globkurier_mcp/application/bus/dispatcher.py
15
+ globkurier_mcp/application/commands/__init__.py
16
+ globkurier_mcp/application/dto/__init__.py
17
+ globkurier_mcp/application/dto/countries_dto.py
18
+ globkurier_mcp/application/dto/product_dto.py
19
+ globkurier_mcp/application/dto/shipping_dto.py
20
+ globkurier_mcp/application/queries/__init__.py
21
+ globkurier_mcp/application/queries/get_countries.py
22
+ globkurier_mcp/application/queries/get_product_addons.py
23
+ globkurier_mcp/application/queries/get_prompts.py
24
+ globkurier_mcp/application/queries/get_search_url.py
25
+ globkurier_mcp/application/queries/get_shipment_status.py
26
+ globkurier_mcp/application/queries/search_products.py
27
+ globkurier_mcp/config/__init__.py
28
+ globkurier_mcp/config/settings.py
29
+ globkurier_mcp/core/__init__.py
30
+ globkurier_mcp/core/countries/__init__.py
31
+ globkurier_mcp/core/countries/models.py
32
+ globkurier_mcp/core/countries/ports.py
33
+ globkurier_mcp/core/products/__init__.py
34
+ globkurier_mcp/core/products/models.py
35
+ globkurier_mcp/core/products/ports.py
36
+ globkurier_mcp/core/prompts/__init__.py
37
+ globkurier_mcp/core/prompts/models.py
38
+ globkurier_mcp/core/prompts/ports.py
39
+ globkurier_mcp/core/shipping/__init__.py
40
+ globkurier_mcp/core/shipping/models.py
41
+ globkurier_mcp/core/shipping/ports.py
42
+ globkurier_mcp/core/shipping/services.py
43
+ globkurier_mcp/infrastructure/__init__.py
44
+ globkurier_mcp/infrastructure/cache/__init__.py
45
+ globkurier_mcp/infrastructure/cache/cached_country_repository.py
46
+ globkurier_mcp/infrastructure/http/__init__.py
47
+ globkurier_mcp/infrastructure/http/countries_client.py
48
+ globkurier_mcp/infrastructure/http/globkurier_client.py
49
+ globkurier_mcp/infrastructure/http/products_client.py
50
+ globkurier_mcp/infrastructure/logging/__init__.py
51
+ globkurier_mcp/infrastructure/logging/config.py
52
+ globkurier_mcp/infrastructure/mcp/__init__.py
53
+ globkurier_mcp/infrastructure/mcp/server.py
54
+ globkurier_mcp/infrastructure/mcp/prompts/__init__.py
55
+ globkurier_mcp/infrastructure/mcp/prompts/prompt_registry.py
56
+ globkurier_mcp/infrastructure/mcp/tools/__init__.py
57
+ globkurier_mcp/infrastructure/mcp/tools/get_countries_tool.py
58
+ globkurier_mcp/infrastructure/mcp/tools/get_product_addons_tool.py
59
+ globkurier_mcp/infrastructure/mcp/tools/get_search_url_tool.py
60
+ globkurier_mcp/infrastructure/mcp/tools/search_products_tool.py
61
+ globkurier_mcp/infrastructure/mcp/tools/shipment_status_tool.py
62
+ globkurier_mcp/infrastructure/prompts/__init__.py
63
+ globkurier_mcp/infrastructure/prompts/json_prompt_repository.py
64
+ tests/test_domain_models.py
65
+ tests/test_prompts_domain_models.py
66
+ tests/test_prompts_query_handler.py
67
+ tests/test_prompts_repository.py
68
+ tests/test_query_handler.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ globkurier-mcp = globkurier_mcp:main
@@ -0,0 +1,5 @@
1
+ fastmcp>=2.0.0
2
+ httpx>=0.27.0
3
+ python-dotenv>=1.0.0
4
+ pydantic>=2.0.0
5
+ pydantic-settings>=2.0.0
@@ -0,0 +1,16 @@
1
+ """GlobKurier MCP Server - Hexagonal Architecture Implementation.
2
+
3
+ This package implements a Model Context Protocol (MCP) server for GlobKurier API
4
+ using Clean Architecture and CQRS principles.
5
+
6
+ Architecture layers:
7
+ - core: Domain models, value objects, and ports (business logic)
8
+ - application: Use cases, DTOs, queries, commands, and bus (orchestration)
9
+ - infrastructure: HTTP clients, MCP tools, external adapters (implementation details)
10
+ - config: Settings and configuration
11
+ """
12
+
13
+ from globkurier_mcp.main import main
14
+
15
+ __version__ = "0.2.0"
16
+ __all__ = ["main"]
@@ -0,0 +1,6 @@
1
+ """Entry point for running the package as a module."""
2
+
3
+ from globkurier_mcp.main import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1 @@
1
+ # Application layer package
@@ -0,0 +1,3 @@
1
+ from globkurier_mcp.application.bus.dispatcher import QueryBus, create_query_bus
2
+
3
+ __all__ = ["QueryBus", "create_query_bus"]
@@ -0,0 +1,112 @@
1
+ from collections.abc import Callable
2
+ from typing import Any, TypeVar, cast
3
+
4
+ from globkurier_mcp.application.queries.get_countries import (
5
+ GetCountriesQuery,
6
+ GetCountriesQueryHandler,
7
+ GetCountryByIsoQuery,
8
+ GetCountryByIsoQueryHandler,
9
+ )
10
+ from globkurier_mcp.application.queries.get_product_addons import (
11
+ GetProductAddonsQuery,
12
+ GetProductAddonsQueryHandler,
13
+ )
14
+ from globkurier_mcp.application.queries.get_prompts import (
15
+ GetAllPromptsQuery,
16
+ GetAllPromptsQueryHandler,
17
+ GetPromptByNameQuery,
18
+ GetPromptByNameQueryHandler,
19
+ )
20
+ from globkurier_mcp.application.queries.get_search_url import (
21
+ GetSearchUrlQuery,
22
+ GetSearchUrlQueryHandler,
23
+ )
24
+ from globkurier_mcp.application.queries.get_shipment_status import (
25
+ GetShipmentStatusQuery,
26
+ GetShipmentStatusQueryHandler,
27
+ )
28
+ from globkurier_mcp.application.queries.search_products import (
29
+ SearchProductsQuery,
30
+ SearchProductsQueryHandler,
31
+ )
32
+
33
+ TQuery = TypeVar("TQuery")
34
+ TResult = TypeVar("TResult")
35
+
36
+
37
+ class QueryBus:
38
+ """Simple query bus implementing CQRS pattern.
39
+
40
+ Routes queries to their respective handlers.
41
+ In a larger application, this could be replaced with a more
42
+ sophisticated implementation (e.g., using dependency injection).
43
+ """
44
+
45
+ def __init__(self) -> None:
46
+ self._handlers: dict[type, Callable[[Any], Any]] = {}
47
+
48
+ def register(self, query_type: type[TQuery], handler: Callable[[TQuery], TResult]) -> None:
49
+ """Register a query handler.
50
+
51
+ Args:
52
+ query_type: The type of query this handler processes
53
+ handler: The handler function/method
54
+ """
55
+ self._handlers[query_type] = handler
56
+
57
+ async def execute(self, query: TQuery) -> TResult:
58
+ """Execute a query by dispatching to registered handler.
59
+
60
+ Args:
61
+ query: The query to execute
62
+
63
+ Returns:
64
+ The result from the handler
65
+
66
+ Raises:
67
+ ValueError: If no handler is registered for this query type
68
+ """
69
+ query_type = type(query)
70
+ handler = self._handlers.get(query_type)
71
+
72
+ if handler is None:
73
+ raise ValueError(f"No handler registered for query type: {query_type.__name__}")
74
+
75
+ return cast(TResult, await handler(query))
76
+
77
+
78
+ def create_query_bus(
79
+ get_shipment_status_handler: GetShipmentStatusQueryHandler,
80
+ get_countries_handler: GetCountriesQueryHandler,
81
+ get_country_by_iso_handler: GetCountryByIsoQueryHandler,
82
+ get_all_prompts_handler: GetAllPromptsQueryHandler,
83
+ get_prompt_by_name_handler: GetPromptByNameQueryHandler,
84
+ search_products_handler: SearchProductsQueryHandler,
85
+ get_product_addons_handler: GetProductAddonsQueryHandler,
86
+ get_search_url_handler: GetSearchUrlQueryHandler,
87
+ ) -> QueryBus:
88
+ """Factory function to create and configure the query bus.
89
+
90
+ Args:
91
+ get_shipment_status_handler: Handler for shipment status queries
92
+ get_countries_handler: Handler for countries list queries
93
+ get_country_by_iso_handler: Handler for single country by ISO code queries
94
+ get_all_prompts_handler: Handler for all prompts queries
95
+ get_prompt_by_name_handler: Handler for single prompt by name queries
96
+ search_products_handler: Handler for product search queries
97
+ get_product_addons_handler: Handler for product addons queries
98
+ get_search_url_handler: Handler for search URL generation queries
99
+
100
+ Returns:
101
+ Configured QueryBus instance
102
+ """
103
+ bus = QueryBus()
104
+ bus.register(GetShipmentStatusQuery, get_shipment_status_handler.handle)
105
+ bus.register(GetCountriesQuery, get_countries_handler.handle)
106
+ bus.register(GetCountryByIsoQuery, get_country_by_iso_handler.handle)
107
+ bus.register(GetAllPromptsQuery, get_all_prompts_handler.handle)
108
+ bus.register(GetPromptByNameQuery, get_prompt_by_name_handler.handle)
109
+ bus.register(SearchProductsQuery, search_products_handler.handle)
110
+ bus.register(GetProductAddonsQuery, get_product_addons_handler.handle)
111
+ bus.register(GetSearchUrlQuery, get_search_url_handler.handle)
112
+ return bus
@@ -0,0 +1,2 @@
1
+ # Commands package - placeholder for future write operations
2
+ # Example: CreateShipmentCommand, UpdateShipmentCommand, etc.
@@ -0,0 +1,3 @@
1
+ from globkurier_mcp.application.dto.shipping_dto import ShipmentStatusDto, TrackingEventDto
2
+
3
+ __all__ = ["ShipmentStatusDto", "TrackingEventDto"]
@@ -0,0 +1,26 @@
1
+ """DTOs for countries bounded context."""
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+
6
+ class CountryDto(BaseModel):
7
+ """DTO for a single country."""
8
+
9
+ id: int = Field(..., description="Unique country identifier")
10
+ name: str = Field(..., description="Country name")
11
+ iso_code: str = Field(..., description="ISO 3166-1 alpha-2 code")
12
+ is_ue_member: bool = Field(..., description="Whether country is EU member")
13
+ is_road_transport_available: bool = Field(..., description="Road transport availability")
14
+ has_states: bool = Field(..., description="Whether country has states/provinces")
15
+ has_post_codes: bool = Field(..., description="Whether country uses postal codes")
16
+ post_code_format: str | None = Field(None, description="Postal code format pattern")
17
+ phone_prefix: str = Field(..., description="International phone prefix")
18
+ post_code_samples: str | None = Field(None, description="Example postal codes")
19
+
20
+
21
+ class CountriesListDto(BaseModel):
22
+ """DTO for list of countries."""
23
+
24
+ countries: list[CountryDto] = Field(..., description="List of available countries")
25
+ total_count: int = Field(..., description="Total number of countries")
26
+ cached: bool = Field(..., description="Whether data was served from cache")
@@ -0,0 +1,138 @@
1
+ """DTOs for product search results.
2
+
3
+ These DTOs are used to transfer data from application layer to presentation layer (MCP).
4
+ Domain models are never exposed directly.
5
+ """
6
+
7
+ from decimal import Decimal
8
+ from typing import Any
9
+
10
+ from pydantic import BaseModel, ConfigDict, Field
11
+
12
+
13
+ class TransportDto(BaseModel):
14
+ """Transport information DTO."""
15
+
16
+ code: str
17
+ name: str
18
+
19
+
20
+ class CollectionTypeOptionDto(BaseModel):
21
+ """Collection type option DTO."""
22
+
23
+ key: str
24
+ trans: str
25
+ image: str
26
+
27
+
28
+ class DeliveryTypeOptionDto(BaseModel):
29
+ """Delivery type option DTO."""
30
+
31
+ key: str
32
+ trans: str
33
+ image: str
34
+
35
+
36
+ class ProductDto(BaseModel):
37
+ """Product DTO for API responses."""
38
+
39
+ id: int
40
+ name: str
41
+ carrier_name: str = Field(alias="carrierName")
42
+ service_code: str | None = Field(alias="serviceCode")
43
+ net_price: Decimal = Field(alias="netPrice")
44
+ gross_price: Decimal = Field(alias="grossPrice")
45
+ net_price_standard: Decimal | None = Field(None, alias="netPriceStandard")
46
+ gross_price_standard: Decimal | None = Field(None, alias="grossPriceStandard")
47
+ currency: str
48
+ units: int
49
+ protocol_available: bool = Field(alias="protocolAvailable")
50
+ package_type: str = Field(alias="packageType")
51
+ package_name: str = Field(alias="packageName")
52
+ transport: TransportDto
53
+ for_company: bool = Field(alias="forCompany")
54
+ carrier_logo_link: str = Field(alias="carrierLogoLink")
55
+ discount_code_allowed: bool = Field(alias="discountCodeAllowed")
56
+ average_delivery: int | None = Field(alias="averageDelivery")
57
+ delivery_time_type: str = Field(alias="deliveryTimeType")
58
+ details_link: str | None = Field(alias="detailsLink")
59
+ promo: str | None = None
60
+ has_country_zone_routing: bool = Field(alias="hasCountryZoneRouting")
61
+ on_demand_delivery_point_required: bool = Field(
62
+ alias="onDemandDeliveryPointRequired"
63
+ )
64
+ custom_document_type: str | None = Field(None, alias="customDocumentType")
65
+ labels: list[str]
66
+ collection_types: list[str] = Field(alias="collectionTypes")
67
+ addons_categories: list[str] = Field(alias="addonsCategories")
68
+ delivery_types: list[str] = Field(alias="deliveryTypes")
69
+ collection_type_options: list[CollectionTypeOptionDto] = Field(
70
+ alias="collectionTypeOptions"
71
+ )
72
+ delivery_type_options: list[DeliveryTypeOptionDto] = Field(
73
+ alias="deliveryTypeOptions"
74
+ )
75
+ carrier_id: int = Field(alias="carrierId")
76
+
77
+ model_config = ConfigDict(populate_by_name=True)
78
+
79
+
80
+ class ProductSearchResultDto(BaseModel):
81
+ """DTO for product search results grouped by delivery time."""
82
+
83
+ fast: list[ProductDto]
84
+ superfast: list[ProductDto]
85
+ noon: list[ProductDto]
86
+ morning: list[ProductDto]
87
+ standard: list[ProductDto]
88
+ total_products: int = Field(alias="totalProducts")
89
+ cheapest_product_id: int | None = Field(None, alias="cheapestProductId")
90
+ fastest_product_id: int | None = Field(None, alias="fastestProductId")
91
+
92
+ model_config = ConfigDict(populate_by_name=True)
93
+
94
+
95
+ class AddonDto(BaseModel):
96
+ """Addon DTO for API responses."""
97
+
98
+ id: int
99
+ addon_name: str = Field(alias="addonName")
100
+ description: str | None = None
101
+ attributes: dict[str, Any] | None = None
102
+ addon_logo: str | None = Field(None, alias="addonLogo")
103
+ price: Decimal
104
+ price_gross: Decimal = Field(alias="priceGross")
105
+ price_description: str | None = Field(None, alias="priceDescription")
106
+ quantity: int = 1
107
+ currency: str
108
+ category: str
109
+ is_required: bool = Field(alias="isRequired")
110
+ insurance_required: bool = Field(alias="insuranceRequired")
111
+ min_value: Decimal | None = Field(None, alias="minValue")
112
+ max_value: Decimal | None = Field(None, alias="maxValue")
113
+ value_currency: str | None = Field(None, alias="valueCurrency")
114
+ days_to_return: int | None = Field(None, alias="daysToReturn")
115
+ verification_required: bool = Field(alias="verificationRequired")
116
+ in_price: bool = Field(alias="inPrice")
117
+
118
+ model_config = ConfigDict(populate_by_name=True)
119
+
120
+
121
+ class GetAddonsResultDto(BaseModel):
122
+ """DTO for product addons result."""
123
+
124
+ addons: list[AddonDto]
125
+ required_alternative_addons_groups: list[list[int]] = Field(
126
+ alias="requiredAlternativeAddonsGroups"
127
+ )
128
+ total_addons: int = Field(alias="totalAddons")
129
+ required_addons_count: int = Field(alias="requiredAddonsCount")
130
+ optional_addons_count: int = Field(alias="optionalAddonsCount")
131
+
132
+ model_config = ConfigDict(populate_by_name=True)
133
+
134
+
135
+ class SearchUrlDto(BaseModel):
136
+ """DTO for GlobKurier search page URL."""
137
+
138
+ url: str = Field(..., description="URL to GlobKurier search page with pre-filled parameters")