-
Notifications
You must be signed in to change notification settings - Fork 1
feat(server): init Geocoding MCP server #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis change introduces the initial codebase for a geocoding MCP server. It adds project configuration files, a license, documentation, and a TypeScript implementation of the server. The code integrates with the Nominatim API for geocoding and reverse geocoding, defines input schemas, registers tools with the MCP server, and sets up CI workflows for linting and release. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant MCPServer
participant GeocodeTool
participant NominatimClient
participant NominatimAPI
Client->>MCPServer: Send geocode or reverse_geocode request
MCPServer->>GeocodeTool: Invoke tool with parameters
GeocodeTool->>NominatimClient: Call geocodeAddress/reverseGeocode
NominatimClient->>NominatimAPI: HTTP GET /search or /reverse
NominatimAPI-->>NominatimClient: Return geocode results
NominatimClient-->>GeocodeTool: Return parsed results
GeocodeTool->>MCPServer: Format and return response
MCPServer-->>Client: Send geocode/reverse geocode result
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (6)
🚧 Files skipped from review as they are similar to previous changes (6)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Nitpick comments (4)
.github/workflows/release.yml (1)
28-30
: Consider making the version update more robust.The
sed
command for updating the version in the source file could be fragile if the version pattern changes or if there are multiple version strings.Consider using a more targeted approach or making the regex more specific:
- sed -i "s/version: \"[0-9]*\.[0-9]*\.[0-9]*\"/version: \"${{ env.VERSION }}\"/" src/index.ts + sed -i "s/version: \"[0-9]\+\.[0-9]\+\.[0-9]\+\(-[a-zA-Z0-9.-]\+\)\?\"/version: \"${{ env.VERSION }}\"/" src/index.tsThis pattern also handles prerelease versions with suffixes like
-beta.1
.tsconfig.json (1)
10-10
: Consider removing JSX configuration for a server-only project.The
"jsx": "react-jsx"
setting appears unnecessary for a geocoding MCP server that doesn't use React components.If JSX isn't needed, consider removing this line:
- "jsx": "react-jsx",
src/types/geocodeTypes.ts (1)
6-8
: Consider simplifying binary flag types.The union types
z.union([z.literal(0), z.literal(1)])
for binary flags could be simplified for better readability.Consider using a more semantic approach:
- addressdetails: z.union([z.literal(0), z.literal(1)]).optional().default(0), - extratags: z.union([z.literal(0), z.literal(1)]).optional().default(0), - namedetails: z.union([z.literal(0), z.literal(1)]).optional().default(0), + addressdetails: z.coerce.number().int().min(0).max(1).optional().default(0), + extratags: z.coerce.number().int().min(0).max(1).optional().default(0), + namedetails: z.coerce.number().int().min(0).max(1).optional().default(0),Or create a reusable schema:
const binaryFlag = z.union([z.literal(0), z.literal(1)]).optional().default(0); export const GeocodeParamsSchema: z.ZodRawShape = { // ... addressdetails: binaryFlag, extratags: binaryFlag, namedetails: binaryFlag, // ... }Also applies to: 12-15
src/tools/reverseGeocode.ts (1)
51-55
: Consider adding explicit error handling.While the current implementation relies on framework error handling, adding explicit error handling could provide better user experience.
Consider wrapping the API call in a try-catch block:
async (params: ReverseGeocodeParams) => { + try { const result = await reverseGeocode(params) return handleGeocodeResult(result) + } catch (error) { + throw new Error(`Reverse geocoding failed: ${error instanceof Error ? error.message : 'Unknown error'}`) + } },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (15)
.github/workflows/lint.yml
(1 hunks).github/workflows/release.yml
(1 hunks).gitignore
(1 hunks)LICENSE
(1 hunks)README.md
(1 hunks)eslint.config.js
(1 hunks)package.json
(1 hunks)src/clients/nominatimClient.ts
(1 hunks)src/index.ts
(1 hunks)src/tools/geocode.ts
(1 hunks)src/tools/reverseGeocode.ts
(1 hunks)src/tools/toolUtils.ts
(1 hunks)src/types/geocodeTypes.ts
(1 hunks)src/types/reverseGeocodeTypes.ts
(1 hunks)tsconfig.json
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/tools/reverseGeocode.ts (2)
src/types/reverseGeocodeTypes.ts (2)
ReverseGeocodeParams
(3-17)ReverseGeocodeParams
(20-20)src/clients/nominatimClient.ts (1)
reverseGeocode
(25-28)
src/tools/geocode.ts (2)
src/types/geocodeTypes.ts (2)
GeocodeParams
(3-17)GeocodeParams
(20-20)src/clients/nominatimClient.ts (1)
geocodeAddress
(20-23)
src/clients/nominatimClient.ts (2)
src/types/geocodeTypes.ts (2)
GeocodeParams
(3-17)GeocodeParams
(20-20)src/types/reverseGeocodeTypes.ts (2)
ReverseGeocodeParams
(3-17)ReverseGeocodeParams
(20-20)
🪛 actionlint (1.7.7)
.github/workflows/release.yml
14-14: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue
(action)
🪛 Biome (1.9.4)
src/clients/nominatimClient.ts
[error] 14-14: Avoid the delete operator which can impact performance.
Unsafe fix: Use an undefined assignment instead.
(lint/performance/noDelete)
🔇 Additional comments (18)
LICENSE (1)
3-3
: LGTM! Standard copyright update.The copyright holder change from "Geocoding AI" to "Srihari Thalla" is appropriate for the project initialization.
.github/workflows/lint.yml (1)
1-24
: LGTM! Well-structured CI workflow.The lint workflow follows GitHub Actions best practices with clear step names, appropriate triggers, and official actions. The use of Bun is consistent with the project's runtime choice.
.gitignore (2)
37-37
: Clarify the.trae
entry.The
.trae
entry is unusual for a standard Node.js project. Please confirm if this is specific to your tooling or if it should be removed.
1-38
: LGTM! Comprehensive gitignore coverage.The gitignore file properly covers all essential categories for a TypeScript/Node.js project including dependencies, build outputs, environment files, caches, and IDE-specific files.
src/index.ts (1)
1-24
: LGTM! Well-structured MCP server implementation.The server setup follows MCP SDK best practices with:
- Proper ES module imports (including correct .js extensions for TypeScript)
- Clean server configuration matching package.json version
- Modular tool registration
- Appropriate error handling with stdio transport
README.md (1)
1-35
: LGTM! Comprehensive project documentation.The README provides clear installation instructions and proper Claude Desktop configuration. The dual licensing approach (MIT for codebase, GPLv2 for documentation) appropriately addresses the Nominatim API documentation licensing requirements.
package.json (1)
1-35
: LGTM! Well-configured package for MCP server.The package configuration properly sets up an ES module with scoped naming, appropriate scripts, and correct dependencies for an MCP server implementation.
.github/workflows/release.yml (1)
38-50
: Well-structured release workflow with proper prerelease handling.The workflow correctly handles both regular releases and prereleases, with appropriate NPM tagging. The conditional publishing logic ensures prereleases go to the "canary" tag while regular releases go to the default tag.
tsconfig.json (1)
1-32
: Excellent TypeScript configuration for modern Node.js development.The configuration uses modern settings appropriate for Node.js ESM with strict type checking enabled. The choice to disable some stricter flags like
noUnusedLocals
andnoUnusedParameters
is reasonable for development convenience.src/types/geocodeTypes.ts (1)
1-21
: Comprehensive and well-structured parameter schema.The schema covers all relevant Nominatim API parameters with appropriate types, defaults, and validation constraints. The use of Zod ensures runtime type safety for API interactions.
src/tools/reverseGeocode.ts (1)
6-57
: Excellent tool implementation with comprehensive documentation.The tool registration is well-implemented with:
- Clear, detailed parameter descriptions matching the Nominatim API
- Proper TypeScript typing with Zod schema validation
- Clean async implementation with result processing
- Good separation of concerns using utility functions
The documentation is particularly thorough, providing zoom level mappings and clear explanations of each parameter.
src/tools/geocode.ts (3)
1-4
: Import statement looks good with proper module extensions.The imports are correctly structured with
.js
extensions for ES modules and proper type imports.
6-48
: Comprehensive tool registration with excellent documentation.The tool registration is well-implemented with:
- Clear tool name and description
- Extensive parameter documentation covering all Nominatim search API features
- Proper async handling and error propagation
- Clean separation of concerns using imported utilities
The documentation is particularly thorough, covering all input parameters with detailed explanations that will help users understand the geocoding capabilities.
50-50
: Export statement is correct.Default export follows proper ES module conventions.
src/types/reverseGeocodeTypes.ts (1)
19-20
: Type export pattern is correct.The schema object creation and type inference follow proper zod patterns.
src/clients/nominatimClient.ts (3)
5-10
: Axios client configuration is properly set up.The client configuration includes:
- Appropriate base URL for Nominatim service
- Custom User-Agent header for API identification
- Clean separation of concerns
20-23
: Geocode function implementation is correct.The function properly:
- Uses the search endpoint for geocoding
- Passes parameters correctly to the API
- Processes results through the helper function
25-28
:✅ Verification successful
Reverse geocode function needs clarification on array wrapping.
The implementation differs from the geocode function by wrapping the response data in an array. This suggests the reverse geocoding API returns a single object rather than an array.
Please verify that the Nominatim reverse API returns a single object rather than an array, justifying the
[response.data]
wrapping. If this is incorrect, the function should handle the response consistently withgeocodeAddress
.
🏁 Script executed:
#!/bin/bash # Verify Nominatim reverse API response format curl -s "https://nominatim.geocoding.ai/reverse?lat=40.7589&lon=-73.9851&format=jsonv2" | jq 'type'Length of output: 108
Reverse geocode array wrapping is correct
The Nominatim reverse endpoint returns a single JSON object (not an array), so wrapping
response.data
in[response.data]
is required forparseResult
, which expects an array of results. No changes needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/types/reverseGeocodeTypes.ts (1)
11-12
: Variable naming inconsistency noted.This file uses
schema
whilegeocodeTypes.ts
uses_schema
for the same purpose. Consider standardizing the variable naming across both type files for consistency.src/tools/prepareResponse.ts (1)
24-24
: Consider using named export instead of default export.Default exports can make refactoring and tree-shaking more difficult. Consider using a named export for better maintainability.
🧹 Nitpick comments (1)
src/types/geocodeTypes.ts (1)
11-12
: Inconsistent variable naming across type files.While the naming conflict mentioned in past reviews has been resolved, there's an inconsistency with the schema variable naming between this file and
reverseGeocodeTypes.ts
.For consistency, consider using the same variable naming pattern across both files:
-const _schema = z.object(GeocodeParamsSchema) +const schema = z.object(GeocodeParamsSchema)Or alternatively, update
reverseGeocodeTypes.ts
to use_schema
to match this file's pattern.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
bun.lock
is excluded by!**/*.lock
📒 Files selected for processing (10)
.github/workflows/release.yml
(1 hunks).gitignore
(1 hunks)package.json
(1 hunks)src/clients/nominatimClient.ts
(1 hunks)src/tools/geocode.ts
(1 hunks)src/tools/prepareResponse.ts
(1 hunks)src/tools/reverseGeocode.ts
(1 hunks)src/types/commonTypes.ts
(1 hunks)src/types/geocodeTypes.ts
(1 hunks)src/types/reverseGeocodeTypes.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/types/commonTypes.ts
🚧 Files skipped from review as they are similar to previous changes (6)
- .gitignore
- .github/workflows/release.yml
- src/tools/reverseGeocode.ts
- src/tools/geocode.ts
- src/clients/nominatimClient.ts
- package.json
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/types/reverseGeocodeTypes.ts (1)
src/types/commonTypes.ts (1)
CommonNominatimParamsSchema
(3-14)
src/types/geocodeTypes.ts (1)
src/types/commonTypes.ts (1)
CommonNominatimParamsSchema
(3-14)
🔇 Additional comments (5)
src/types/geocodeTypes.ts (2)
1-2
: LGTM! Clean imports with proper file extensions.The imports are well-structured and include the necessary
.js
extension for ES modules.
4-9
: Well-structured geocoding parameter schema.The schema definition is comprehensive and follows good practices:
- Required
q
parameter with proper non-empty string validation- Proper reuse of common Nominatim parameters via spreading
- Appropriate optional parameters for geocoding use cases
- Valid enum values for
featureType
that align with typical geographic hierarchysrc/types/reverseGeocodeTypes.ts (2)
1-2
: LGTM! Consistent import pattern.The imports follow the same pattern as the geocode types file with proper ES module extensions.
4-9
: Excellent validation constraints for geographic data.The schema properly validates geographic coordinates and zoom levels:
- Latitude range (-90 to 90) is correct for valid geographic coordinates
- Longitude range (-180 to 180) is correct for valid geographic coordinates
- Zoom level range (0-18) aligns with standard map zoom levels
- Proper integration of common Nominatim parameters via spreading
src/tools/prepareResponse.ts (1)
1-1
: LGTM! Proper MCP SDK import.The import correctly pulls the necessary type from the MCP SDK.
Summary by CodeRabbit