osm-edit-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 (45) hide show
  1. osm_edit_mcp-0.2.0/.gitignore +198 -0
  2. osm_edit_mcp-0.2.0/LICENSE +21 -0
  3. osm_edit_mcp-0.2.0/PKG-INFO +327 -0
  4. osm_edit_mcp-0.2.0/README.md +276 -0
  5. osm_edit_mcp-0.2.0/lhm.plugin.json +1482 -0
  6. osm_edit_mcp-0.2.0/oauth_auth.py +478 -0
  7. osm_edit_mcp-0.2.0/pyproject.toml +136 -0
  8. osm_edit_mcp-0.2.0/scripts/security_audit.py +410 -0
  9. osm_edit_mcp-0.2.0/src/osm_edit_mcp/__init__.py +13 -0
  10. osm_edit_mcp-0.2.0/src/osm_edit_mcp/_version.py +18 -0
  11. osm_edit_mcp-0.2.0/src/osm_edit_mcp/app.py +20 -0
  12. osm_edit_mcp-0.2.0/src/osm_edit_mcp/auth.py +97 -0
  13. osm_edit_mcp-0.2.0/src/osm_edit_mcp/config.py +332 -0
  14. osm_edit_mcp-0.2.0/src/osm_edit_mcp/edit_tools.py +258 -0
  15. osm_edit_mcp-0.2.0/src/osm_edit_mcp/http_client.py +67 -0
  16. osm_edit_mcp-0.2.0/src/osm_edit_mcp/natural_language.py +332 -0
  17. osm_edit_mcp-0.2.0/src/osm_edit_mcp/prompts.py +89 -0
  18. osm_edit_mcp-0.2.0/src/osm_edit_mcp/proposal_store.py +375 -0
  19. osm_edit_mcp-0.2.0/src/osm_edit_mcp/read_tools.py +1187 -0
  20. osm_edit_mcp-0.2.0/src/osm_edit_mcp/server.py +187 -0
  21. osm_edit_mcp-0.2.0/src/osm_edit_mcp/token_store.py +112 -0
  22. osm_edit_mcp-0.2.0/src/osm_edit_mcp/track_tools.py +2728 -0
  23. osm_edit_mcp-0.2.0/src/osm_edit_mcp/valhalla.py +161 -0
  24. osm_edit_mcp-0.2.0/src/osm_edit_mcp/write_tools.py +1104 -0
  25. osm_edit_mcp-0.2.0/src/osm_edit_mcp/xml_models.py +94 -0
  26. osm_edit_mcp-0.2.0/tests/__init__.py +1 -0
  27. osm_edit_mcp-0.2.0/tests/conftest.py +61 -0
  28. osm_edit_mcp-0.2.0/tests/test_auth_safety.py +155 -0
  29. osm_edit_mcp-0.2.0/tests/test_config.py +280 -0
  30. osm_edit_mcp-0.2.0/tests/test_edit_tools.py +85 -0
  31. osm_edit_mcp-0.2.0/tests/test_escaping.py +81 -0
  32. osm_edit_mcp-0.2.0/tests/test_lobehub_manifest.py +69 -0
  33. osm_edit_mcp-0.2.0/tests/test_module_boundaries.py +33 -0
  34. osm_edit_mcp-0.2.0/tests/test_oauth_flow.py +209 -0
  35. osm_edit_mcp-0.2.0/tests/test_package_metadata.py +55 -0
  36. osm_edit_mcp-0.2.0/tests/test_prompts.py +69 -0
  37. osm_edit_mcp-0.2.0/tests/test_proposal_store.py +88 -0
  38. osm_edit_mcp-0.2.0/tests/test_read_tools.py +141 -0
  39. osm_edit_mcp-0.2.0/tests/test_release_artifacts.py +74 -0
  40. osm_edit_mcp-0.2.0/tests/test_security_audit.py +31 -0
  41. osm_edit_mcp-0.2.0/tests/test_track_tools.py +1136 -0
  42. osm_edit_mcp-0.2.0/tests/test_valhalla.py +90 -0
  43. osm_edit_mcp-0.2.0/tests/test_way_writes.py +92 -0
  44. osm_edit_mcp-0.2.0/tests/test_xml_parser.py +124 -0
  45. osm_edit_mcp-0.2.0/web_server.py +330 -0
