serichard1 commited on
Commit
12e7a1a
·
1 Parent(s): 327efa4
Files changed (3) hide show
  1. app.py +291 -406
  2. gradio_mcp_server.py +335 -97
  3. lexison +1 -0
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import asyncio
2
  import os
3
  import json
4
- import base64
5
  from typing import List, Dict, Any, Union, Optional
6
  from contextlib import AsyncExitStack
7
 
@@ -10,8 +9,6 @@ from gradio.components.chatbot import ChatMessage
10
  from mcp import ClientSession, StdioServerParameters
11
  from mcp.client.stdio import stdio_client
12
  from anthropic import Anthropic
13
- from openai import OpenAI
14
- from mistralai.client import MistralClient
15
  from dotenv import load_dotenv
16
 
17
  load_dotenv()
@@ -23,50 +20,27 @@ class MCPClientWrapper:
23
  def __init__(self):
24
  self.session = None
25
  self.exit_stack = None
26
- self.clients = {}
27
  self.tools = []
28
  self.connected = False
29
- self.current_provider = "claude"
30
- self._init_clients()
31
 
32
- def _init_clients(self):
33
- """Initialize all available LLM clients based on API keys"""
34
  if os.getenv("ANTHROPIC_API_KEY"):
35
- self.clients["claude"] = Anthropic()
36
-
37
- if os.getenv("OPENAI_API_KEY"):
38
- self.clients["openai"] = OpenAI()
39
-
40
- if os.getenv("MISTRAL_API_KEY"):
41
- self.clients["mistral"] = MistralClient(api_key=os.getenv("MISTRAL_API_KEY"))
42
-
43
- if os.getenv("LLAMAINDEX_API_KEY"):
44
- # Assuming this is for a generic API that accepts OpenAI-compatible format
45
- self.clients["llama"] = OpenAI(
46
- api_key=os.getenv("LLAMAINDEX_API_KEY"),
47
- base_url="https://api.llamaindex.ai/v1" # Adjust URL as needed
48
- )
49
-
50
- def set_provider(self, provider: str):
51
- """Set the current LLM provider"""
52
- if provider in self.clients:
53
- self.current_provider = provider
54
- return f"✅ Switched to {provider.upper()}"
55
- return f"❌ {provider.upper()} API key not found"
56
-
57
- def get_available_providers(self) -> List[str]:
58
- """Get list of available providers"""
59
- return list(self.clients.keys())
60
 
61
  def connect(self) -> str:
62
  return loop.run_until_complete(self._connect())
63
-
64
  async def _connect(self) -> str:
65
  if self.exit_stack:
66
  await self.exit_stack.aclose()
67
 
68
  self.exit_stack = AsyncExitStack()
69
-
70
  server_path = "gradio_mcp_server.py"
71
 
72
  server_params = StdioServerParameters(
@@ -90,11 +64,10 @@ class MCPClientWrapper:
90
  } for tool in response.tools]
91
 
92
  self.connected = True
93
- tool_names = [tool["name"] for tool in self.tools]
94
- return f"✅ Connected to MCP Weather Server. Available tools: {', '.join(tool_names)}"
95
  except Exception as e:
96
  self.connected = False
97
- return f"Failed to connect to MCP server: {str(e)}"
98
 
99
  def _read_file_content(self, file_path: str) -> str:
100
  """Read and extract text content from uploaded file"""
@@ -122,7 +95,6 @@ class MCPClientWrapper:
122
  return f.read()
123
 
124
  else:
125
- # Try to read as text, fallback to binary info
126
  try:
127
  with open(file_path, 'r', encoding='utf-8') as f:
128
  return f.read()
@@ -133,14 +105,15 @@ class MCPClientWrapper:
133
  except Exception as e:
134
  return f"Error reading file {os.path.basename(file_path)}: {str(e)}"
135
 
136
- def process_message(self, message: str, files: Optional[List], history: List[Union[Dict[str, Any], ChatMessage]]) -> tuple:
 
 
137
  if not self.session or not self.connected:
138
- return history + [
139
- {"role": "user", "content": message},
140
- {"role": "assistant", "content": "❌ MCP weather server is not connected. Please check the connection status above."}
141
- ], gr.Textbox(value=""), None
142
 
143
- # Process uploaded files
144
  file_content = ""
145
  if files:
146
  file_content = "\n\n--- UPLOADED FILES ---\n"
@@ -151,42 +124,68 @@ class MCPClientWrapper:
151
  file_path = file
152
 
153
  content = self._read_file_content(file_path)
154
- file_content += f"\n📄 File: {os.path.basename(file_path)}\n{content}\n"
155
  file_content += "--- END FILES ---\n\n"
156
 
157
  # Combine message with file content
158
  full_message = file_content + message if file_content else message
159
 
 
160
  new_messages = loop.run_until_complete(self._process_query(full_message, history))
161
- return history + [{"role": "user", "content": message}] + new_messages, gr.Textbox(value=""), None
162
-
 
 
 
 
 
 
 
 
 
 
163
 
164
  async def _process_query(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]):
165
- if self.current_provider not in self.clients:
166
- return [{"role": "assistant", "content": f" {self.current_provider.upper()} client not available"}]
167
 
168
- client = self.clients[self.current_provider]
169
-
170
- # System message for Claude (separate parameter)
171
- system_prompt = """You are a helpful assistant with access to agricultural and weather data tools.
172
 
173
- IMPORTANT TOOL USAGE GUIDELINES:
174
- - Users may ask for information using common names (e.g., "Paris weather" instead of station codes)
175
- - You should make multiple tool calls in sequence to find the right information
176
- - First call broader tools (like get_weather_stations) to find specific IDs/codes
177
- - Then use those IDs/codes in more specific tool calls
178
- - Always analyze tool results to determine if you need additional calls
179
 
180
- EXAMPLE WORKFLOW:
181
- User: "Get weather for Paris station"
182
- 1. Call get_weather_stations() to find Paris station codes
183
- 2. Call get_weather_data(station_code) with the found code
184
- 3. Present the weather data to user
 
 
 
185
 
186
- Available tools include weather stations, cadastral parcels, CAP parcels, municipalities, and agricultural data."""
 
 
 
 
 
 
 
 
 
 
 
 
 
187
 
 
188
  claude_messages = []
189
-
190
  for msg in history:
191
  if isinstance(msg, ChatMessage):
192
  role, content = msg.role, msg.content
@@ -199,414 +198,300 @@ class MCPClientWrapper:
199
  claude_messages.append({"role": "user", "content": message})
200
 
201
  try:
202
- if self.current_provider == "claude":
203
- response = client.messages.create(
204
- model="claude-3-5-sonnet-20241022",
205
- max_tokens=1500,
206
- system=system_prompt, # System prompt as separate parameter
207
- messages=claude_messages,
208
- tools=self.tools
209
- )
210
- return await self._process_claude_response(response, claude_messages, system_prompt)
211
 
212
- elif self.current_provider == "openai":
213
- # For OpenAI, add system message to messages array
214
- openai_messages = [{"role": "system", "content": system_prompt}] + claude_messages
215
-
216
- openai_tools = []
217
- for tool in self.tools:
218
- openai_tools.append({
219
- "type": "function",
220
- "function": {
221
- "name": tool["name"],
222
- "description": tool["description"],
223
- "parameters": tool["input_schema"]
224
- }
225
- })
226
-
227
- response = client.chat.completions.create(
228
- model="gpt-4-turbo-preview",
229
- max_tokens=1500,
230
- messages=openai_messages,
231
- tools=openai_tools if openai_tools else None
232
- )
233
- return await self._process_openai_response(response, openai_messages)
234
-
235
- elif self.current_provider == "mistral":
236
- response = client.chat(
237
- model="mistral-large-latest",
238
- max_tokens=1500,
239
- messages=claude_messages,
240
- tools=self.tools if self.tools else None
241
- )
242
- return await self._process_mistral_response(response, claude_messages)
243
-
244
- elif self.current_provider == "llama":
245
- response = client.chat.completions.create(
246
- model="llama-2-70b-chat", # Adjust model name as needed
247
- max_tokens=1500,
248
- messages=claude_messages,
249
- tools=self.tools if self.tools else None
250
- )
251
- return await self._process_openai_response(response, claude_messages) # Same format as OpenAI
252
-
253
  except Exception as e:
254
- return [{"role": "assistant", "content": f"Error with {self.current_provider}: {str(e)}"}]
255
 
256
- async def _process_claude_response(self, response, claude_messages, system_prompt):
 
257
  result_messages = []
258
- max_tool_rounds = 3
259
- current_round = 0
260
 
261
- while current_round < max_tool_rounds:
262
- has_tool_calls = False
263
- current_round += 1
264
 
265
- for content in response.content:
266
- if content.type == 'text':
267
- result_messages.append({"role": "assistant", "content": content.text})
268
-
269
- elif content.type == 'tool_use':
270
- has_tool_calls = True
271
- tool_name = content.name
272
- tool_args = content.input
273
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
274
  result_messages.append({
275
  "role": "assistant",
276
- "content": f"🔧 Using **{tool_name}** tool to find the information you need...",
277
- "metadata": {"title": f"Tool {current_round}: {tool_name}", "status": "pending"}
278
  })
279
 
280
- try:
281
- result = await self.session.call_tool(tool_name, tool_args)
282
- result_content = result.content
283
- if isinstance(result_content, list):
284
- result_content = "\n".join(str(item) for item in result_content)
285
-
286
- result_messages.append({
287
  "role": "assistant",
288
- "content": self._format_tool_result(result_content),
289
- "metadata": {"title": f"Tool {current_round} Result", "status": "done"}
290
- })
291
-
292
- # Add tool result to conversation context for next round
293
- claude_messages.append({
294
- "role": "assistant",
295
- "content": f"I used {tool_name} and got this result: {result_content}"
296
- })
297
- claude_messages.append({
298
- "role": "user",
299
- "content": "Based on this result, continue helping me with my original request. If you need more specific information (like station codes, parcel IDs), use the data from previous tool calls to make additional tool calls as needed."
300
  })
301
-
302
- except Exception as e:
303
- result_messages.append({
304
- "role": "assistant",
305
- "content": f"❌ Error calling {tool_name}: {str(e)}",
306
- "metadata": {"title": "Tool Error", "status": "error"}
307
- })
308
- break
309
-
310
- # If we made tool calls, get Claude's next response
311
- if has_tool_calls:
312
- try:
313
- next_response = self.clients["claude"].messages.create(
314
- model="claude-3-5-sonnet-20241022",
315
- max_tokens=1500,
316
- system=system_prompt, # Keep system prompt consistent
317
- messages=claude_messages,
318
- tools=self.tools
319
- )
320
- response = next_response
321
- except Exception as e:
322
- result_messages.append({
323
- "role": "assistant",
324
- "content": f"❌ Error in follow-up analysis: {str(e)}"
325
- })
326
  break
327
- else:
 
 
 
 
 
328
  break
329
 
330
- if current_round >= max_tool_rounds:
331
- result_messages.append({
332
- "role": "assistant",
333
- "content": "⚠️ Reached maximum tool call limit. I've gathered the available information above."
334
- })
335
-
336
- return result_messages
337
-
338
- async def _process_openai_response(self, response, claude_messages):
339
- result_messages = []
340
- message = response.choices[0].message
341
-
342
- if message.content:
343
- result_messages.append({"role": "assistant", "content": message.content})
344
-
345
- if message.tool_calls:
346
- for tool_call in message.tool_calls:
347
- tool_name = tool_call.function.name
348
- tool_args = json.loads(tool_call.function.arguments)
349
 
350
- result_messages.append({
351
- "role": "assistant",
352
- "content": f"🔧 Using **{tool_name}** tool...",
353
- "metadata": {"title": f"Tool: {tool_name}", "status": "pending"}
354
  })
355
 
356
- result = await self.session.call_tool(tool_name, tool_args)
357
- result_content = result.content
358
- if isinstance(result_content, list):
359
- result_content = "\n".join(str(item) for item in result_content)
 
 
 
360
 
 
 
 
 
 
 
 
 
361
  result_messages.append({
362
  "role": "assistant",
363
- "content": self._format_tool_result(result_content),
364
- "metadata": {"title": "Tool Result", "status": "done"}
365
  })
366
 
367
- return result_messages
368
-
369
- async def _process_mistral_response(self, response, claude_messages):
370
- result_messages = []
371
- message = response.choices[0].message
372
-
373
- if message.content:
374
- result_messages.append({"role": "assistant", "content": message.content})
375
 
376
  return result_messages
377
-
378
- def _format_tool_result(self, result_content: str) -> str:
379
- """Enhanced tool result formatting with data extraction"""
380
- try:
381
- result_json = json.loads(result_content)
382
-
383
- if isinstance(result_json, dict) and result_json.get("type") == "success":
384
- data = result_json.get("data", {})
385
- endpoint = result_json.get("endpoint", "")
386
-
387
- # Handle weather stations list
388
- if "stations" in endpoint and isinstance(data, list):
389
- formatted_response = f"## 🌤️ Found {len(data)} Weather Stations\n\n"
390
- for station in data[:10]: # Show first 10
391
- if isinstance(station, dict):
392
- code = station.get("code", station.get("id", "N/A"))
393
- name = station.get("name", station.get("description", "N/A"))
394
- formatted_response += f"- **{code}**: {name}\n"
395
- if len(data) > 10:
396
- formatted_response += f"\n... and {len(data) - 10} more stations"
397
- return formatted_response
398
-
399
- # Handle single weather station
400
- elif "stations/" in endpoint and "hourly-reports" not in endpoint:
401
- station_code = result_json.get("station_code", data.get("code", "Unknown"))
402
- formatted_response = f"## 🌤️ Weather Station: {station_code}\n\n"
403
- if isinstance(data, dict):
404
- for key, value in data.items():
405
- if key not in ["id", "code"]:
406
- formatted_response += f"- **{key.title()}**: {value}\n"
407
- return formatted_response
408
-
409
- # Handle weather data reports (existing logic)
410
- elif isinstance(data, dict) and "reports" in data:
411
- return self._format_weather_reports(data, result_json.get("station_code", "Unknown"))
412
-
413
- # Handle municipalities, parcels, etc.
414
- elif isinstance(data, list) and len(data) > 0:
415
- item_type = "Items"
416
- if "municipalities" in endpoint:
417
- item_type = "Municipalities"
418
- elif "parcels" in endpoint:
419
- item_type = "Parcels"
420
-
421
- formatted_response = f"## 📍 Found {len(data)} {item_type}\n\n"
422
- for item in data[:10]:
423
- if isinstance(item, dict):
424
- name = item.get("name", item.get("id", item.get("code", "N/A")))
425
- id_val = item.get("id", item.get("code", ""))
426
- formatted_response += f"- **{id_val}**: {name}\n"
427
- return formatted_response
428
-
429
- # Generic JSON formatting
430
- return f"```json\n{json.dumps(data, indent=2)}\n```"
431
-
432
- elif isinstance(result_json, dict) and result_json.get("type") == "error":
433
- error_msg = result_json.get("message", "Unknown error")
434
- return f"## ❌ Error\n\n{error_msg}"
435
-
436
- return f"```json\n{json.dumps(result_json, indent=2)}\n```"
437
-
438
- except json.JSONDecodeError:
439
- return f"```\n{result_content}\n```"
440
-
441
- def _format_weather_reports(self, weather_data: dict, station_code: str) -> str:
442
- """Format weather reports data"""
443
- formatted_response = f"## 🌤️ Weather Data for Station: {station_code}\n\n"
444
-
445
- reports = weather_data.get("reports", [])
446
- if isinstance(reports, list) and len(reports) > 0:
447
- formatted_response += f"**Found {len(reports)} weather reports**\n\n"
448
- for i, report in enumerate(reports[:5]): # Show first 5
449
- if isinstance(report, dict):
450
- timestamp = report.get("timestamp", "Unknown time")
451
- temperature = report.get("temperature", "N/A")
452
- humidity = report.get("humidity", "N/A")
453
- formatted_response += f"**Report {i+1}** ({timestamp}):\n"
454
- formatted_response += f"- Temperature: {temperature}\n"
455
- formatted_response += f"- Humidity: {humidity}\n\n"
456
-
457
- if len(reports) > 5:
458
- formatted_response += f"... and {len(reports) - 5} more reports\n\n"
459
-
460
- return formatted_response
461
 
462
  client = MCPClientWrapper()
463
 
464
  def gradio_interface():
465
- with gr.Blocks(title="MCP LEXICON", theme=gr.themes.Soft()) as demo:
466
- gr.Markdown("# 🌤️ LEXICON CHATBOT - Multi-LLM Weather Assistant")
467
- gr.Markdown(
468
- "Ask me about weather data from any weather station! Upload files for additional context. "
469
- "I can fetch hourly reports, help you explore weather patterns, and answer questions about specific stations."
470
- )
 
 
471
 
472
- # Settings row
473
  with gr.Row():
474
- # LLM Provider selection
475
- available_providers = client.get_available_providers()
476
- if available_providers:
477
- provider_choice = gr.Dropdown(
478
- choices=available_providers,
479
- value=client.current_provider if client.current_provider in available_providers else available_providers[0],
480
- label="🤖 LLM Provider",
481
- scale=1
482
- )
483
- else:
484
- provider_choice = gr.Dropdown(
485
- choices=["No API keys found"],
486
- value="No API keys found",
487
- label="🤖 LLM Provider",
488
- scale=1,
489
  interactive=False
490
  )
491
-
492
- # Connection status
493
- status = gr.Textbox(
494
- label="🔌 MCP Connection",
495
- interactive=False,
496
- value="🔄 Connecting...",
497
- scale=2
 
 
 
498
  )
 
499
 
500
- # Main chat interface
501
- chatbot = gr.Chatbot(
502
- value=[],
503
- height=600,
504
- type="messages",
505
- show_copy_button=True,
506
- avatar_images=("👤", "🤖"),
507
- bubble_full_width=False
508
- )
509
-
510
- # Input row with file upload
511
  with gr.Row():
512
- with gr.Column(scale=4):
513
  msg = gr.Textbox(
514
- label="💬 Message",
515
- placeholder="Ask about weather data or upload files for context...",
516
- lines=2
517
- )
518
- with gr.Column(scale=2):
519
- file_upload = gr.File(
520
- label="📎 Upload Files",
521
- file_count="multiple",
522
- file_types=[".txt", ".pdf", ".csv", ".json", ".md", ".py", ".js", ".html", ".xml", ".yaml"]
523
  )
 
 
 
 
 
 
 
 
524
 
525
- # Control buttons
526
- with gr.Row():
527
- submit_btn = gr.Button("Send", variant="primary", scale=2)
528
- clear_btn = gr.Button("🗑️ Clear", scale=1)
529
- reconnect_btn = gr.Button("🔄 Reconnect MCP", scale=1)
530
-
531
- # Example queries
532
  with gr.Accordion("💡 Example Queries", open=False):
533
  gr.Examples(
534
  examples=[
535
- "What weather stations are available?",
536
- "Get weather data for station ABC123",
537
- "Show me the latest reports for NYC001",
538
- "Compare weather patterns between two stations",
539
- "Analyze the uploaded CSV data with weather information"
540
  ],
541
  inputs=msg
542
  )
543
 
544
  # Event handlers
545
  def auto_connect():
546
- return client.connect()
547
-
548
- def change_provider(provider):
549
- if provider != "No API keys found":
550
- result = client.set_provider(provider)
551
- return result
552
- return "❌ No valid provider selected"
553
 
554
  def process_and_clear(message, files, history):
555
  if not message.strip() and not files:
556
  return history, "", None
 
557
  return client.process_message(message, files, history)
558
 
559
  # Setup events
560
- demo.load(auto_connect, outputs=status)
561
-
562
- provider_choice.change(
563
- change_provider,
564
- inputs=provider_choice,
565
- outputs=gr.Textbox(visible=False) # Hidden output for status
566
- )
567
 
568
  submit_btn.click(
569
  process_and_clear,
570
- inputs=[msg, file_upload, chatbot],
571
- outputs=[chatbot, msg, file_upload]
572
  )
573
 
574
  msg.submit(
575
  process_and_clear,
576
- inputs=[msg, file_upload, chatbot],
577
- outputs=[chatbot, msg, file_upload]
578
  )
579
 
580
- clear_btn.click(lambda: ([], "", None), outputs=[chatbot, msg, file_upload])
581
- reconnect_btn.click(auto_connect, outputs=status)
582
 
583
  return demo
584
 
585
  if __name__ == "__main__":
586
- # Check for API keys
587
- api_keys = {
588
- "ANTHROPIC_API_KEY": "Claude",
589
- "OPENAI_API_KEY": "OpenAI",
590
- "MISTRAL_API_KEY": "Mistral",
591
- "LLAMAINDEX_API_KEY": "Llama"
592
- }
593
-
594
- found_keys = []
595
- for key, name in api_keys.items():
596
- if os.getenv(key):
597
- found_keys.append(name)
598
-
599
- if found_keys:
600
- print(f"🔑 Found API keys for: {', '.join(found_keys)}")
601
  else:
602
- print("⚠️ Warning: No API keys found in environment.")
603
- print("Please set them in your .env file:")
604
- for key in api_keys.keys():
605
- print(f"{key}=your_key_here")
606
 
607
- print("🚀 Starting MCP Multi-LLM Weather Client...")
608
- print("🔡 Will auto-connect to gradio_mcp_server.py")
609
- print("🌐 Weather API endpoint: https://lexicon.osfarm.org/weather/stations")
610
 
611
  interface = gradio_interface()
612
- interface.launch(debug=True, share=True)
 
 
 
1
  import asyncio
2
  import os
3
  import json
 
4
  from typing import List, Dict, Any, Union, Optional
5
  from contextlib import AsyncExitStack
6
 
 
9
  from mcp import ClientSession, StdioServerParameters
10
  from mcp.client.stdio import stdio_client
11
  from anthropic import Anthropic
 
 
12
  from dotenv import load_dotenv
13
 
14
  load_dotenv()
 
20
  def __init__(self):
21
  self.session = None
22
  self.exit_stack = None
23
+ self.client = None
24
  self.tools = []
25
  self.connected = False
26
+ self.max_iterations = 3 # Prevent infinite loops
27
+ self._init_client()
28
 
29
+ def _init_client(self):
30
+ """Initialize Claude client"""
31
  if os.getenv("ANTHROPIC_API_KEY"):
32
+ self.client = Anthropic()
33
+ else:
34
+ raise ValueError("ANTHROPIC_API_KEY not found in environment")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
  def connect(self) -> str:
37
  return loop.run_until_complete(self._connect())
38
+
39
  async def _connect(self) -> str:
40
  if self.exit_stack:
41
  await self.exit_stack.aclose()
42
 
43
  self.exit_stack = AsyncExitStack()
 
44
  server_path = "gradio_mcp_server.py"
45
 
46
  server_params = StdioServerParameters(
 
64
  } for tool in response.tools]
65
 
66
  self.connected = True
67
+ return f"Connected to MCP Server. Available tools: {len(self.tools)}"
 
68
  except Exception as e:
69
  self.connected = False
70
+ return f"Failed to connect to MCP server: {str(e)}"
71
 
72
  def _read_file_content(self, file_path: str) -> str:
73
  """Read and extract text content from uploaded file"""
 
95
  return f.read()
96
 
97
  else:
 
98
  try:
99
  with open(file_path, 'r', encoding='utf-8') as f:
100
  return f.read()
 
105
  except Exception as e:
106
  return f"Error reading file {os.path.basename(file_path)}: {str(e)}"
107
 
108
+ # In the MCPClientWrapper class...
109
+
110
+ def process_message(self, message: str, files: Optional[List], history: List[List[str]]) -> tuple:
111
  if not self.session or not self.connected:
112
+ # Format the error message correctly for the chatbot
113
+ error_response = "MCP server is not connected. Please check the connection status above."
114
+ return history + [[message, error_response]], "", None
 
115
 
116
+ # Process uploaded files (your existing code is fine here)
117
  file_content = ""
118
  if files:
119
  file_content = "\n\n--- UPLOADED FILES ---\n"
 
124
  file_path = file
125
 
126
  content = self._read_file_content(file_path)
127
+ file_content += f"\nFile: {os.path.basename(file_path)}\n{content}\n"
128
  file_content += "--- END FILES ---\n\n"
129
 
130
  # Combine message with file content
131
  full_message = file_content + message if file_content else message
132
 
133
+ # This returns a list of dictionaries like [{'role': 'assistant', 'content': '...'}, ...]
134
  new_messages = loop.run_until_complete(self._process_query(full_message, history))
135
+
136
+ # 1. Combine all the assistant's generated messages (tool calls, analysis) into a single string.
137
+ assistant_response_parts = [
138
+ msg.get('content', '') for msg in new_messages if msg.get('role') == 'assistant'
139
+ ]
140
+ assistant_full_response = "\n\n".join(assistant_response_parts)
141
+
142
+ # 2. Update the history in the format Gradio expects: a list of [user, assistant] pairs.
143
+ updated_history = history + [[message, assistant_full_response]]
144
+
145
+ # 3. Return the correctly formatted history and other component updates.
146
+ return updated_history, "", None
147
 
148
  async def _process_query(self, message: str, history: List[Union[Dict[str, Any], ChatMessage]]):
149
+ if not self.client:
150
+ return [{"role": "assistant", "content": "Claude client not available"}]
151
 
152
+ # Enhanced system prompt that encourages planning and comprehensive analysis
153
+ system_prompt = """You are LEXICON, an intelligent agricultural and weather data assistant with access to comprehensive databases through specialized tools.
154
+
155
+ CORE MISSION: When users ask questions, you must create and execute detailed plans to provide complete, accurate answers using ALL relevant data sources.
156
 
157
+ PLANNING APPROACH:
158
+ 1. **ANALYZE** the user's question to identify all information needs
159
+ 2. **PLAN** a systematic approach using multiple tools and data sources
160
+ 3. **EXECUTE** your plan step-by-step, making multiple tool calls as needed
161
+ 4. **SYNTHESIZE** all gathered data into a comprehensive, well-structured answer
 
162
 
163
+ AVAILABLE DATA SOURCES:
164
+ - Weather stations and meteorological data (current and historical)
165
+ - Municipalities and geographical references
166
+ - Cadastral parcels and CAP (Common Agricultural Policy) parcels
167
+ - Agricultural production data and statistics
168
+ - Seed varieties and vine varieties databases
169
+ - Phytosanitary products and crop protection information
170
+ - Geolocation data (GeoJSON) for mapping and spatial analysis
171
 
172
+ EXECUTION PRINCIPLES:
173
+ - Make MULTIPLE tool calls to gather complete information
174
+ - Follow up on IDs, codes, or references found in initial results
175
+ - Cross-reference data between different sources when relevant
176
+ - Always aim for comprehensive coverage of the topic
177
+ - If initial results suggest additional relevant data exists, pursue it
178
+ - Provide context and explain relationships between different data points
179
+
180
+ EXAMPLE WORKFLOWS:
181
+ - Location query → Search municipalities → Get detailed info → Fetch cadastral/CAP data → Analyze geographical context
182
+ - Weather inquiry → Find relevant stations → Get station details → Retrieve weather data → Analyze patterns
183
+ - Agricultural question → Search relevant databases → Cross-reference production data → Provide comprehensive agricultural context
184
+
185
+ Remember: Your goal is thorough investigation and complete answers, not quick single-tool responses."""
186
 
187
+ # Build conversation history for Claude
188
  claude_messages = []
 
189
  for msg in history:
190
  if isinstance(msg, ChatMessage):
191
  role, content = msg.role, msg.content
 
198
  claude_messages.append({"role": "user", "content": message})
199
 
200
  try:
201
+ # Start the iterative tool calling process
202
+ return await self._iterative_tool_calling(claude_messages)
 
 
 
 
 
 
 
203
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  except Exception as e:
205
+ return [{"role": "assistant", "content": f"Error with Claude: {str(e)}"}]
206
 
207
+ async def _iterative_tool_calling(self, messages: List[Dict[str, str]]):
208
+ """Enhanced method that allows Claude to reason through multiple tool calls"""
209
  result_messages = []
210
+ conversation_messages = messages.copy()
211
+ iteration = 0
212
 
213
+ while iteration < self.max_iterations:
214
+ iteration += 1
 
215
 
216
+ try:
217
+ # Make API call to Claude
218
+ response = self.client.messages.create(
219
+ model="claude-3-5-sonnet-20241022",
220
+ max_tokens=8192,
221
+ system="""You are LEXICON, an intelligent agricultural and weather data assistant with access to comprehensive databases through specialized tools.
222
+
223
+ CORE MISSION: When users ask questions, you must create and execute detailed plans to provide complete, accurate answers using ALL relevant data sources.
224
+
225
+ PLANNING APPROACH:
226
+ 1. **ANALYZE** the user's question to identify all information needs
227
+ 2. **PLAN** a systematic approach using multiple tools and data sources
228
+ 3. **EXECUTE** your plan step-by-step, making multiple tool calls as needed
229
+ 4. **SYNTHESIZE** all gathered data into a comprehensive, well-structured answer
230
+
231
+ AVAILABLE DATA SOURCES:
232
+ - Weather stations and meteorological data (current and historical)
233
+ - Municipalities and geographical references
234
+ - Cadastral parcels and CAP (Common Agricultural Policy) parcels
235
+ - Agricultural production data and statistics
236
+ - Seed varieties and vine varieties databases
237
+ - Phytosanitary products and crop protection information
238
+ - Geolocation data (GeoJSON) for mapping and spatial analysis
239
+
240
+ EXECUTION PRINCIPLES:
241
+ - Make MULTIPLE tool calls to gather complete information
242
+ - Follow up on IDs, codes, or references found in initial results
243
+ - Cross-reference data between different sources when relevant
244
+ - Always aim for comprehensive coverage of the topic
245
+ - If initial results suggest additional relevant data exists, pursue it
246
+ - Provide context and explain relationships between different data points
247
+
248
+ EXAMPLE WORKFLOWS:
249
+ - Location query → Search municipalities → Get detailed info → Fetch cadastral/CAP data → Analyze geographical context
250
+ - Weather inquiry → Find relevant stations → Get station details → Retrieve weather data → Analyze patterns
251
+ - Agricultural question → Search relevant databases → Cross-reference production data → Provide comprehensive agricultural context
252
+
253
+ Remember: Your goal is thorough investigation and complete answers, not quick single-tool responses.""",
254
+ messages=conversation_messages,
255
+ tools=self.tools
256
+ )
257
+
258
+ # Process the response
259
+ has_tool_calls = False
260
+ response_text = ""
261
+
262
+ for content in response.content:
263
+ if content.type == 'text':
264
+ response_text = content.text
265
+
266
+ elif content.type == 'tool_use':
267
+ has_tool_calls = True
268
+ tool_name = content.name
269
+ tool_args = content.input
270
+ tool_call_id = content.id
271
+
272
+ try:
273
+ # Execute the tool call
274
+ result = await self.session.call_tool(tool_name, tool_args)
275
+ raw_result = result.content
276
+
277
+ if isinstance(raw_result, list):
278
+ raw_result = "\n".join(str(item) for item in raw_result)
279
+
280
+ # Add tool result to conversation for Claude to see
281
+ conversation_messages.append({
282
+ "role": "assistant",
283
+ "content": [
284
+ {"type": "tool_use", "id": tool_call_id, "name": tool_name, "input": tool_args}
285
+ ]
286
+ })
287
+ conversation_messages.append({
288
+ "role": "user",
289
+ "content": [
290
+ {
291
+ "type": "tool_result",
292
+ "tool_use_id": tool_call_id,
293
+ "content": str(raw_result)
294
+ }
295
+ ]
296
+ })
297
+
298
+ # Add to result messages for display
299
+ tool_display = f"🔧 **{tool_name}**({', '.join(f'{k}={v}' for k, v in tool_args.items())})\n\n```json\n{raw_result}\n```"
300
+ result_messages.append({
301
+ "role": "assistant",
302
+ "content": tool_display
303
+ })
304
+
305
+ except Exception as e:
306
+ error_msg = f"❌ Error calling {tool_name}: {str(e)}"
307
+ result_messages.append({
308
+ "role": "assistant",
309
+ "content": error_msg
310
+ })
311
+
312
+ # Add error to conversation
313
+ conversation_messages.append({
314
+ "role": "user",
315
+ "content": [
316
+ {
317
+ "type": "tool_result",
318
+ "tool_use_id": tool_call_id,
319
+ "content": f"Error: {str(e)}"
320
+ }
321
+ ]
322
+ })
323
+
324
+ # If there was response text, add it
325
+ if response_text.strip():
326
  result_messages.append({
327
  "role": "assistant",
328
+ "content": response_text
 
329
  })
330
 
331
+ # Add to conversation if this isn't just a tool call
332
+ if not has_tool_calls:
333
+ conversation_messages.append({
 
 
 
 
334
  "role": "assistant",
335
+ "content": response_text
 
 
 
 
 
 
 
 
 
 
 
336
  })
337
+
338
+ # If no tool calls were made, we're done with data gathering
339
+ if not has_tool_calls:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  break
341
+
342
+ except Exception as e:
343
+ result_messages.append({
344
+ "role": "assistant",
345
+ "content": f"❌ Error in iteration {iteration}: {str(e)}"
346
+ })
347
  break
348
 
349
+ # After all tool calls, get Claude's final synthesis
350
+ if iteration > 1: # Only if we actually made tool calls
351
+ try:
352
+ final_prompt = "Based on all the data you've gathered above, please provide a comprehensive, well-structured answer to the user's original question. Synthesize the information from all sources and present it in a clear, useful format. Don't repeat the raw data - instead, analyze and explain what it means for the user."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
 
354
+ conversation_messages.append({
355
+ "role": "user",
356
+ "content": final_prompt
 
357
  })
358
 
359
+ final_response = self.client.messages.create(
360
+ model="claude-3-5-sonnet-20241022",
361
+ max_tokens=8192,
362
+ system="You are LEXICON. Provide a comprehensive, synthesized answer based on all the data gathered. Focus on insights, analysis, and practical information rather than repeating raw data.",
363
+ messages=conversation_messages,
364
+ tools=[] # No tools for final synthesis
365
+ )
366
 
367
+ for content in final_response.content:
368
+ if content.type == 'text':
369
+ result_messages.append({
370
+ "role": "assistant",
371
+ "content": f"## 📋 **Comprehensive Analysis**\n\n{content.text}"
372
+ })
373
+
374
+ except Exception as e:
375
  result_messages.append({
376
  "role": "assistant",
377
+ "content": f"❌ Error generating final analysis: {str(e)}"
 
378
  })
379
 
380
+ # # If we hit max iterations, add a note
381
+ # if iteration >= self.max_iterations:
382
+ # result_messages.append({
383
+ # "role": "assistant",
384
+ # "content": f"ℹ️ Reached maximum analysis depth ({self.max_iterations} steps)."
385
+ # })
 
 
386
 
387
  return result_messages
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
 
389
  client = MCPClientWrapper()
390
 
391
  def gradio_interface():
392
+ # Keep the custom orange and red theme
393
+ theme = gr.themes.Default(
394
+ primary_hue=gr.themes.colors.orange,
395
+ secondary_hue=gr.themes.colors.red,
396
+ neutral_hue=gr.themes.colors.slate,
397
+ )
398
+
399
+ with gr.Blocks(title="MCP LEXICON", theme=theme, css=".gradio-container {max-width: 95% !important;}") as demo:
400
 
401
+ # 1. Top row with title and the new dynamic status button
402
  with gr.Row():
403
+ with gr.Column(scale=8):
404
+ gr.Markdown("## 🌾 LEXICON CHATBOT")
405
+ with gr.Column(scale=2, min_width=220):
406
+ status_button = gr.Button(
407
+ "Connecting...",
408
+ variant="stop",
 
 
 
 
 
 
 
 
 
409
  interactive=False
410
  )
411
+
412
+ # 2. Main chat interface with a clear button
413
+ with gr.Row():
414
+ chatbot = gr.Chatbot(
415
+ label="Conversation",
416
+ value=[],
417
+ height=650,
418
+ show_copy_button=True,
419
+ avatar_images=("👤", "🌾"),
420
+ bubble_full_width=False,
421
  )
422
+ clear_btn = gr.Button("🗑️ Clear", scale=0)
423
 
424
+ # 3. Concise input bar at the bottom (standard chatbot layout)
 
 
 
 
 
 
 
 
 
 
425
  with gr.Row():
426
+ with gr.Column(scale=10):
427
  msg = gr.Textbox(
428
+ label="User Prompt",
429
+ placeholder="Ask a question about agriculture, weather, or geography...",
430
+ show_label=False,
431
+ container=False # Removes border for a cleaner look
 
 
 
 
 
432
  )
433
+
434
+ file_btn = gr.UploadButton("📎", file_count="multiple", scale=1)
435
+
436
+ submit_btn = gr.Button(
437
+ "Ask",
438
+ variant="primary",
439
+ scale=1
440
+ )
441
 
442
+ # Examples accordion remains at the bottom
 
 
 
 
 
 
443
  with gr.Accordion("💡 Example Queries", open=False):
444
  gr.Examples(
445
  examples=[
446
+ "What's the complete agricultural profile of Bignan including weather stations, cadastral parcels, and production data?",
447
+ "Find all weather stations near Paris, get their latest data, and analyze weather patterns",
448
+ "I need comprehensive information about vine varieties and which phytosanitary products are recommended for vineyard management",
 
 
449
  ],
450
  inputs=msg
451
  )
