Skip to content

Conversation

DaxServer
Copy link
Contributor

@DaxServer DaxServer commented May 31, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a geocoding server supporting address-to-coordinates and reverse geocoding using the Nominatim API.
    • Added tools for both geocoding and reverse geocoding with extensive parameter options and structured responses.
    • Provided TypeScript type safety and input validation for all geocoding operations.
  • Documentation
    • Added a comprehensive README with setup instructions, usage details, and licensing information.
  • Chores
    • Established project configuration files for TypeScript, ESLint, and gitignore.
    • Added automated workflows for linting and release management.
    • Updated license information.

Copy link

coderabbitai bot commented May 31, 2025

Walkthrough

This 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

File(s) Change Summary
.github/workflows/lint.yml
.github/workflows/release.yml
Added GitHub Actions workflows for linting on pull request events and automated releases triggered by release publishing.
.gitignore Added ignore rules for dependencies, build outputs, logs, coverage, environment files, IDE files, and OS metadata.
LICENSE Changed copyright holder in MIT license from "Geocoding AI" to "Srihari Thalla."
README.md Added project documentation, installation instructions, usage, and licensing details.
package.json
tsconfig.json
Added package manifest and TypeScript configuration for the project.
eslint.config.js Added ESLint configuration with custom rules and TypeScript support.
src/index.ts Implemented MCP server initialization, tool registration, and main process logic.
src/clients/nominatimClient.ts Added Nominatim API client with exported geocode and reverse geocode functions.
src/tools/geocode.ts
src/tools/reverseGeocode.ts
Added tool registration functions for geocoding and reverse geocoding on the MCP server.
src/tools/prepareResponse.ts Added utility function to format geocode results for tool responses.
src/types/commonTypes.ts
src/types/geocodeTypes.ts
src/types/reverseGeocodeTypes.ts
Added Zod schemas and TypeScript types for common, geocode, and reverse geocode parameters.

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
Loading

Poem

🗺️
The server awakens, a rabbit hops near,
Geocoding magic—addresses appear!
With Nominatim’s wisdom and MCP’s might,
Coordinates and places are found day or night.
CI/CD is ready, the code’s shining bright—
Hooray for new journeys, mapped out just right!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b34941b and 8541092.

📒 Files selected for processing (6)
  • src/index.ts (1 hunks)
  • src/tools/geocode.ts (1 hunks)
  • src/tools/prepareResponse.ts (1 hunks)
  • src/tools/reverseGeocode.ts (1 hunks)
  • src/types/reverseGeocodeTypes.ts (1 hunks)
  • tsconfig.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/index.ts
  • src/tools/prepareResponse.ts
  • src/types/reverseGeocodeTypes.ts
  • tsconfig.json
  • src/tools/geocode.ts
  • src/tools/reverseGeocode.ts
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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.ts

This 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

📥 Commits

Reviewing files that changed from the base of the PR and between c69bd81 and 35fc8ed.

⛔ 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 and noUnusedParameters 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 with geocodeAddress.


🏁 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 for parseResult, which expects an array of results. No changes needed.

Copy link

@coderabbitai coderabbitai bot left a 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 while geocodeTypes.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

📥 Commits

Reviewing files that changed from the base of the PR and between 35fc8ed and b34941b.

⛔ 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 hierarchy
src/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.

@DaxServer DaxServer merged commit 7dd9866 into main May 31, 2025
2 checks passed
@DaxServer DaxServer deleted the init branch May 31, 2025 16:46
@coderabbitai coderabbitai bot mentioned this pull request Oct 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant