python-alfresco-mcp-server 1.2.0__tar.gz → 1.2.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.
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/CHANGELOG.md +172 -161
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/PKG-INFO +18 -4
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/README.md +15 -1
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/config.py +145 -139
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/utils/connection.py +14 -2
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/pyproject.toml +2 -2
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/sample-dot-env.txt +63 -58
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/.gitignore +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/LICENSE +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/fastmcp_server.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/prompts/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/prompts/search_and_analyze.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/resources/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/resources/repository_resources.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/browse_repository.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/cancel_checkout.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/checkin_document.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/checkout_document.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/create_folder.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/delete_node.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/download_document.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/get_node_properties.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/update_node_properties.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/core/upload_document.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/search/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/search/advanced_search.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/search/cmis_search.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/search/search_by_metadata.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/tools/search/search_content.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/utils/__init__.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/utils/file_type_analysis.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/utils/json_utils.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-pipx-macos.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-pipx-windows.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-uv-macos.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-uv-windows.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-uvx-macos.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/claude-desktop-configs/claude-desktop-config-uvx-windows.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/config.yaml +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/README.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/api_reference.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/claude_desktop_setup.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/client_configurations.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/configuration_guide.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/install_with_pip_pipx.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/mcp_inspector_setup.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/quick_start_guide.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/testing_guide.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/troubleshooting.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/README.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/batch_operations.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/document_lifecycle.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/error_handling.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/examples_summary.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/quick_start.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/transport_examples.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-http-pipx-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-http-uv-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-http-uvx-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-stdio-pipx-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-stdio-uv-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/mcp-inspector-configs/mcp-inspector-stdio-uvx-config.json +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/prompts-for-claude.md +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/pytest.ini +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/run_server.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/scripts/run_tests.py +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/scripts/test.bat +0 -0
- {python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/uv.lock +0 -0
|
@@ -1,162 +1,173 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
|
|
8
|
-
## [Unreleased]
|
|
9
|
-
|
|
10
|
-
## [1.2.
|
|
11
|
-
|
|
12
|
-
### Added
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
###
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
- **
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
###
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
- `
|
|
65
|
-
- `
|
|
66
|
-
- `
|
|
67
|
-
- `
|
|
68
|
-
- `
|
|
69
|
-
- `
|
|
70
|
-
- `
|
|
71
|
-
-
|
|
72
|
-
|
|
73
|
-
###
|
|
74
|
-
-
|
|
75
|
-
- `
|
|
76
|
-
-
|
|
77
|
-
- `
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
-
|
|
81
|
-
-
|
|
82
|
-
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
-
|
|
87
|
-
- added
|
|
88
|
-
- added
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
-
|
|
114
|
-
-
|
|
115
|
-
-
|
|
116
|
-
|
|
117
|
-
###
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-
|
|
124
|
-
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
138
|
-
-
|
|
139
|
-
-
|
|
140
|
-
-
|
|
141
|
-
-
|
|
142
|
-
-
|
|
143
|
-
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
150
|
-
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [Unreleased]
|
|
9
|
+
|
|
10
|
+
## [1.2.1] - 2026-09-29
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- **`ALFRESCO_TICKET`**: with `ALFRESCO_AUTH_METHOD=ticket`, a login ticket you already hold is used as-is instead of being fetched from a username and password — so the server can run with no Alfresco password configured at all. Leave it unset and ticket auth behaves as before (acquired from `ALFRESCO_USERNAME` / `ALFRESCO_PASSWORD`). A supplied ticket is never renewed, so it stops working when it expires.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Requires **python-alfresco-api >= 1.2.2** for the ticket pass-through above.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- **Integration test `test_search_shared_folder`**: now passes `node_type="cm:folder"`. `search_content` searches documents (`cm:content`) by default, so the search never matched the Shared folder and the test failed.
|
|
20
|
+
|
|
21
|
+
## [1.2.0] - 2026-08-05
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- **Alfresco auth methods** (`ALFRESCO_AUTH_METHOD` = `basic` | `ticket` | `oauth2`): the server can now authenticate to Alfresco via HTTP Basic, a login ticket, or an OAuth2/OIDC bearer token (Alfresco `identity-service`), via `python-alfresco-api` 1.2.1+ `OAuth2AuthUtil`, configured with `ALFRESCO_OAUTH2_*` env vars. Documents the setup in the README **Authentication** section (addresses #2). Live-tested basic/ticket/oauth2 end-to-end.
|
|
25
|
+
- **Optional MCP transport authentication** (`MCP_TRANSPORT_AUTH=true`): secures the MCP server itself — HTTP/SSE callers must present an OAuth2 bearer token, validated against an OIDC IdP's JWKS (FastMCP JWT verifier). Off by default; stdio unaffected. Env: `MCP_AUTH_JWKS_URI` / `MCP_AUTH_ISSUER` / `MCP_AUTH_AUDIENCE`.
|
|
26
|
+
- **`download_document` `destination_dir`**: optional custom download folder (default `~/Downloads`). Thanks [@jeremie-lesage](https://github.com/jeremie-lesage) ([#1](https://github.com/stevereiner/python-alfresco-mcp-server/pull/1)).
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- **Version 1.2.0** of this package; requires **python-alfresco-api >= 1.2.1** (OAuth2/OIDC auth, `VersionsClient` fix, and OAuth2 service-account `displayName` handling — see below).
|
|
30
|
+
- **Config layout**: moved Claude Desktop sample configs into [`claude-desktop-configs/`](./claude-desktop-configs/) and MCP Inspector samples into [`mcp-inspector-configs/`](./mcp-inspector-configs/); docs and README updated accordingly.
|
|
31
|
+
- **FastMCP 3 upgrade**: bumped dependency from FastMCP 2.x to `fastmcp>=3.4.5,<4`. Server code is compatible with FastMCP 3's API (`list_tools()` / `list_resources()` / `list_prompts()`); JWT transport auth now uses `JWTVerifier` directly. See [FastMCP 2 → 3 upgrade guide](https://gofastmcp.com/getting-started/upgrading/from-fastmcp-2).
|
|
32
|
+
- **Packaging**: switched build backend from setuptools to hatchling (same as python-alfresco-api) for quieter `uv build` output.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
- **checkout_document**: local download filename puts the node ID before the extension (`name_<nodeId>.txt`) instead of after it (`name.txt_<nodeId>`), so editors keep the correct file type.
|
|
36
|
+
- **OAuth2 service-account nodes** (via **python-alfresco-api 1.2.1**): Keycloak client-credentials authenticates as a JIT Alfresco user with no display name, so Alfresco returns `createdByUser` / `modifiedByUser` / `owner` without `displayName` and the generated `UserInfo.from_dict` raised `KeyError('displayName')` (breaking `download_document` and other `nodes.get` tools). Fixed upstream with a runtime shim (`python_alfresco_api/_compat.py`, applied at package import) that defaults missing `displayName` to `id` for core and search `UserInfo` — outside `raw_clients/` so it survives client re-generation. Basic/ticket and user-based OAuth2 tokens were unaffected.
|
|
37
|
+
|
|
38
|
+
## [1.1.0] - 2025-01-25
|
|
39
|
+
|
|
40
|
+
### Alfresco_MCP_Server dir code changes for v1.1
|
|
41
|
+
- **Code Split**: Refactored from monolithic single file to modular structure with separate files
|
|
42
|
+
- **Directory Structure**: Reorganized from flat to hierarchical structure
|
|
43
|
+
- `tools/search/` - 4 search-related tools
|
|
44
|
+
- `tools/core/` - 11 core management tools
|
|
45
|
+
- `resources/` - Repository information
|
|
46
|
+
- `prompts/` - AI templates
|
|
47
|
+
- `utils/` - Shared utilities
|
|
48
|
+
- fix: implement Windows UTF-8 encoding support (emoji character encoding)
|
|
49
|
+
- get to work with python-alfresco-api 1.1.x
|
|
50
|
+
- add imports and __all__ to get files included in packaging
|
|
51
|
+
|
|
52
|
+
### UV Package Management Support
|
|
53
|
+
- **Rust-based Performance**: UV provides faster dependency resolution and package management
|
|
54
|
+
- **Automatic Environment Management**: UV handles virtual environment creation and activation
|
|
55
|
+
- **Simplified Installation**: One-command setup replaces multi-step manual process
|
|
56
|
+
- **Cross-platform Compatibility**: Consistent behavior across Windows, macOS, and Linux
|
|
57
|
+
|
|
58
|
+
### PyPI Distribution
|
|
59
|
+
- **Direct Installation**: Available via `pip install python-alfresco-mcp-server`
|
|
60
|
+
- **UV Integration**: Compatible with `uv pip install python-alfresco-mcp-server`
|
|
61
|
+
- **Immediate Usage**: Run server directly after installation without source code
|
|
62
|
+
|
|
63
|
+
### Update Tests for v1.1
|
|
64
|
+
- `test: transform test suite from 76+ failures to 143/143 passing`
|
|
65
|
+
- `test: add comprehensive live integration testing with 21 Alfresco tests`
|
|
66
|
+
- `test: implement cross-platform emoji handling for Windows compatibility`
|
|
67
|
+
- `test: enhance coverage reporting with HTML output`
|
|
68
|
+
- `test: add automated testing for all manual scenarios`
|
|
69
|
+
- `test: implement strip_emojis() function for Windows compatibility`
|
|
70
|
+
- `test: add comprehensive unit test coverage (122 tests)`
|
|
71
|
+
- `test: fix test import paths for modular architecture`
|
|
72
|
+
|
|
73
|
+
### MCP Clients: config files added for v1.1
|
|
74
|
+
- Added Claude Desktop and MCP Inspector config files
|
|
75
|
+
- `config: added claude-desktop-config-developer-windows.json with UV support`
|
|
76
|
+
- `config: added claude-desktop-config-developer-macos.json with UV support`
|
|
77
|
+
- `config: added claude-desktop-config-user-windows.json`
|
|
78
|
+
- `config: added claude-desktop-config-user-macos.json`
|
|
79
|
+
- `config: added Windows UTF-8 encoding variables to windows configs`
|
|
80
|
+
- `config: added mcp-inspector-http-config.json for HTTP transport using uv`
|
|
81
|
+
- `config: added mcp-inspector-stdio-config.json for STDIO transport using uv`
|
|
82
|
+
- 'examples: prompts-for-claude.md has example prompt text to test tools
|
|
83
|
+
|
|
84
|
+
### Update docs for v1.1
|
|
85
|
+
- `docs: create comprehensive CHANGELOG.md for v1.0.0 and v1.1.0`
|
|
86
|
+
- `docs: update quick start guide for UV approach`
|
|
87
|
+
- 'docs: api_reference.md added details for all tools, etc
|
|
88
|
+
- `docs: added claude_desktop_setup.md, mcp_inspector_setup.md, and client_configurations.md
|
|
89
|
+
|
|
90
|
+
### Documentation Updates for v1.1
|
|
91
|
+
- **Installation Instructions**: Added PyPI installation methods
|
|
92
|
+
- **Configuration Examples**: Updated for UV approach
|
|
93
|
+
- **Testing Procedures**: Comprehensive test execution guidance
|
|
94
|
+
- **Troubleshooting**: Enhanced problem resolution guidance
|
|
95
|
+
|
|
96
|
+
### Update Readme for v1.1
|
|
97
|
+
- added install from PyPI
|
|
98
|
+
- added how to install UV package manager
|
|
99
|
+
- added claude desktop and mcp inspector setup sections
|
|
100
|
+
- reword technical sections for accuracy
|
|
101
|
+
- add v1.1 list of changes, depend on python-alfresco 1.1.1, python 3.10+
|
|
102
|
+
- added how to install Alfresco Community from github
|
|
103
|
+
|
|
104
|
+
### Update project files and misc root dir files for v1.1
|
|
105
|
+
- gitignore now ignores cursor memory and memory-bank dir, keep .vscode/mcp.json
|
|
106
|
+
- config.yaml has changed alfresco_url to have base_url, added timeout, added
|
|
107
|
+
mcp server name and version confg
|
|
108
|
+
- MANIFEST.in added for proper package distrubution config
|
|
109
|
+
- pyproject.toml change to have v1.1.0 release, pypi distrib settings, remove
|
|
110
|
+
fastMCP version restriction, update to require python 3.10 or greater, add
|
|
111
|
+
pypi keyword and topic, settings, project urls for pypi, configure setuptools
|
|
112
|
+
for includes, excludes
|
|
113
|
+
- run_server.py script added
|
|
114
|
+
- .vscode/mcp.json uses run_server.py for debugging mcp server
|
|
115
|
+
- uv.lock add now that use uv, and uv lock --upgrade updated v0.12.5 from v0.12.4 of ruff
|
|
116
|
+
|
|
117
|
+
### Fixes for pyproject.toml for v1.1
|
|
118
|
+
- require python-alfresco-api >= 1.1.1 not 1.0.0 in dependencies
|
|
119
|
+
- have python 3.10 instead of 3.8 for tool.mypy, and py310 not py38 for tool.ruff and tool.black
|
|
120
|
+
|
|
121
|
+
### Example Code Updates for v1.1
|
|
122
|
+
- `examples: update transport examples for UV approach`
|
|
123
|
+
- `examples: enhance document lifecycle example`
|
|
124
|
+
- `examples: add UV-specific installation examples`
|
|
125
|
+
- `examples: update batch operations for improved performance`
|
|
126
|
+
- `examples: refactor error handling patterns`
|
|
127
|
+
|
|
128
|
+
### Requirements
|
|
129
|
+
- **Python Versions**: 3.10+ (unchanged)
|
|
130
|
+
- **python-alfresco-api**: >= 1.1.1 (updated requirement)
|
|
131
|
+
- **FastMCP**: Tested with v2.10.6
|
|
132
|
+
|
|
133
|
+
### Tested
|
|
134
|
+
- **Alfresco Versions**: Community 25.1 (tested), Enterprise (not tested in v1.1)
|
|
135
|
+
- **Operating Systems**:
|
|
136
|
+
- Windows (tested)
|
|
137
|
+
- macOS (needs testing)
|
|
138
|
+
- Linux (needs testing, note: no Claude Desktop support on Linux)
|
|
139
|
+
- **MCP Clients**:
|
|
140
|
+
- Claude Desktop (tested and validated)
|
|
141
|
+
- MCP Inspector (tested and validated)
|
|
142
|
+
- Cursor (configuration provided, not tested in v1.1)
|
|
143
|
+
- Claude Code (configuration provided, not tested in v1.1)
|
|
144
|
+
|
|
145
|
+
## [1.0.0] - 2024-06-24
|
|
146
|
+
|
|
147
|
+
### Added
|
|
148
|
+
- Initial FastMCP 2.0 server implementation
|
|
149
|
+
- 15 content management tools across search and core operations
|
|
150
|
+
- Full text search with wildcard support
|
|
151
|
+
- Advanced search using AFTS query language
|
|
152
|
+
- Metadata search with property-based queries
|
|
153
|
+
- CMIS SQL search capabilities
|
|
154
|
+
- Complete document lifecycle management (upload, download, checkout, checkin)
|
|
155
|
+
- Version management with major/minor version support
|
|
156
|
+
- Folder operations and repository browsing
|
|
157
|
+
- Property management for documents and folders
|
|
158
|
+
- Multiple transport protocols (STDIO, HTTP, SSE)
|
|
159
|
+
- Configuration via environment variables and .env files
|
|
160
|
+
- Claude Desktop integration with Windows and macOS configs
|
|
161
|
+
- MCP Inspector support for development testing
|
|
162
|
+
- Comprehensive documentation and examples
|
|
163
|
+
- Testing framework with unit and integration tests
|
|
164
|
+
- Error handling and recovery patterns
|
|
165
|
+
- Repository discovery and status reporting
|
|
166
|
+
|
|
167
|
+
### Technical Implementation
|
|
168
|
+
- python-alfresco-api integration for content services access
|
|
169
|
+
- Pydantic v2 models for type safety
|
|
170
|
+
- Async support for concurrent operations
|
|
171
|
+
- Connection pooling and authentication management
|
|
172
|
+
- Progress reporting and context logging
|
|
162
173
|
- Configuration validation and environment setup
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: python-alfresco-mcp-server
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: FastMCP 3 server for Alfresco Content Services integration
|
|
5
5
|
Project-URL: Homepage, https://github.com/stevereiner/python-alfresco-mcp-server
|
|
6
6
|
Project-URL: Repository, https://github.com/stevereiner/python-alfresco-mcp-server
|
|
@@ -27,7 +27,7 @@ Requires-Dist: fastmcp<4,>=3.4.5
|
|
|
27
27
|
Requires-Dist: httpx>=0.24.0
|
|
28
28
|
Requires-Dist: pydantic-settings>=2.0.0
|
|
29
29
|
Requires-Dist: pydantic>=2.0.0
|
|
30
|
-
Requires-Dist: python-alfresco-api>=1.2.
|
|
30
|
+
Requires-Dist: python-alfresco-api>=1.2.2
|
|
31
31
|
Requires-Dist: python-multipart>=0.0.6
|
|
32
32
|
Requires-Dist: pyyaml>=6.0
|
|
33
33
|
Provides-Extra: all
|
|
@@ -55,7 +55,7 @@ Requires-Dist: pytest-xdist>=3.0.0; extra == 'test'
|
|
|
55
55
|
Requires-Dist: pytest>=7.0.0; extra == 'test'
|
|
56
56
|
Description-Content-Type: text/markdown
|
|
57
57
|
|
|
58
|
-
# Python Alfresco MCP Server v1.
|
|
58
|
+
# Python Alfresco MCP Server v1.2 🚀
|
|
59
59
|
|
|
60
60
|
[](https://pypi.org/project/python-alfresco-mcp-server/)
|
|
61
61
|
[](https://pepy.tech/project/python-alfresco-mcp-server)
|
|
@@ -70,6 +70,15 @@ Built with [FastMCP 3](https://github.com/PrefectHQ/fastmcp).
|
|
|
70
70
|
Features complete documentation, examples, and
|
|
71
71
|
config for various MCP clients (Claude Desktop, MCP Inspector, references to configuring others).
|
|
72
72
|
|
|
73
|
+
## 🌟 What's New in v1.2
|
|
74
|
+
|
|
75
|
+
- **Alfresco authentication methods**: connect via **basic**, **ticket**, or **OAuth2/OIDC** (`ALFRESCO_AUTH_METHOD` + `ALFRESCO_OAUTH2_*`, backed by `python-alfresco-api` 1.2.1) — see [Authentication](#-authentication).
|
|
76
|
+
- **Optional MCP transport authentication**: secure the MCP server itself with an OAuth2 bearer token (`MCP_TRANSPORT_AUTH=true`), validated against your IdP's JWKS (HTTP/SSE transports; stdio unaffected).
|
|
77
|
+
- **FastMCP 3**: upgraded to `fastmcp>=3.4.5,<4` (transport auth uses `JWTVerifier`).
|
|
78
|
+
- **`download_document` custom folder**: optional `destination_dir` (default `~/Downloads`) — thanks [@jeremie-lesage](https://github.com/jeremie-lesage) ([#1](https://github.com/stevereiner/python-alfresco-mcp-server/pull/1)).
|
|
79
|
+
- **Packaging**: switched to the hatchling build backend.
|
|
80
|
+
- Requires **python-alfresco-api ≥ 1.2.1** (OAuth2/OIDC auth + OAuth2 service-account `displayName` fix).
|
|
81
|
+
|
|
73
82
|
## 🌟 What's New in v1.1
|
|
74
83
|
|
|
75
84
|
### **Modular Architecture & Enhanced Testing**
|
|
@@ -228,10 +237,15 @@ uv sync # Basic dependencies
|
|
|
228
237
|
uv sync --extra dev # With development tools
|
|
229
238
|
uv sync --extra test # With testing tools
|
|
230
239
|
uv sync --extra all # Everything
|
|
240
|
+
|
|
241
|
+
# Or an editable install into the active virtual environment (pip-style):
|
|
242
|
+
uv pip install -e .
|
|
231
243
|
```
|
|
232
244
|
|
|
233
245
|
### 4. Configure Alfresco Connection
|
|
234
246
|
|
|
247
|
+
> The examples below use HTTP **Basic** auth. Alfresco also supports **ticket** and **OAuth2/OIDC** (`ALFRESCO_AUTH_METHOD` + `ALFRESCO_OAUTH2_*`), and you can optionally secure the MCP transport with an OAuth2 bearer (`MCP_TRANSPORT_AUTH`) — see the [Authentication](#-authentication) section for all methods.
|
|
248
|
+
|
|
235
249
|
**Option 1: Environment Variables**
|
|
236
250
|
```bash
|
|
237
251
|
# Linux/Mac
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Python Alfresco MCP Server v1.
|
|
1
|
+
# Python Alfresco MCP Server v1.2 🚀
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/python-alfresco-mcp-server/)
|
|
4
4
|
[](https://pepy.tech/project/python-alfresco-mcp-server)
|
|
@@ -13,6 +13,15 @@ Built with [FastMCP 3](https://github.com/PrefectHQ/fastmcp).
|
|
|
13
13
|
Features complete documentation, examples, and
|
|
14
14
|
config for various MCP clients (Claude Desktop, MCP Inspector, references to configuring others).
|
|
15
15
|
|
|
16
|
+
## 🌟 What's New in v1.2
|
|
17
|
+
|
|
18
|
+
- **Alfresco authentication methods**: connect via **basic**, **ticket**, or **OAuth2/OIDC** (`ALFRESCO_AUTH_METHOD` + `ALFRESCO_OAUTH2_*`, backed by `python-alfresco-api` 1.2.1) — see [Authentication](#-authentication).
|
|
19
|
+
- **Optional MCP transport authentication**: secure the MCP server itself with an OAuth2 bearer token (`MCP_TRANSPORT_AUTH=true`), validated against your IdP's JWKS (HTTP/SSE transports; stdio unaffected).
|
|
20
|
+
- **FastMCP 3**: upgraded to `fastmcp>=3.4.5,<4` (transport auth uses `JWTVerifier`).
|
|
21
|
+
- **`download_document` custom folder**: optional `destination_dir` (default `~/Downloads`) — thanks [@jeremie-lesage](https://github.com/jeremie-lesage) ([#1](https://github.com/stevereiner/python-alfresco-mcp-server/pull/1)).
|
|
22
|
+
- **Packaging**: switched to the hatchling build backend.
|
|
23
|
+
- Requires **python-alfresco-api ≥ 1.2.1** (OAuth2/OIDC auth + OAuth2 service-account `displayName` fix).
|
|
24
|
+
|
|
16
25
|
## 🌟 What's New in v1.1
|
|
17
26
|
|
|
18
27
|
### **Modular Architecture & Enhanced Testing**
|
|
@@ -171,10 +180,15 @@ uv sync # Basic dependencies
|
|
|
171
180
|
uv sync --extra dev # With development tools
|
|
172
181
|
uv sync --extra test # With testing tools
|
|
173
182
|
uv sync --extra all # Everything
|
|
183
|
+
|
|
184
|
+
# Or an editable install into the active virtual environment (pip-style):
|
|
185
|
+
uv pip install -e .
|
|
174
186
|
```
|
|
175
187
|
|
|
176
188
|
### 4. Configure Alfresco Connection
|
|
177
189
|
|
|
190
|
+
> The examples below use HTTP **Basic** auth. Alfresco also supports **ticket** and **OAuth2/OIDC** (`ALFRESCO_AUTH_METHOD` + `ALFRESCO_OAUTH2_*`), and you can optionally secure the MCP transport with an OAuth2 bearer (`MCP_TRANSPORT_AUTH`) — see the [Authentication](#-authentication) section for all methods.
|
|
191
|
+
|
|
178
192
|
**Option 1: Environment Variables**
|
|
179
193
|
```bash
|
|
180
194
|
# Linux/Mac
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/alfresco_mcp_server/config.py
RENAMED
|
@@ -1,140 +1,146 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Configuration management for MCP Server for Alfresco.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
from typing import Optional
|
|
7
|
-
from pydantic import BaseModel, Field
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class AlfrescoConfig(BaseModel):
|
|
11
|
-
"""Configuration for MCP Server for Alfresco."""
|
|
12
|
-
|
|
13
|
-
# Alfresco server connection
|
|
14
|
-
alfresco_url: str = Field(
|
|
15
|
-
default_factory=lambda: os.getenv("ALFRESCO_URL", "http://localhost:8080"),
|
|
16
|
-
description="Alfresco server URL"
|
|
17
|
-
)
|
|
18
|
-
|
|
19
|
-
# Authentication method: basic | ticket | oauth2
|
|
20
|
-
auth_method: str = Field(
|
|
21
|
-
default_factory=lambda: os.getenv("ALFRESCO_AUTH_METHOD", "basic").lower(),
|
|
22
|
-
description="Alfresco auth method: basic | ticket | oauth2"
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
# Authentication (basic / ticket)
|
|
26
|
-
username: str = Field(
|
|
27
|
-
default_factory=lambda: os.getenv("ALFRESCO_USERNAME", "admin"),
|
|
28
|
-
description="Alfresco username"
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
password: str = Field(
|
|
32
|
-
default_factory=lambda: os.getenv("ALFRESCO_PASSWORD", "admin"),
|
|
33
|
-
description="Alfresco password"
|
|
34
|
-
)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
)
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
default_factory=lambda: os.getenv("
|
|
69
|
-
description="
|
|
70
|
-
)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
description="
|
|
81
|
-
)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
description="
|
|
92
|
-
)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
default_factory=lambda: os.getenv("
|
|
107
|
-
description="
|
|
108
|
-
)
|
|
109
|
-
|
|
110
|
-
#
|
|
111
|
-
|
|
112
|
-
default_factory=lambda:
|
|
113
|
-
description="
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
def
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
1
|
+
"""
|
|
2
|
+
Configuration management for MCP Server for Alfresco.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Optional
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AlfrescoConfig(BaseModel):
|
|
11
|
+
"""Configuration for MCP Server for Alfresco."""
|
|
12
|
+
|
|
13
|
+
# Alfresco server connection
|
|
14
|
+
alfresco_url: str = Field(
|
|
15
|
+
default_factory=lambda: os.getenv("ALFRESCO_URL", "http://localhost:8080"),
|
|
16
|
+
description="Alfresco server URL"
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
# Authentication method: basic | ticket | oauth2
|
|
20
|
+
auth_method: str = Field(
|
|
21
|
+
default_factory=lambda: os.getenv("ALFRESCO_AUTH_METHOD", "basic").lower(),
|
|
22
|
+
description="Alfresco auth method: basic | ticket | oauth2"
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
# Authentication (basic / ticket)
|
|
26
|
+
username: str = Field(
|
|
27
|
+
default_factory=lambda: os.getenv("ALFRESCO_USERNAME", "admin"),
|
|
28
|
+
description="Alfresco username"
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
password: str = Field(
|
|
32
|
+
default_factory=lambda: os.getenv("ALFRESCO_PASSWORD", "admin"),
|
|
33
|
+
description="Alfresco password"
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
ticket: Optional[str] = Field(
|
|
37
|
+
default_factory=lambda: os.getenv("ALFRESCO_TICKET"),
|
|
38
|
+
description="Pre-obtained Alfresco login ticket; with auth_method=ticket it is "
|
|
39
|
+
"used as-is instead of being fetched from username/password"
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# OAuth2 (auth_method=oauth2) — Alfresco Identity Service / any OIDC IdP
|
|
43
|
+
oauth2_client_id: Optional[str] = Field(
|
|
44
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_CLIENT_ID"),
|
|
45
|
+
description="OAuth2 client id"
|
|
46
|
+
)
|
|
47
|
+
oauth2_client_secret: Optional[str] = Field(
|
|
48
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_CLIENT_SECRET"),
|
|
49
|
+
description="OAuth2 client secret"
|
|
50
|
+
)
|
|
51
|
+
oauth2_token_endpoint: Optional[str] = Field(
|
|
52
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_TOKEN_ENDPOINT"),
|
|
53
|
+
description="OAuth2 token endpoint URL"
|
|
54
|
+
)
|
|
55
|
+
oauth2_grant_type: str = Field(
|
|
56
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_GRANT_TYPE", "client_credentials"),
|
|
57
|
+
description="OAuth2 grant type: client_credentials | refresh_token"
|
|
58
|
+
)
|
|
59
|
+
oauth2_scope: Optional[str] = Field(
|
|
60
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_SCOPE"),
|
|
61
|
+
description="OAuth2 scope"
|
|
62
|
+
)
|
|
63
|
+
oauth2_access_token: Optional[str] = Field(
|
|
64
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_ACCESS_TOKEN"),
|
|
65
|
+
description="Pre-obtained OAuth2 access token (optional)"
|
|
66
|
+
)
|
|
67
|
+
oauth2_refresh_token: Optional[str] = Field(
|
|
68
|
+
default_factory=lambda: os.getenv("ALFRESCO_OAUTH2_REFRESH_TOKEN"),
|
|
69
|
+
description="OAuth2 refresh token (optional)"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# Connection settings
|
|
73
|
+
verify_ssl: bool = Field(
|
|
74
|
+
default_factory=lambda: os.getenv("ALFRESCO_VERIFY_SSL", "false").lower() == "true",
|
|
75
|
+
description="Verify SSL certificates"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
timeout: int = Field(
|
|
79
|
+
default_factory=lambda: int(os.getenv("ALFRESCO_TIMEOUT", "30")),
|
|
80
|
+
description="Request timeout in seconds"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
# MCP Server settings
|
|
84
|
+
server_name: str = Field(
|
|
85
|
+
default="python-alfresco-mcp-server",
|
|
86
|
+
description="MCP server name"
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
server_version: str = Field(
|
|
90
|
+
default="1.0.0",
|
|
91
|
+
description="MCP server version"
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# FastAPI settings (for HTTP transport)
|
|
95
|
+
fastapi_host: str = Field(
|
|
96
|
+
default_factory=lambda: os.getenv("FASTAPI_HOST", "localhost"),
|
|
97
|
+
description="FastAPI host"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
fastapi_port: int = Field(
|
|
101
|
+
default_factory=lambda: int(os.getenv("FASTAPI_PORT", "8000")),
|
|
102
|
+
description="FastAPI port"
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
fastapi_prefix: str = Field(
|
|
106
|
+
default_factory=lambda: os.getenv("FASTAPI_PREFIX", "/mcp"),
|
|
107
|
+
description="FastAPI URL prefix"
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
# Logging
|
|
111
|
+
log_level: str = Field(
|
|
112
|
+
default_factory=lambda: os.getenv("LOG_LEVEL", "INFO"),
|
|
113
|
+
description="Logging level"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
# Content settings
|
|
117
|
+
max_file_size: int = Field(
|
|
118
|
+
default_factory=lambda: int(os.getenv("MAX_FILE_SIZE", "100000000")), # 100MB
|
|
119
|
+
description="Maximum file size for uploads in bytes"
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
allowed_extensions: list[str] = Field(
|
|
123
|
+
default_factory=lambda: [
|
|
124
|
+
".txt", ".pdf", ".doc", ".docx", ".xls", ".xlsx",
|
|
125
|
+
".ppt", ".pptx", ".jpg", ".jpeg", ".png", ".gif",
|
|
126
|
+
".zip", ".xml", ".json", ".csv"
|
|
127
|
+
],
|
|
128
|
+
description="Allowed file extensions for uploads"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
class Config:
|
|
132
|
+
env_prefix = "ALFRESCO_"
|
|
133
|
+
case_sensitive = False
|
|
134
|
+
|
|
135
|
+
def model_post_init(self, __context) -> None:
|
|
136
|
+
"""Normalize URLs after initialization."""
|
|
137
|
+
if self.alfresco_url.endswith("/"):
|
|
138
|
+
self.alfresco_url = self.alfresco_url.rstrip("/")
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def load_config() -> AlfrescoConfig:
|
|
142
|
+
"""Load configuration from environment variables and defaults."""
|
|
143
|
+
return AlfrescoConfig()
|
|
144
|
+
|
|
145
|
+
# Global config instance for import
|
|
140
146
|
config = load_config()
|
|
@@ -20,6 +20,9 @@ def get_alfresco_config() -> dict:
|
|
|
20
20
|
'auth_method': os.getenv('ALFRESCO_AUTH_METHOD', 'basic').lower(), # basic | ticket | oauth2
|
|
21
21
|
'username': os.getenv('ALFRESCO_USERNAME', 'admin'),
|
|
22
22
|
'password': os.getenv('ALFRESCO_PASSWORD', 'admin'),
|
|
23
|
+
# A login ticket obtained elsewhere. With auth_method=ticket this replaces
|
|
24
|
+
# username/password entirely instead of being fetched from them.
|
|
25
|
+
'ticket': os.getenv('ALFRESCO_TICKET', ''),
|
|
23
26
|
'verify_ssl': os.getenv('ALFRESCO_VERIFY_SSL', 'false').lower() == 'true',
|
|
24
27
|
'timeout': int(os.getenv('ALFRESCO_TIMEOUT', '30')),
|
|
25
28
|
'oauth2': {
|
|
@@ -38,14 +41,23 @@ def _build_auth_util(config: dict):
|
|
|
38
41
|
"""Build a python-alfresco-api auth util for the configured auth_method.
|
|
39
42
|
|
|
40
43
|
Returns None for basic auth (ClientFactory builds its own from username/password).
|
|
41
|
-
- ticket:
|
|
44
|
+
- ticket: either a caller-supplied login ticket (ALFRESCO_TICKET) used as-is, or one
|
|
45
|
+
TicketAuthUtil self-fetches from username/password. Either way the wire format is
|
|
46
|
+
Authorization: Basic base64(ticket).
|
|
42
47
|
- oauth2: OAuth2AuthUtil (client_credentials/refresh, or a pre-obtained access_token → Bearer),
|
|
43
48
|
e.g. against Alfresco Identity Service / Keycloak.
|
|
44
49
|
"""
|
|
45
50
|
method = config.get('auth_method', 'basic')
|
|
46
51
|
if method == 'ticket':
|
|
47
52
|
from python_alfresco_api.auth_util import TicketAuthUtil
|
|
48
|
-
|
|
53
|
+
ticket = config.get('ticket')
|
|
54
|
+
if ticket:
|
|
55
|
+
logger.info(">> Using Alfresco ticket authentication (caller-supplied ticket)")
|
|
56
|
+
return TicketAuthUtil(
|
|
57
|
+
base_url=config['alfresco_url'], ticket=ticket,
|
|
58
|
+
verify_ssl=config['verify_ssl'], timeout=config['timeout'],
|
|
59
|
+
)
|
|
60
|
+
logger.info(">> Using Alfresco ticket authentication (acquired from username/password)")
|
|
49
61
|
return TicketAuthUtil(
|
|
50
62
|
config['username'], config['password'],
|
|
51
63
|
base_url=config['alfresco_url'],
|
|
@@ -35,7 +35,7 @@ exclude = [
|
|
|
35
35
|
|
|
36
36
|
[project]
|
|
37
37
|
name = "python-alfresco-mcp-server"
|
|
38
|
-
version = "1.2.
|
|
38
|
+
version = "1.2.1"
|
|
39
39
|
description = "FastMCP 3 server for Alfresco Content Services integration"
|
|
40
40
|
authors = [{name = "Steve Reiner", email = "example@example.com"}]
|
|
41
41
|
license = "Apache-2.0"
|
|
@@ -63,7 +63,7 @@ dependencies = [
|
|
|
63
63
|
"fastmcp>=3.4.5,<4",
|
|
64
64
|
|
|
65
65
|
# Alfresco integration
|
|
66
|
-
"python-alfresco-api>=1.2.
|
|
66
|
+
"python-alfresco-api>=1.2.2",
|
|
67
67
|
|
|
68
68
|
# Configuration and utilities
|
|
69
69
|
"pydantic>=2.0.0",
|
|
@@ -1,59 +1,64 @@
|
|
|
1
|
-
# Alfresco MCP Server Configuration
|
|
2
|
-
# Copy this file to .env and customize for your environment
|
|
3
|
-
# The .env file will be ignored by git for security
|
|
4
|
-
|
|
5
|
-
# === REQUIRED: Alfresco Connection ===
|
|
6
|
-
ALFRESCO_URL=http://localhost:8080
|
|
7
|
-
|
|
8
|
-
# === Authentication ===
|
|
9
|
-
# ALFRESCO_AUTH_METHOD: basic | ticket | oauth2 (default: basic)
|
|
10
|
-
# basic = HTTP Basic (username/password below)
|
|
11
|
-
# ticket = Alfresco login ticket
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
-
#
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
#
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
|
|
51
|
-
#
|
|
52
|
-
#
|
|
53
|
-
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
#
|
|
57
|
-
#
|
|
58
|
-
|
|
1
|
+
# Alfresco MCP Server Configuration
|
|
2
|
+
# Copy this file to .env and customize for your environment
|
|
3
|
+
# The .env file will be ignored by git for security
|
|
4
|
+
|
|
5
|
+
# === REQUIRED: Alfresco Connection ===
|
|
6
|
+
ALFRESCO_URL=http://localhost:8080
|
|
7
|
+
|
|
8
|
+
# === Authentication ===
|
|
9
|
+
# ALFRESCO_AUTH_METHOD: basic | ticket | oauth2 (default: basic)
|
|
10
|
+
# basic = HTTP Basic (username/password below)
|
|
11
|
+
# ticket = Alfresco login ticket, sent as Authorization: Basic base64(ticket).
|
|
12
|
+
# Either set ALFRESCO_TICKET to a ticket you already have (no username or
|
|
13
|
+
# password needed at all), or leave it empty and a ticket is fetched from the
|
|
14
|
+
# username/password below so the password isn't sent on every request.
|
|
15
|
+
# oauth2 = OIDC Bearer token via Alfresco Identity Service / Keycloak (see OAuth2 block)
|
|
16
|
+
ALFRESCO_AUTH_METHOD=basic
|
|
17
|
+
ALFRESCO_USERNAME=admin
|
|
18
|
+
ALFRESCO_PASSWORD=admin
|
|
19
|
+
# A pre-obtained login ticket (only used when ALFRESCO_AUTH_METHOD=ticket). Set this and
|
|
20
|
+
# username/password are ignored; it is never re-fetched, so it stops working when it expires.
|
|
21
|
+
#ALFRESCO_TICKET=TICKET_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
22
|
+
|
|
23
|
+
# === OPTIONAL: OAuth2 (only when ALFRESCO_AUTH_METHOD=oauth2) ===
|
|
24
|
+
# Requires Alfresco's identity-service subsystem configured against an OIDC IdP (Keycloak).
|
|
25
|
+
# Either client_credentials (client id+secret+token endpoint) OR a pre-obtained access token.
|
|
26
|
+
#ALFRESCO_OAUTH2_CLIENT_ID=flexible-graphrag
|
|
27
|
+
#ALFRESCO_OAUTH2_CLIENT_SECRET=flexible-graphrag-secret
|
|
28
|
+
#ALFRESCO_OAUTH2_TOKEN_ENDPOINT=http://localhost:8091/realms/alfresco/protocol/openid-connect/token
|
|
29
|
+
#ALFRESCO_OAUTH2_GRANT_TYPE=client_credentials
|
|
30
|
+
#ALFRESCO_OAUTH2_SCOPE=
|
|
31
|
+
#ALFRESCO_OAUTH2_ACCESS_TOKEN=
|
|
32
|
+
#ALFRESCO_OAUTH2_REFRESH_TOKEN=
|
|
33
|
+
|
|
34
|
+
# === OPTIONAL: Connection Settings ===
|
|
35
|
+
ALFRESCO_VERIFY_SSL=false
|
|
36
|
+
ALFRESCO_TIMEOUT=30
|
|
37
|
+
|
|
38
|
+
# === OPTIONAL: Server Settings ===
|
|
39
|
+
LOG_LEVEL=INFO
|
|
40
|
+
MAX_FILE_SIZE=100000000
|
|
41
|
+
|
|
42
|
+
# === OPTIONAL: HTTP Transport Settings ===
|
|
43
|
+
FASTAPI_HOST=localhost
|
|
44
|
+
FASTAPI_PORT=8000
|
|
45
|
+
|
|
46
|
+
# === OPTIONAL: MCP Transport Authentication (secures the MCP server itself) ===
|
|
47
|
+
# Distinct from ALFRESCO_AUTH_METHOD (which is how the server authenticates TO Alfresco).
|
|
48
|
+
# When enabled, HTTP/SSE clients (incl. MCP Inspector) must send Authorization: Bearer <token>.
|
|
49
|
+
# stdio transport ignores this. RS256 bearer tokens are validated against the IdP's JWKS.
|
|
50
|
+
MCP_TRANSPORT_AUTH=false
|
|
51
|
+
# JWKS endpoint of your OIDC IdP (default = local Keycloak realm used for Alfresco identity-service)
|
|
52
|
+
#MCP_AUTH_JWKS_URI=http://host.docker.internal:8091/realms/alfresco/protocol/openid-connect/certs
|
|
53
|
+
# Optional strict issuer check. NOTE: the MCP SDK requires an HTTPS issuer URL (localhost excepted),
|
|
54
|
+
# so leave unset for a local http Keycloak — the JWKS signature check still gates access.
|
|
55
|
+
#MCP_AUTH_ISSUER=https://<your-idp>/realms/<realm>
|
|
56
|
+
# Optional audience check (unset = don't validate aud)
|
|
57
|
+
#MCP_AUTH_AUDIENCE=
|
|
58
|
+
|
|
59
|
+
# === NOTES ===
|
|
60
|
+
# - Environment variables take precedence over defaults
|
|
61
|
+
# - python-alfresco-api may have its own configuration (check its docs)
|
|
62
|
+
# - For production, use environment variables or secure secret management
|
|
63
|
+
# - Boolean values: true/false (case insensitive)
|
|
59
64
|
# - File size in bytes (100000000 = 100MB)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/claude_desktop_setup.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/client_configurations.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/configuration_guide.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/install_with_pip_pipx.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/mcp_inspector_setup.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/quick_start_guide.md
RENAMED
|
File without changes
|
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/docs/troubleshooting.md
RENAMED
|
File without changes
|
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/batch_operations.py
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/document_lifecycle.py
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/error_handling.py
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/examples_summary.md
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/quick_start.py
RENAMED
|
File without changes
|
{python_alfresco_mcp_server-1.2.0 → python_alfresco_mcp_server-1.2.1}/examples/transport_examples.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|