452
 
453
  # Event handlers
454
  def auto_connect():
455
+ for status_update in client.connect():
456
+ yield status_update
 
 
 
 
 
457
 
458
  def process_and_clear(message, files, history):
459
  if not message.strip() and not files:
460
  return history, "", None
461
+ # Simply return the result from the client method
462
  return client.process_message(message, files, history)
463
 
464
  # Setup events
465
+ demo.load(auto_connect, outputs=status_button)
466
+ status_button.click(auto_connect, outputs=status_button)
 
 
 
 
 
467
 
468
  submit_btn.click(
469
  process_and_clear,
470
+ inputs=[msg, file_btn, chatbot],
471
+ outputs=[chatbot, msg, file_btn]
472
  )
473
 
474
  msg.submit(
475
  process_and_clear,
476
+ inputs=[msg, file_btn, chatbot],
477
+ outputs=[chatbot, msg, file_btn]
478
  )
479
 
480
+ clear_btn.click(lambda: ([], "", None), outputs=[chatbot, msg, file_btn], queue=False)
 
481
 
482
  return demo
483
 
484
  if __name__ == "__main__":
485
+ if not os.getenv("ANTHROPIC_API_KEY"):
486
+ print("Warning: ANTHROPIC_API_KEY not found in environment.")
487
+ print("Please set it in your .env file: ANTHROPIC_API_KEY=your_key_here")
 
 
 
 
 
 
 
 
 
 
 
 
488
  else:
489
+ print("Found Anthropic API key")
 
 
 
490
 
491
+ print("Starting Enhanced MCP Client with Multi-Step Planning...")
492
+ print("API endpoint: https://lexicon.osfarm.org")
 
493
 
494
  interface = gradio_interface()
495
+ interface.launch(debug=True, share=True)
496
+
497
+ # provide everything you know about the municipality of ABANCOURT
gradio_mcp_server.py CHANGED
@@ -69,162 +69,400 @@ def make_api_request(endpoint: str, params: dict = None) -> str:
69
  "message": f"Unexpected error: {str(e)}"
70
  })
71
 
72
- # WEATHER TOOLS
73
  @mcp.tool()
74
- async def get_weather_stations() -> str:
75
- """Get a list of all available weather stations"""
76
- return make_api_request("/weather/stations.json")
77
 
78
- @mcp.tool()
79
- async def get_weather_station(station_code: str) -> str:
80
- """Get details of a specific weather station
81
-
82
  Args:
83
- station_code: The weather station code/ID
 
 
 
 
 
 
 
84
  """
85
- return make_api_request(f"/weather/stations/{station_code}.json")
 
86
 
87
  @mcp.tool()
88
- async def get_weather_data(station_code: str, page: int = 1, start: str = None, end: str = None) -> str:
89
- """Get hourly weather reports from a weather station.
90
-
 
 
 
 
 
 
 
91
  Args:
92
- station_code: The weather station code/ID to fetch data from
93
- page: Page number for pagination (default: 1)
94
- start: Start date/time filter in ISO format (optional, e.g., '2024-01-01T00:00:00Z')
95
- end: End date/time filter in ISO format (optional, e.g., '2024-01-31T23:59:59Z')
 
 
 
 
 
 
 
96
  """
97
  params = {"page": page}
98
- if start:
99
- params["start"] = start
100
- if end:
101
- params["end"] = end
102
-
103
- return make_api_request(f"/weather/stations/{station_code}/hourly-reports.json", params)
104
 
105
- # TOOLS
106
  @mcp.tool()
107
- async def get_parcel_identifier_json() -> str:
108
- """Get parcel identifier tool data in JSON format"""
109
- return make_api_request("/tools/parcel-identifier.json")
 
 
 
 
 
 
 
 
 
 
110
 
111
  @mcp.tool()
112
- async def get_parcel_identifier_geojson() -> str:
113
- """Get parcel identifier tool data in GeoJSON format"""
114
- return make_api_request("/tools/parcel-identifier.geojson")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
- # GEOGRAPHICAL REFERENCES - CADASTRAL PARCELS
117
  @mcp.tool()