@@ -0,0 +1,198 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ pip-wheel-metadata/
24
+ share/python-wheels/
25
+ *.egg-info/
26
+ .installed.cfg
27
+ *.egg
28
+ MANIFEST
29
+
30
+ # PyInstaller
31
+ # Usually these files are written by a python script from a template
32
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
33
+ *.manifest
34
+ *.spec
35
+
36
+ # Installer logs
37
+ pip-log.txt
38
+ pip-delete-this-directory.txt
39
+
40
+ # Unit test / coverage reports
41
+ htmlcov/
42
+ .tox/
43
+ .nox/
44
+ .coverage
45
+ .coverage.*
46
+ .cache
47
+ nosetests.xml
48
+ coverage.xml
49
+ *.cover
50
+ *.py,cover
51
+ .hypothesis/
52
+ .pytest_cache/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ target/
76
+
77
+ # Jupyter Notebook
78
+ .ipynb_checkpoints
79
+
80
+ # IPython
81
+ profile_default/
82
+ ipython_config.py
83
+
84
+ # pyenv
85
+ .python-version
86
+
87
+ # pipenv
88
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
90
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
91
+ # install all needed dependencies.
92
+ #Pipfile.lock
93
+
94
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95
+ __pypackages__/
96
+
97
+ # Celery stuff
98
+ celerybeat-schedule
99
+ celerybeat.pid
100
+
101
+ # SageMath parsed files
102
+ *.sage.py
103
+
104
+ # Environments
105
+ .env
106
+ .venv
107
+ env/
108
+ venv/
109
+ ENV/
110
+ env.bak/
111
+ venv.bak/
112
+
113
+ # Spyder project settings
114
+ .spyderproject
115
+ .spyproject
116
+
117
+ # Rope project settings
118
+ .ropeproject
119
+
120
+ # mkdocs documentation
121
+ /site
122
+
123
+ # mypy
124
+ .mypy_cache/
125
+ .dmypy.json
126
+ dmypy.json
127
+
128
+ # Pyre type checker
129
+ .pyre/
130
+
131
+ # OAuth credentials and tokens
132
+ oauth_tokens.json
133
+ .oauth_cache/
134
+
135
+ # Local development files
136
+ .env.local
137
+ .env.development
138
+ .env.production
139
+ .claude/settings.local.json
140
+
141
+ # IDE/Editor files
142
+ .vscode/
143
+ .idea/
144
+ *.swp
145
+ *.swo
146
+ *~
147
+
148
+ # macOS
149
+ .DS_Store
150
+ .AppleDouble
151
+ .LSOverride
152
+
153
+ # Windows
154
+ Thumbs.db
155
+ ehthumbs.db
156
+ Desktop.ini
157
+
158
+ # Log files
159
+ *.log
160
+ logs/
161
+
162
+ # Cache directories
163
+ .cache/
164
+ cache/
165
+
166
+ # Temporary files
167
+ tmp/
168
+ temp/
169
+ *.tmp
170
+
171
+ # Local GPX survey inputs can contain sensitive location history. Keep the
172
+ # directory available, but never commit its contents.
173
+ tracks/*
174
+ !tracks/.gitkeep
175
+
176
+ # Testing output
177
+ test-results/
178
+ .coverage.*
179
+ test_report.json
180
+ test_results.log
181
+
182
+ # OAuth tokens
183
+ .osm_token_dev.json
184
+ .osm_token_prod.json
185
+ .osm_token_*.json
186
+
187
+ # Security and keys
188
+ *.key
189
+ *.pem
190
+ *.p12
191
+ *.pfx
192
+ *.crt
193
+ *.cer
194
+ private_key*
195
+ secret_key*
196
+
197
+ # Security audit reports
198
+ security_audit_report.json
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 pk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,327 @@
1
+ Metadata-Version: 2.5
2
+ Name: osm-edit-mcp
3
+ Version: 0.2.0
4
+ Summary: Review-first MCP server for previewed, version-checked OpenStreetMap road edits from local GPX surveys
5
+ Project-URL: Homepage, https://github.com/skywinder/osm-edit-mcp
6
+ Project-URL: Repository, https://github.com/skywinder/osm-edit-mcp
7
+ Project-URL: Issues, https://github.com/skywinder/osm-edit-mcp/issues
8
+ Author: skywinder
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: ai,assistant,fastmcp,geospatial,gis,gpx,map-editing,mcp,model-context-protocol,openstreetmap,osm
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: GIS
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: anyio<5,>=4.9.0
23
+ Requires-Dist: authlib<2,>=1.8.0
24
+ Requires-Dist: cryptography<51,>=50.0.1
25
+ Requires-Dist: defusedxml<1,>=0.7.1
26
+ Requires-Dist: fastapi<1,>=0.141.1
27
+ Requires-Dist: httpx<1,>=0.28.1
28
+ Requires-Dist: keyring<26,>=25.7.0
29
+ Requires-Dist: mcp<2,>=1.10
30
+ Requires-Dist: pydantic-settings<3,>=2.10.0
31
+ Requires-Dist: pydantic<3,>=2.11.0
32
+ Requires-Dist: python-dotenv<2,>=1.2.3
33
+ Requires-Dist: python-multipart<1,>=0.0.32
34
+ Requires-Dist: uvicorn[standard]<1,>=0.52.4
35
+ Provides-Extra: dev
36
+ Requires-Dist: bandit[toml]>=1.8.0; extra == 'dev'
37
+ Requires-Dist: black>=23.0.0; extra == 'dev'
38
+ Requires-Dist: flake8>=6.0.0; extra == 'dev'
39
+ Requires-Dist: hatchling<2,>=1.27; extra == 'dev'
40
+ Requires-Dist: isort>=5.0.0; extra == 'dev'
41
+ Requires-Dist: mypy>=1.0.0; extra == 'dev'
42
+ Requires-Dist: pip-audit>=2.9.0; extra == 'dev'
43
+ Requires-Dist: pre-commit>=3.0.0; extra == 'dev'
44
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
45
+ Requires-Dist: pytest-cov>=4.0.0; extra == 'dev'
46
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
47
+ Requires-Dist: tomli>=2.0.0; (python_version < '3.11') and extra == 'dev'
48
+ Requires-Dist: twine>=6.0.0; extra == 'dev'
49
+ Requires-Dist: types-defusedxml>=0.7.0.20260504; extra == 'dev'
50
+ Description-Content-Type: text/markdown
51
+
52
+ # OSM Edit MCP
53
+
54
+ [![MCP Badge](https://lobehub.com/badge/mcp/pk-osm-edit-mcp)](https://lobehub.com/mcp/pk-osm-edit-mcp)
55
+
56
+ A review-first Model Context Protocol server for inspecting OpenStreetMap and
57
+ turning a selected part of a local GPX survey into a previewed road-edit proposal.
58
+
59
+ > **Alpha software.** It does not autonomously edit OpenStreetMap. The normal
60
+ > profile can inspect data and prepare proposals, but a production write requires
61
+ > an exact preview, a separate MCP host confirmation of its SHA-256 digest, fresh
62
+ > OSM identity/version checks, and one atomic `osmChange` upload.
63
+
64
+ ## Why this server
65
+
66
+ Most OpenStreetMap MCP servers focus on search, geocoding, or routing. OSM Edit
67
+ MCP focuses on the risky last mile: helping a mapper review a narrowly selected
68
+ survey before any road geometry reaches OSM.
69
+
70
+ ```text
71
+ local GPX → selected segment → current/proposed preview
72
+ → exact digest confirmation → OSM changeset
73
+ ```
74
+
75
+ The safe profile can:
76
+
77
+ - read OSM nodes, ways, relations, changesets, and small map areas;
78
+ - analyze GPX 1.0/1.1 locally without publishing the trace;
79
+ - select one continuous range by index, time, or endpoint coordinates;
80
+ - optionally compare it with local Valhalla map matching;
81
+ - suggest nearby `highway=*` ways without choosing one automatically;
82
+ - preview a new road or a selected contiguous chain of existing ways;
83
+ - expose current/proposed GeoJSON through an MCP `ui://` resource;
84
+ - apply one confirmed proposal atomically and return OSM links and versions;
85
+ - re-fetch a completed edit for later verification.
86
+
87
+ It does **not** upload GPS traces, infer crossings, delete roads, restructure
88
+ relations, copy geometry from restricted providers, or authorize a production
89
+ edit from natural-language consent alone.
90
+
91
+ ## Quick start
92
+
93
+ Requirements:
94
+
95
+ - Python 3.10 or newer;
96
+ - [uv](https://docs.astral.sh/uv/);
97
+ - an MCP host that supports local stdio servers.
98
+
99
+ Add this server to a JSON-based MCP host:
100
+
101
+ ```json
102
+ {
103
+ "mcpServers": {
104
+ "osm-edit": {
105
+ "command": "uvx",
106
+ "args": ["osm-edit-mcp"],
107
+ "env": {
108
+ "OSM_USE_DEV_API": "true",
109
+ "OSM_WRITE_PROFILE": "safe"
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ Restart the host, then call `get_server_info` or `get_edit_capabilities`.
117
+ The first `uvx` launch installs the released package in an isolated environment.
118
+ The development API is the default in this example; no OAuth credentials are
119
+ needed for read-only inspection.
120
+
121
+ For client-specific formats, including Codex TOML, see
122
+ [MCP client setup](docs/MCP_CLIENT_SETUP.md). A real read-only protocol smoke
123
+ client is available at [examples/quick_start.py](examples/quick_start.py).
124
+
125
+ MCP hosts can also start the guided `review_gpx_road_edit` prompt with a local
126
+ GPX path and edit goal. It requires explicit segment and target choices, builds
127
+ a non-writing preview, and stops at review of the complete proposal digest. It
128
+ never calls `apply_osm_edit`.
129
+
130
+ ## Review workflow
131
+
132
+ Keep private tracks outside the repository. Set `OSM_TRACK_IMPORT_DIR` to a
133
+ directory you control, or provide inline GPX XML. Files are limited to 10 MiB
134
+ and 100,000 raw points; path traversal and symlink escapes are rejected.
135
+
136
+ ### 1. Analyze the track
137
+
138
+ ```text
139
+ analyze_gpx_track(gpx_path="survey.gpx")
140
+ ```
141
+
142
+ The result identifies stable track/segment IDs, bounds, distance, timestamps,
143
+ and discontinuities. Separate GPX segments are never joined implicitly.
144
+
145
+ ### 2. Select only the surveyed section
146
+
147
+ ```text
148
+ create_track_selection(
149
+ track_id="<track_id>",
150
+ segment_id="trk-0-seg-0",
151
+ start_point_index=1240,
152
+ end_point_index=1395
153
+ )
154
+ ```
155
+
156
+ Timestamp and endpoint-coordinate selection are also supported. Review the
157
+ returned `preview_uri` or its GeoJSON fallback.
158
+
159
+ ### 3. Compare with current OSM
160
+
161
+ ```text
162
+ match_track_selection(selection_id="<selection_id>", costing="auto")
163
+ suggest_track_road_candidates(selection_id="<selection_id>")
164
+ ```
165
+
166
+ Valhalla output is diagnostic only. Candidate discovery never selects the target
167
+ way on the mapper's behalf.
168
+
169
+ ### 4. Build a non-writing preview
170
+
171
+ Track analysis, segment selection, and the selection preview work without OAuth.
172
+ `preview_track_road_edit` still requires an authenticated OSM identity because
173
+ the proposal is bound to that exact account and API target, even though this
174
+ step does not write to OSM.
175
+
176
+ For a new road:
177
+
178
+ ```text
179
+ preview_track_road_edit(
180
+ selection_id="<selection_id>",
181
+ action="create",
182
+ tags={"highway":"residential"},
183
+ changeset_comment="Add surveyed residential road",
184
+ changeset_source="survey",
185
+ evidence_kind="survey_gpx"
186
+ )
187
+ ```
188
+
189
+ For an existing contiguous chain:
190
+
191
+ ```text
192
+ preview_track_road_edit(
193
+ selection_id="<selection_id>",
194
+ action="update",
195
+ target_way_ids=[123456, 123457],
196
+ changeset_comment="Realign road from local survey",
197
+ changeset_source="survey",
198
+ evidence_kind="survey_gpx"
199
+ )
200
+ ```
201
+
202
+ Review the current/proposed GeoJSON, exact operations and tags, preserved nodes,
203
+ endpoint connections, warnings, blocking issues, API target, expiry, and
204
+ `proposal_digest`. Ambiguous topology is reported rather than invented.
205
+
206
+ ### 5. Confirm and apply
207
+
208
+ `apply_osm_edit` accepts the exact proposal ID and digest. In production, the
209
+ MCP host must display a separate elicitation request for that digest. Apply then
210
+ checks the live OSM account, `write_api` permission, referenced versions, and
211
+ affected highways before sending one transactional upload.
212
+
213
+ A network failure after an upload starts becomes `RECONCILE_REQUIRED`; the
214
+ server does not blindly retry an ambiguous write.
215
+
216
+ ### 6. Verify
217
+
218
+ ```text
219
+ verify_osm_edit(proposal_id="<proposal_id>")
220
+ list_edit_proposals(status="APPLIED")
221
+ ```
222
+
223
+ ## Safety model
224
+
225
+ The normal `safe` profile enforces:
226
+
227
+ 1. Exact, expiring proposals stored in a local SQLite state machine.
228
+ 2. Atomic proposal claims that block concurrent or repeated upload.
229
+ 3. API-target, account, permission, OSM-version, and content binding.
230
+ 4. MCP elicitation bound to the proposal SHA-256 for production.
231
+ 5. One transactional `osmChange` upload for creates and modifications.
232
+ 6. Durable receipts and explicit reconciliation after ambiguous failures.
233
+ 7. No registration of raw direct-write or natural-language write tools.
234
+
235
+ Raw write tools are available only in the explicit `expert` profile while
236
+ targeting the OSM development API.
237
+
238
+ GPX accuracy is not ground truth. Review every proposal against independent,
239
+ permitted evidence and local knowledge. Follow OpenStreetMap's mapping,
240
+ licensing, import, and automated-edit policies; systematic edits may require
241
+ community discussion even when this software requires per-proposal review.
242
+
243
+ ## OAuth and production use
244
+
245
+ The package quick start is intentionally safe for inspection. Production setup
246
+ is an advanced operator workflow:
247
+
248
+ 1. Register separate development and production OAuth applications with only
249
+ `read_prefs` and `write_api`.
250
+ 2. From an existing source checkout, create a private `.env`, configure the
251
+ development application, then authenticate it:
252
+
253
+ ```bash
254
+ install -m 600 .env.example .env
255
+ uv sync --locked --extra dev
256
+ export OSM_EDIT_MCP_ENV_FILE="$PWD/.env"
257
+ uv run python oauth_auth.py --dev
258
+ ```
259
+
260
+ 3. Complete representative create/update preview and apply acceptance against
261
+ the OSM development API.
262
+ 4. Only after that development acceptance, configure and authenticate the
263
+ separate production app:
264
+
265
+ ```bash
266
+ export OSM_EDIT_MCP_ENV_FILE="$PWD/.env"
267
+ uv run python oauth_auth.py --prod
268
+ ```
269
+
270
+ Tokens are keyring-first. Plaintext compatibility files are disabled by default
271
+ and, when explicitly enabled, must have mode `0600`.
272
+
273
+ Do not switch to `OSM_USE_DEV_API=false` unless
274
+ `get_edit_capabilities` reports the expected account, production target,
275
+ `safe` profile, and digest-bound host confirmation.
276
+
277
+ ## Main tools
278
+
279
+ Inspection:
280
+
281
+ - `get_server_info`
282
+ - `get_edit_capabilities`
283
+ - `inspect_map_context`
284
+ - read/search/validation tools for OSM elements and tags
285
+
286
+ Review and editing:
287
+
288
+ - `analyze_gpx_track`
289
+ - `create_track_selection`
290
+ - `match_track_selection`
291
+ - `suggest_track_road_candidates`
292
+ - `preview_track_road_edit`
293
+ - `apply_osm_edit`
294
+ - `list_edit_proposals`
295
+ - `verify_osm_edit`
296
+
297
+ Guided prompt:
298
+
299
+ - `review_gpx_road_edit(gpx_path, edit_goal)`
300
+
301
+ ## Development
302
+
303
+ From an existing source checkout:
304
+
305
+ ```bash
306
+ uv sync --locked --extra dev
307
+ uv run --locked --extra dev pytest
308
+ uv run --locked --extra dev pytest --cov=src/osm_edit_mcp --cov-report=term-missing
309
+ ```
310
+
311
+ Unit tests mock the network and force the development API at import time.
312
+ Development-API acceptance is separate and opt-in; it must never point at
313
+ production.
314
+
315
+ More documentation:
316
+
317
+ - [Quick start](docs/quick-start-guide.md)
318
+ - [MCP client setup](docs/MCP_CLIENT_SETUP.md)
319
+ - [Safe usage examples](docs/mcp-usage-examples.md)
320
+ - [Troubleshooting](docs/MCP_TROUBLESHOOTING.md)
321
+ - [Security policy](SECURITY.md)
322
+ - [Contributing](CONTRIBUTING.md)
323
+
324
+ ## License
325
+
326
+ MIT. OpenStreetMap edits are also subject to the OSM contributor terms,
327
+ community guidelines, and source-licensing requirements.