118
- async def get_cadastral_parcels() -> str:
119
- """Get list of all cadastral parcels"""
120
- return make_api_request("/geographical-references/cadastral-parcels.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  @mcp.tool()
123
- async def get_cadastral_parcel(parcel_id: str) -> str:
124
- """Get details of a specific cadastral parcel
125
-
 
126
  Args:
127
- parcel_id: The cadastral parcel ID
 
 
 
 
 
128
  """
129
- return make_api_request(f"/geographical-references/cadastral-parcels/{parcel_id}.json")
130
 
131
  @mcp.tool()
132
- async def get_cadastral_parcel_geolocation(parcel_id: str) -> str:
133
- """Get geolocation data for a cadastral parcel in GeoJSON format
134
-
 
135
  Args:
136
- parcel_id: The cadastral parcel ID
 
 
 
 
 
 
 
137
  """
138
- return make_api_request(f"/geographical-references/cadastral-parcels/{parcel_id}/geolocation.geojson")
 
 
 
139
 
140
- # GEOGRAPHICAL REFERENCES - CAP PARCELS
141
  @mcp.tool()
142
- async def get_cap_parcels() -> str:
143
- """Get list of all CAP (Common Agricultural Policy) parcels"""
144
- return make_api_request("/geographical-references/cap-parcels.json")
 
 
 
 
 
 
 
 
 
 
145
 
146
  @mcp.tool()
147
- async def get_cap_parcel(cap_id: str) -> str:
148
- """Get details of a specific CAP parcel
149
-
 
150
  Args:
151
- cap_id: The CAP parcel ID
 
 
 
 
 
 
 
152
  """
153
- return make_api_request(f"/geographical-references/cap-parcels/{cap_id}.json")
 
 
 
154
 
155
  @mcp.tool()
156
- async def get_cap_parcel_geolocation(cap_id: str) -> str:
157
- """Get geolocation data for a CAP parcel in GeoJSON format
 
 
158
  Args:
159
- cap_id: The CAP parcel ID
 
 
 
 
 
160
  """
161
- return make_api_request(f"/geographical-references/cap-parcels/{cap_id}/geolocation.geojson")
 
162
 
163
  @mcp.tool()
164
- async def get_municipalities() -> str:
165
- """Get list of all municipalities"""
166
- return make_api_request("/geographical-references/municipalities.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
 
168
  @mcp.tool()
169
- async def get_municipality(municipality_id: str) -> str:
170
- """Get details of a specific municipality
171
-
 
172
  Args:
173
- municipality_id: The municipality ID
 
 
 
 
 
174
  """
175
- return make_api_request(f"/geographical-references/municipalities/{municipality_id}.json")
 
176
 
177
  @mcp.tool()
178
- async def get_municipality_cadastre(municipality_id: str) -> str:
179
- """Get cadastre data for a municipality in GeoJSON format
180
-
 
181
  Args:
182
- municipality_id: The municipality ID
 
 
 
 
 
 
183
  """
184
- return make_api_request(f"/geographical-references/municipalities/{municipality_id}/cadastre.geojson")
 
 
185
 
186
  @mcp.tool()
187
- async def get_municipality_cap_parcels(municipality_id: str) -> str:
188
- """Get CAP parcels geolocation data for a municipality in GeoJSON format
189
-
 
190
  Args:
191
- municipality_id: The municipality ID
 
 
 
 
 
 
 
192
  """
193
- return make_api_request(f"/geographical-references/municipalities/{municipality_id}/cap-parcels.geojson")
 
 
 
194
 
195
- # PRODUCTION
196
  @mcp.tool()
197
- async def get_productions() -> str:
198
- """Get list of all production data"""
199
- return make_api_request("/production/productions.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
 
201
- # PHYTOSANITARY
202
  @mcp.tool()
203
- async def get_cropsets() -> str:
204
- """Get list of all phytosanitary cropsets"""
205
- return make_api_request("/phytosanitary/cropsets.json")
 
 
 
 
 
 
 
 
 
 
206
 
207
  @mcp.tool()
208
- async def get_phytosanitary_products() -> str:
209
- """Get list of all phytosanitary products"""
210
- return make_api_request("/phytosanitary/products.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
 
212
  @mcp.tool()
213
- async def get_phytosanitary_symbols() -> str:
214
- """Get list of all phytosanitary symbols"""
215
- return make_api_request("/phytosanitary/symbols.json")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
- # SEEDS
218
  @mcp.tool()
219
- async def get_seed_varieties() -> str:
220
- """Get list of all seed varieties"""
221
- return make_api_request("/seeds/varieties.json")
 
 
 
 
 
 
 
 
 
 
222
 
223
- # VITICULTURE
224
  @mcp.tool()
225
- async def get_vine_varieties() -> str:
226
- """Get list of all vine varieties"""
227
- return make_api_request("/viticulture/vine-varieties.json")
 
 
 
 
 
 
 
 
 
 
228
 
229
  if __name__ == "__main__":
230
  mcp.run(transport='stdio')
 
69
  "message": f"Unexpected error: {str(e)}"
70
  })
71
 
 
72
  @mcp.tool()
73
+ async def get_parcel_identifier_json(latitude: float, longitude: float) -> str:
74
+ """
75
+ Retrieve parcel identifier information in JSON format for a given geographic location.
76
 
 
 
 
 
77
  Args:
78
+ latitude (float): Latitude of the point of interest.
79
+ longitude (float): Longitude of the point of interest.
80
+
81
+ Returns:
82
+ str: JSON string containing parcel identifier data for the specified coordinates.
83
+
84
+ This tool allows you to obtain parcel identification data by providing precise geographic coordinates.
85
+ Useful for reverse-geocoding a location to its cadastral reference.
86
  """
87
+ params = {"latitude": latitude, "longitude": longitude}
88
+ return make_api_request("/tools/parcel-identifier.json", params)
89
 
90
  @mcp.tool()
91
+ async def get_cadastral_parcels(
92
+ page: int = 1,
93
+ code: str = None,
94
+ prefix: str = None,
95
+ section: str = None,
96
+ number: str = None
97
+ ) -> str:
98
+ """
99
+ Retrieve a paginated list of cadastral parcels, with optional filters.
100
+
101
  Args:
102
+ page (int, optional): Page number for pagination (default: 1).
103
+ code (str, optional): Commune code to filter parcels.
104
+ prefix (str, optional): Parcel prefix for more precise filtering.
105
+ section (str, optional): Parcel section identifier.
106
+ number (str, optional): Parcel number.
107
+
108
+ Returns:
109
+ str: JSON string containing a list of cadastral parcels matching the filters.
110
+
111
+ This tool enables searching for cadastral parcels using various administrative and parcel-specific filters.
112
+ Useful for exploring land registry data at different levels of granularity.
113
  """
114
  params = {"page": page}
115
+ if code: params["code"] = code
116
+ if prefix: params["prefix"] = prefix
117
+ if section: params["section"] = section
118
+ if number: params["number"] = number
119
+ return make_api_request("/geographical-references/cadastral-parcels.json", params)
 
120
 
 
121
  @mcp.tool()
122
+ async def get_cadastral_parcel(parcel_id: str) -> str:
123
+ """
124
+ Retrieve detailed information about a specific cadastral parcel.
125
+
126
+ Args:
127
+ parcel_id (str): Unique identifier of the cadastral parcel.
128
+
129
+ Returns:
130
+ str: JSON string with detailed information about the parcel.
131
+
132
+ Use this tool to get all available data for a single cadastral parcel, including administrative and spatial attributes.
133
+ """
134
+ return make_api_request(f"/geographical-references/cadastral-parcels/{parcel_id}.json")
135
 
136
  @mcp.tool()
137
+ async def get_cadastral_parcel_prices(postal_code: str = None, city: str = None, department: str = None) -> str:
138
+ """
139
+ Retrieve cadastral parcel price information, filtered by postal code, city, or department.
140
+
141
+ Args:
142
+ postal_code (str, optional): Postal code to filter results.
143
+ city (str, optional): City name for filtering.
144
+ department (str, optional): Department code or name.
145
+
146
+ Returns:
147
+ str: JSON string with price information for cadastral parcels.
148
+
149
+ This tool provides access to price data for cadastral parcels, supporting multiple administrative filters.
150
+ """
151
+ params = {}
152
+ if postal_code: params["postal_code"] = postal_code
153
+ if city: params["city"] = city
154
+ if department: params["department"] = department
155
+ return make_api_request("/geographical-references/cadastral-parcel-prices.json", params)
156
 
 
157
  @mcp.tool()
158
+ async def get_cap_parcels(page: int = 1, city: str = None) -> str:
159
+ """
160
+ Retrieve a paginated list of CAP (Common Agricultural Policy) parcels, optionally filtered by city.
161
+
162
+ Args:
163
+ page (int, optional): Page number for pagination (default: 1).
164
+ city (str, optional): City name to filter CAP parcels.
165
+
166
+ Returns:
167
+ str: JSON string containing CAP parcels matching the filters.
168
+
169
+ This tool allows you to explore CAP parcels, which are relevant for agricultural policy and subsidy management.
170
+ """
171
+ params = {"page": page}
172
+ if city: params["city"] = city
173
+ return make_api_request("/geographical-references/cap-parcels.json", params)
174
 
175
  @mcp.tool()
176
+ async def get_cap_parcel(cap_id: str) -> str:
177
+ """
178
+ Retrieve detailed information about a specific CAP parcel.
179
+
180
  Args:
181
+ cap_id (str): Unique identifier of the CAP parcel.
182
+
183
+ Returns:
184
+ str: JSON string with detailed information about the CAP parcel.
185
+
186
+ Use this tool to access all available data for a single CAP parcel, including administrative and spatial attributes.
187
  """
188
+ return make_api_request(f"/geographical-references/cap-parcels/{cap_id}.json")
189
 
190
  @mcp.tool()
191
+ async def get_municipalities(page: int = 1, country: str = None, city: str = None) -> str:
192
+ """
193
+ Retrieve a paginated list of municipalities, with optional filters for country and city.
194
+
195
  Args:
196
+ page (int, optional): Page number for pagination (default: 1).
197
+ country (str, optional): Country name to filter municipalities.
198
+ city (str, optional): City name for more precise filtering.
199
+
200
+ Returns:
201
+ str: JSON string containing municipalities matching the filters.
202
+
203
+ This tool is useful for exploring administrative boundaries and locating municipalities by name or country.
204
  """
205
+ params = {"page": page}
206
+ if country: params["country"] = country
207
+ if city: params["city"] = city
208
+ return make_api_request("/geographical-references/municipalities.json", params)
209
 
 
210
  @mcp.tool()
211
+ async def get_municipality(municipality_id: str) -> str:
212
+ """
213
+ Retrieve detailed information about a specific municipality.
214
+
215
+ Args:
216
+ municipality_id (str): Unique identifier of the municipality.
217
+
218
+ Returns:
219
+ str: JSON string with detailed information about the municipality.
220
+
221
+ Use this tool to access all available data for a single municipality, including administrative and spatial attributes.
222
+ """
223
+ return make_api_request(f"/geographical-references/municipalities/{municipality_id}.json")
224
 
225
  @mcp.tool()
226
+ async def get_productions(page: int = 1, family: str = None, usage: str = None) -> str:
227
+ """
228
+ Retrieve a paginated list of production data, with optional filters for family and usage.
229
+
230
  Args:
231
+ page (int, optional): Page number for pagination (default: 1).
232
+ family (str, optional): Production family (e.g., crop type).
233
+ usage (str, optional): Usage type (e.g., food, feed).
234
+
235
+ Returns:
236
+ str: JSON string containing production data matching the filters.
237
+
238
+ This tool is useful for analyzing agricultural production by type and intended use.
239
  """
240
+ params = {"page": page}
241
+ if family: params["family"] = family
242
+ if usage: params["usage"] = usage
243
+ return make_api_request("/production/productions.json", params)
244
 
245
  @mcp.tool()
246
+ async def get_cropsets(page: int = 1) -> str:
247
+ """
248
+ Retrieve a paginated list of phytosanitary cropsets.
249
+
250
  Args:
251
+ page (int, optional): Page number for pagination (default: 1).
252
+
253
+ Returns:
254
+ str: JSON string containing cropset data.
255
+
256
+ This tool provides access to phytosanitary cropsets, which are important for plant protection and regulatory compliance.
257
  """
258
+ params = {"page": page}
259
+ return make_api_request("/phytosanitary/cropsets.json", params)
260
 
261
  @mcp.tool()
262
+ async def get_phytosanitary_products(page: int = 1, type: str = None, state: str = None) -> str:
263
+ """
264
+ Retrieve a paginated list of phytosanitary products, with optional filters for type and state.
265
+
266
+ Args:
267
+ page (int, optional): Page number for pagination (default: 1).
268
+ type (str, optional): Product type (e.g., herbicide, fungicide).
269
+ state (str, optional): Product state (e.g., approved, withdrawn).
270
+
271
+ Returns:
272
+ str: JSON string containing phytosanitary products matching the filters.
273
+
274
+ This tool is useful for exploring available plant protection products and their regulatory status.
275
+ """
276
+ params = {"page": page}
277
+ if type: params["type"] = type
278
+ if state: params["state"] = state
279
+ return make_api_request("/phytosanitary/products.json", params)
280
 
281
  @mcp.tool()
282
+ async def get_phytosanitary_symbols(page: int = 1) -> str:
283
+ """
284
+ Retrieve a paginated list of phytosanitary symbols.
285
+
286
  Args:
287
+ page (int, optional): Page number for pagination (default: 1).
288
+
289
+ Returns:
290
+ str: JSON string containing phytosanitary symbols.
291
+
292
+ This tool provides access to symbols used in plant protection and regulatory documentation.
293
  """
294
+ params = {"page": page}
295
+ return make_api_request("/phytosanitary/symbols.json", params)
296
 
297
  @mcp.tool()
298
+ async def get_seed_varieties(page: int = 1, species: str = None) -> str:
299
+ """
300
+ Retrieve a paginated list of seed varieties, optionally filtered by species.
301
+
302
  Args:
303
+ page (int, optional): Page number for pagination (default: 1).
304
+ species (str, optional): Species name to filter seed varieties.
305
+
306
+ Returns:
307
+ str: JSON string containing seed varieties matching the filters.
308
+
309
+ This tool is useful for exploring available seed varieties for different crops.
310
  """
311
+ params = {"page": page}
312
+ if species: params["species"] = species
313
+ return make_api_request("/seeds/varieties.json", params)
314
 
315
  @mcp.tool()
316
+ async def get_vine_varieties(page: int = 1, category: str = None, color: str = None) -> str:
317
+ """
318
+ Retrieve a paginated list of vine varieties, with optional filters for category and color.
319
+
320
  Args:
321
+ page (int, optional): Page number for pagination (default: 1).
322
+ category (str, optional): Vine category (e.g., table, wine).
323
+ color (str, optional): Grape color (e.g., red, white).
324
+
325
+ Returns:
326
+ str: JSON string containing vine varieties matching the filters.
327
+
328
+ This tool is useful for exploring grapevine diversity and selecting varieties for viticulture.
329
  """
330
+ params = {"page": page}
331
+ if category: params["category"] = category
332
+ if color: params["color"] = color
333
+ return make_api_request("/viticulture/vine-varieties.json", params)
334
 
 
335
  @mcp.tool()
336
+ async def get_weather_stations(page: int = 1, country: str = None, name: str = None) -> str:
337
+ """
338
+ Retrieve a paginated list of weather stations, with optional filters for country and station name.
339
+
340
+ Args:
341
+ page (int, optional): Page number for pagination (default: 1).
342
+ country (str, optional): Country name to filter stations.
343
+ name (str, optional): Station name for more precise filtering.
344
+
345
+ Returns:
346
+ str: JSON string containing weather stations matching the filters.
347
+
348
+ This tool is useful for discovering available weather stations and narrowing down by location or name.
349
+ """
350
+ params = {"page": page}
351
+ if country: params["country"] = country
352
+ if name: params["name"] = name
353
+ return make_api_request("/weather/stations.json", params)
354
 
 
355
  @mcp.tool()
356
+ async def get_weather_station(station_code: str) -> str:
357
+ """
358
+ Retrieve detailed information about a specific weather station.
359
+
360
+ Args:
361
+ station_code (str): Unique code identifying the weather station.
362
+
363
+ Returns:
364
+ str: JSON string with detailed information about the weather station.
365
+
366
+ Use this tool to access metadata and attributes for a single weather station.
367
+ """
368
+ return make_api_request(f"/weather/stations/{station_code}.json")
369
 
370
  @mcp.tool()
371
+ async def get_weather_data(station_code: str, start: str = None, end: str = None) -> str:
372
+ """
373
+ Retrieve hourly weather reports for a specific station, optionally filtered by date range.
374
+
375
+ Args:
376
+ station_code (str): Unique code identifying the weather station.
377
+ start (str, optional): Start date/time in ISO format (e.g., '2024-01-01T00:00:00Z').
378
+ end (str, optional): End date/time in ISO format (e.g., '2024-01-31T23:59:59Z').
379
+
380
+ Returns:
381
+ str: JSON string containing hourly weather reports for the specified station and date range.
382
+
383
+ This tool is useful for analyzing weather data over time for a given location.
384
+ """
385
+ params = {}
386
+ if start: params["start"] = start
387
+ if end: params["end"] = end
388
+ return make_api_request(f"/weather/stations/{station_code}/hourly-reports.json", params)
389
 
390
  @mcp.tool()
391
+ async def get_parcel_identifier_geojson(latitude: float, longitude: float) -> str:
392
+ """
393
+ Retrieve parcel identifier information in GeoJSON format for a given geographic location.
394
+
395
+ Args:
396
+ latitude (float): Latitude of the point of interest.
397
+ longitude (float): Longitude of the point of interest.
398
+
399
+ Returns:
400
+ str: GeoJSON string containing parcel identifier data for the specified coordinates.
401
+
402
+ This tool allows you to obtain spatial parcel identification data for mapping and GIS applications.
403
+ """
404
+ params = {"latitude": latitude, "longitude": longitude}
405
+ return make_api_request("/tools/parcel-identifier.geojson", params)
406
+
407
+ @mcp.tool()
408
+ async def get_cadastral_parcel_geolocation(parcel_id: str) -> str:
409
+ """
410
+ Retrieve geolocation data for a specific cadastral parcel in GeoJSON format.
411
+
412
+ Args:
413
+ parcel_id (str): Unique identifier of the cadastral parcel.
414
+
415
+ Returns:
416
+ str: GeoJSON string with spatial data for the parcel.
417
+
418
+ Use this tool to obtain the geometry of a cadastral parcel for mapping or spatial analysis.
419
+ """
420
+ return make_api_request(f"/geographical-references/cadastral-parcels/{parcel_id}/geolocation.geojson")
421
+
422
+ @mcp.tool()
423
+ async def get_cap_parcel_geolocation(cap_id: str) -> str:
424
+ """
425
+ Retrieve geolocation data for a specific CAP parcel in GeoJSON format.
426
+
427
+ Args:
428
+ cap_id (str): Unique identifier of the CAP parcel.
429
+
430
+ Returns:
431
+ str: GeoJSON string with spatial data for the CAP parcel.
432
+
433
+ Use this tool to obtain the geometry of a CAP parcel for mapping or spatial analysis.
434
+ """
435
+ return make_api_request(f"/geographical-references/cap-parcels/{cap_id}/geolocation.geojson")
436
 
 
437
  @mcp.tool()
438
+ async def get_municipality_cadastre(municipality_id: str) -> str:
439
+ """
440
+ Retrieve cadastre data for a municipality in GeoJSON format.
441
+
442
+ Args:
443
+ municipality_id (str): Unique identifier of the municipality.
444
+
445
+ Returns:
446
+ str: GeoJSON string with cadastre data for the municipality.
447
+
448
+ Use this tool to obtain the spatial extent of a municipality's cadastre for mapping or GIS analysis.
449
+ """
450
+ return make_api_request(f"/geographical-references/municipalities/{municipality_id}/cadastre.geojson")
451
 
 
452
  @mcp.tool()
453
+ async def get_municipality_cap_parcels(municipality_id: str) -> str:
454
+ """
455
+ Retrieve CAP parcels geolocation data for a municipality in GeoJSON format.
456
+
457
+ Args:
458
+ municipality_id (str): Unique identifier of the municipality.
459
+
460
+ Returns:
461
+ str: GeoJSON string with CAP parcels spatial data for the municipality.
462
+
463
+ Use this tool to obtain the geometry of all CAP parcels within a municipality for mapping or spatial analysis.
464
+ """
465
+ return make_api_request(f"/geographical-references/municipalities/{municipality_id}/cap-parcels.geojson")
466
 
467
  if __name__ == "__main__":
468
  mcp.run(transport='stdio')
lexison ADDED
@@ -0,0 +1 @@
 
 
1
+ {"@id":"http://lexicon.osfarm.org/geographical-references/municipalities.json","title":"Communes","breadcrumbs":[{"@type":"Link","value":"Accueil","method":"GET","href":"/"},{"@type":"Link","value":"Références géographiques","method":"GET","href":"/geographical-references"}],"form":{"country":{"@type":"Select","label":"Pays","options":{"FR":"France"},"required":false},"city":{"@type":"Text","label":"Ville","required":false}},"table":{"columns":{"country":"Pays","city":"Ville","city-code":"Code commune","postal-code":"Code postal","details":"Détails"},"rows":[{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AAST"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64460"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64001_64460_AAST_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABAINVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"55001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"55130"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/55001_55130_ABAINV_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABANCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"59001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"59268"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/59001_59268_ABANCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABANCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60220"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60001_60220_ABANCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABAUCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54610"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54001_54610_ABAUCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABAUCOURT HAUTECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"55002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"55400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/55002_55400_ABAUCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABAUCOURT HAUTECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"55002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"55400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/55002_55400_ABAUCO_HAUTECOURTLE"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBANS DESSOUS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25320"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25001_25320_ABBANS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBANS DESSUS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25440"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25002_25440_ABBANS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBARETZ"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"44001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"44170"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/44001_44170_ABBARE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60430"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60002_60430_ABBECO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"02001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"02300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/02001_02300_ABBECO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBENANS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25340"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25003_25340_ABBENA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBEVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80100"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80001_80100_ABBEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBEVILLE LA RIVIERE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"91001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"91150"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/91001_91150_ABBEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBEVILLE LES CONFLANS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54002_54800_ABBEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBEVILLE ST LUCIEN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60480"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60003_60480_ABBEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABBEVILLERS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25310"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25004_25310_ABBEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABEILHAN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34290"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34001_34290_ABEILH_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABELCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"70001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"70300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/70001_70300_ABELCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABERE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64160"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64002_64160_ABERE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABERGEMENT LA RONCE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"39001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"39500"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/39001_39500_ABERGE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABERGEMENT LE GRAND"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"39002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"39600"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/39002_39600_ABERGE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABERGEMENT LE PETIT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"39003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"39800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/39003_39800_ABERGE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABERGEMENT LES THESY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"39004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"39110"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/39004_39110_ABERGE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABIDOS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64150"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64003_64150_ABIDOS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABILLY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"37001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"37160"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/37001_37160_ABILLY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABITAIN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64390"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64004_64390_ABITAI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABJAT SUR BANDIAT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"24001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"24300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/24001_24300_ABJATS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLAIN ST NAZAIRE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62153"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62001_62153_ABLAIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLAINCOURT PRESSOIR"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80320"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80002_80320_ABLAIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLAINZEVELLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62116"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62002_62116_ABLAIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLANCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"51001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"51240"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/51001_51240_ABLANC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLEIGES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"95002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"95450"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/95002_95450_ABLEIG_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLIS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"78003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"78660"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/78003_78660_ABLIS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLON"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"14001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"14600"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/14001_14600_ABLON_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABLON SUR SEINE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"94001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"94480"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/94001_94480_ABLONS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABOEN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"42001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"42380"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/42001_42380_ABOEN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57920"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57001_57920_ABONCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54115"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54003_54115_ABONCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONCOURT GESINCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"70002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"70500"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/70002_70500_ABONCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONCOURT SUR SEILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57590"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57002_57590_ABONCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONDANCE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"74001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"74360"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/74001_74360_ABONDA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABONDANT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"28001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"28410"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/28001_28410_ABONDA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABOS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64360"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64005_64360_ABOS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABRESCHVILLER"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57560"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57003_57560_ABRESC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABREST"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"03001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"03200"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/03001_03200_ABREST_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABRIES RISTOLAS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"05001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"05460"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/05001_05460_ABRIES_ABRIES"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABRIES RISTOLAS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"05001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"05460"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/05001_05460_ABRIES_RISTOLAS"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABSCON"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"59002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"59215"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/59002_59215_ABSCON_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABZAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"33001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"33230"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/33001_33230_ABZAC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ABZAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"16001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"16500"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/16001_16500_ABZAC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACCOLANS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25250"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25005_25250_ACCOLA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACCONS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"07001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"07160"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/07001_07160_ACCONS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACCOUS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64490"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64006_64490_ACCOUS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHAIN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57340"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57004_57340_ACHAIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHEN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57412"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57006_57412_ACHEN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHENHEIM"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"67001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"67204"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/67001_67204_ACHENH_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHERES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"18001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"18250"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/18001_18250_ACHERE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHERES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"78005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"78260"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/78005_78260_ACHERE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHERES LA FORET"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"77001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"77760"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/77001_77760_ACHERE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHERY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"02002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"02800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/02002_02800_ACHERY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHEUX EN AMIENOIS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80560"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80003_80560_ACHEUX_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHEUX EN VIMEU"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80210"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80004_80210_ACHEUX_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHEVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62320"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62003_62320_ACHEVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHEY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"70003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"70180"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/70003_70180_ACHEY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHICOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62217"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62004_62217_ACHICO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHIET LE GRAND"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62121"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62005_62121_ACHIET_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHIET LE PETIT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62121"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62006_62121_ACHIET_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHUN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"58001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"58110"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/58001_58110_ACHUN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACHY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60690"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60004_60690_ACHY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACIGNE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"35001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"35690"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/35001_35690_ACIGNE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACLOU"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"27001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"27800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/27001_27800_ACLOU_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACON"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"27002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"27570"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/27002_27570_ACON_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACOUA"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"97601"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"97630"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/97601_97630_ACOUA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACQ"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62007"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62144"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62007_62144_ACQ_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACQUIGNY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"27003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"27400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/27003_27400_ACQUIG_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACQUIGNY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"27003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"27400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/27003_27400_ACQUIG_LESPLANCHES"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACQUIN WESTBECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62008"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62380"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62008_62380_ACQUIN_WESTBECOURT"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACQUIN WESTBECOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62008"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62380"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62008_62380_ACQUIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"02003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"02200"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/02003_02200_ACY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACY EN MULTIEN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60620"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60005_60620_ACYENM_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ACY ROMANCE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"08001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"08300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/08001_08300_ACYROM_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAINCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57007"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57580"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57007_57580_ADAINC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAINVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"78006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"78113"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/78006_78113_ADAINV_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAM LES PASSAVANT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25360"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25006_25360_ADAMLE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAM LES VERCEL"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25007"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25530"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25007_25530_ADAMLE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAMSWILLER"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"67002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"67320"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/67002_67320_ADAMSW_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADAST"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"65001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"65260"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/65001_65260_ADAST_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"65002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"65100"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/65002_65100_ADE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADELANGE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"57008"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"57380"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/57008_57380_ADELAN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADELANS ET LE VAL DE BITHAINE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"70004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"70200"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/70004_70200_ADELAN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADERVIELLE POUCHERGUES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"65003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"65240"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/65003_65240_ADERVI_POUCHERGUES"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADERVIELLE POUCHERGUES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"65003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"65240"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/65003_65240_ADERVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADILLY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"79002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"79200"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/79002_79200_ADILLY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADINFER"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62009"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62116"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62009_62116_ADINFE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADISSAN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34230"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34002_34230_ADISSA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADON"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"45001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"45230"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/45001_45230_ADON_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"ADRIERS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"86001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"86430"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/86001_86430_ADRIER_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFA"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"2A001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"20167"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/2A001_20167_AFA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFFIEUX"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"19001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"19260"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/19001_19260_AFFIEU_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFFLEVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54004_54800_AFFLEV_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFFOUX"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"69001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"69170"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/69001_69170_AFFOUX_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFFRACOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54740"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54005_54740_AFFRAC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AFFRINGUES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62010"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62380"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62010_62380_AFFRIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGASSAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"31001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"31230"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/31001_31230_AGASSA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGDE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34003_34300_AGDE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGDE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34300"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34003_34300_AGDE_LECAPDAGDE"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGEL"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34210"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34004_34210_AGEL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGEN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"47001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"47000"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/47001_47000_AGEN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGEN D'AVEYRON"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"12001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"12630"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/12001_12630_AGENDA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGENCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"21001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"21700"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/21001_21700_AGENCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGENVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80370"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80005_80370_AGENVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGENVILLERS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"80006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"80150"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/80006_80150_AGENVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGEVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"52001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"52340"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/52001_52340_AGEVIL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGEY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"21002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"21410"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/21002_21410_AGEY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGHIONE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"2B002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"20270"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/2B002_20270_AGHION_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGINCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"54006"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"54770"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/54006_54770_AGINCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGME"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"47002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"47350"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/47002_47350_AGME_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"47003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"47800"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/47003_47800_AGNAC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNAT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"43001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"43100"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/43001_43100_AGNAT_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNEAUX"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"50002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"50180"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/50002_50180_AGNEAU_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNETZ"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"60007"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"60600"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/60007_60600_AGNETZ_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNEZ LES DUISANS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62011"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62161"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62011_62161_AGNEZL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNICOURT ET SECHELLES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"02004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"02340"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/02004_02340_AGNICO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNIERES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62012"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62690"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62012_62690_AGNIER_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNIN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"38003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"38150"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/38003_38150_AGNIN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNOS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64007"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64007_64400_AGNOS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGNY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"62013"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"62217"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/62013_62217_AGNY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGON COUTAINVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"50003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"50230"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/50003_50230_AGONCO_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGONAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"24002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"24460"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/24002_24460_AGONAC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGONES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"34005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"34190"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/34005_34190_AGONES_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGONGES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"03002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"03210"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/03002_03210_AGONGE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGOS VIDALOS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"65004"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"65400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/65004_65400_AGOSVI_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGRIS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"16003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"16110"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/16003_16110_AGRIS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGUDELLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"17002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"17500"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/17002_17500_AGUDEL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGUESSAC"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"12002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"12520"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/12002_12520_AGUESS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGUILCOURT"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"02005"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"02190"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/02005_02190_AGUILC_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGUTS"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"81001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"81470"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/81001_81470_AGUTS_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AGY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"14003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"14400"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/14003_14400_AGY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHAXE ALCIETTE BASCASSAN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64008"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64220"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64008_64220_AHAXEA_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHETZE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64009"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64210"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64009_64210_AHETZE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHEVILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"88002"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"88500"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/88002_88500_AHEVIL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHUILLE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"53001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"53940"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/53001_53940_AHUILL_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHUN"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"23001"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"23150"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/23001_23150_AHUN_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AHUY"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"21003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"21121"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/21003_21121_AHUY_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AIBES"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"59003"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"59149"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/59003_59149_AIBES_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AIBRE"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"25008"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"25750"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/25008_25750_AIBRE_"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AICIRITS CAMOU SUHAST"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64010"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64120"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64010_64120_AICIRI_CAMOUMIXESUH"}},{"country":{"@type":"Text","label":"Pays","value":"France"},"city":{"@type":"Text","label":"Code postal","value":"AICIRITS CAMOU SUHAST"},"city-code":{"@type":"Text","label":"geographical_references_municipality_postal_code_code","value":"64010"},"postal-code":{"@type":"Text","label":"geographical_references_municipality_code","value":"64120"},"details":{"@type":"Link","value":"Voir","method":"GET","href":"/geographical-references/municipalities/64010_64120_AICIRI_"}}]},"items-per-page":150,"items-count":150,"items-total":39192,"page":1,"total-pages":262,"pages":[{"@type":"Link","value":"1","method":"GET","href":"/geographical-references/municipalities.json?page=1"},{"@type":"Link","value":"2","method":"GET","href":"/geographical-references/municipalities.json?page=2"},{"@type":"Link","value":"3","method":"GET","href":"/geographical-references/municipalities.json?page=3"},{"@type":"Link","value":"4","method":"GET","href":"/geographical-references/municipalities.json?page=4"},{"@type":"Link","value":"5","method":"GET","href":"/geographical-references/municipalities.json?page=5"},{"@type":"Link","value":"6","method":"GET","href":"/geographical-references/municipalities.json?page=6"}],"navigation":{"next-page":{"@type":"Link","value":"Page suivante","method":"GET","href":"/geographical-references/municipalities.json?page=2"},"last-page":{"@type":"Link","value":"262","method":"GET","href":"/geographical-references/municipalities.json?page=262"}},"formats":{"html":{"@type":"Link","value":"HTML","method":"GET","href":"/geographical-references/municipalities"},"json":{"@type":"Link","value":"JSON","method":"GET","href":"/geographical-references/municipalities.json"},"csv":{"@type":"Link","value":"CSV","method":"GET","href":"/geographical-references/municipalities.csv"}}}