# Directory Structure
```
├── .gitignore
├── .mcp.json
├── .python-version
├── LICENSE
├── main.py
├── pyproject.toml
├── README.md
└── uv.lock
```
# Files
--------------------------------------------------------------------------------
/.python-version:
--------------------------------------------------------------------------------
```
1 | 3.10
2 |
```
--------------------------------------------------------------------------------
/.mcp.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "mcpServers": {
3 | "zipcode-search": {
4 | "command": "uv",
5 | "args": ["run", "python", "main.py"]
6 | }
7 | }
8 | }
9 |
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | #.python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # IDE
132 | .vscode/
133 | .idea/
134 | *.swp
135 | *.swo
136 |
137 | # macOS
138 | .DS_Store
139 |
140 | # Windows
141 | Thumbs.db
142 | ehthumbs.db
143 | Desktop.ini
144 |
145 | # Linux
146 | *~
147 |
148 | # Keep important MCP files
149 | !.mcp.json
150 | !.python-version
151 |
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # Zipcode Search MCP Server
2 |
3 | [](https://opensource.org/licenses/MIT)
4 | [](https://www.python.org/downloads/)
5 |
6 | A Model Context Protocol (MCP) server that provides Japanese postal code to address lookup functionality. This server can be integrated with AI assistants and other MCP clients to enable postal code search capabilities.
7 |
8 | ## Features
9 |
10 | - 🏣 Search Japanese addresses by 7-digit postal codes
11 | - 🔌 Model Context Protocol (MCP) compatible
12 | - 🚀 Fast and lightweight implementation
13 | - 🌐 Uses reliable Zipcloud API as data source
14 | - 🛡️ Built-in error handling and validation
15 |
16 | ## Tech Stack
17 |
18 | - **Python 3.10+**
19 | - **MCP (Model Context Protocol)** - AI tool integration protocol
20 | - **FastMCP** - MCP server framework
21 | - **httpx** - Modern HTTP client
22 | - **Zipcloud API** - Japanese postal code data source
23 |
24 | ## Installation
25 |
26 | ### Prerequisites
27 |
28 | - Python 3.10 or higher
29 | - [uv](https://docs.astral.sh/uv/) (recommended) or pip
30 |
31 | ### Quick Start
32 |
33 | 1. Clone the repository:
34 | ```bash
35 | git clone https://github.com/rooking-oss/zipcode-search-mcp.git
36 | cd zipcode-search-mcp
37 | ```
38 |
39 | 2. Install dependencies using uv:
40 | ```bash
41 | uv sync
42 | ```
43 |
44 | Or with pip:
45 | ```bash
46 | pip install -e .
47 | ```
48 |
49 | 3. Run the MCP server:
50 | ```bash
51 | uv run python main.py
52 | ```
53 |
54 | ## MCP Client Configuration
55 |
56 | ### Claude Desktop
57 |
58 | Add the following configuration to your `claude_desktop_config.json`:
59 |
60 | ```json
61 | {
62 | "mcpServers": {
63 | "zipcode-search": {
64 | "command": "uv",
65 | "args": ["run", "python", "/path/to/zipcode-search-mcp/main.py"]
66 | }
67 | }
68 | }
69 | ```
70 |
71 | ### Other MCP Clients
72 |
73 | For other MCP clients, refer to the included `.mcp.json` configuration file or use the following connection details:
74 |
75 | - **Server Name**: `zipcode-search`
76 | - **Command**: `uv run python main.py`
77 | - **Working Directory**: Project root directory
78 |
79 | ## Available Tools
80 |
81 | ### search_zipcode
82 |
83 | Searches for a Japanese address using a postal code.
84 |
85 | **Parameters:**
86 | - `zipcode` (string): 7-digit postal code (e.g., "1000001")
87 |
88 | **Returns:**
89 | - `address` (string): The found address, or "Address not found" if no match
90 |
91 | **Example Usage:**
92 |
93 | In your MCP client (like Claude):
94 |
95 | ```
96 | What's the address for postal code 1000001?
97 | ```
98 |
99 | Or directly:
100 |
101 | ```
102 | Use the search_zipcode tool to find the address for postal code 1600020
103 | ```
104 |
105 | ## API Reference
106 |
107 | The server provides one tool through the MCP protocol:
108 |
109 | | Tool | Description | Input | Output |
110 | |------|-------------|-------|--------|
111 | | `search_zipcode` | Search address by postal code | `zipcode: string` | `{address: string}` |
112 |
113 | ## Development
114 |
115 | ### Project Structure
116 |
117 | ```
118 | zipcode-search-mcp/
119 | ├── main.py # MCP server implementation
120 | ├── pyproject.toml # Project configuration and dependencies
121 | ├── uv.lock # Dependency lock file
122 | ├── .mcp.json # MCP client configuration
123 | ├── .python-version # Python version specification
124 | ├── .gitignore # Git ignore rules
125 | └── README.md # This file
126 | ```
127 |
128 | ### Development Setup
129 |
130 | 1. Clone and install in development mode:
131 | ```bash
132 | git clone https://github.com/rooking-oss/zipcode-search-mcp.git
133 | cd zipcode-search-mcp
134 | uv sync
135 | ```
136 |
137 | 2. Run tests (if available):
138 | ```bash
139 | uv run pytest
140 | ```
141 |
142 | 3. Format code:
143 | ```bash
144 | uv run black .
145 | uv run isort .
146 | ```
147 |
148 | ### Contributing
149 |
150 | We welcome contributions! Please follow these steps:
151 |
152 | 1. Fork the repository
153 | 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
154 | 3. Make your changes
155 | 4. Add tests if applicable
156 | 5. Commit your changes (`git commit -m 'Add amazing feature'`)
157 | 6. Push to the branch (`git push origin feature/amazing-feature`)
158 | 7. Open a Pull Request
159 |
160 | ## Dependencies
161 |
162 | ### External Services
163 | - [Zipcloud API](https://zipcloud.ibsnet.co.jp/) - Provides postal code to address mapping data
164 |
165 | ### Python Packages
166 | - `mcp[cli]` - Model Context Protocol implementation
167 | - `httpx` - Async HTTP client for API requests
168 |
169 | ## Troubleshooting
170 |
171 | ### Server Won't Start
172 |
173 | 1. Verify Python version is 3.10+:
174 | ```bash
175 | python --version
176 | ```
177 |
178 | 2. Ensure dependencies are installed:
179 | ```bash
180 | uv sync
181 | ```
182 |
183 | 3. Check if the server starts manually:
184 | ```bash
185 | uv run python main.py
186 | ```
187 |
188 | ### Postal Code Not Found
189 |
190 | - Ensure the postal code is exactly 7 digits (no hyphens)
191 | - Verify the Zipcloud API is accessible
192 | - Check your internet connection
193 |
194 | ### MCP Client Connection Issues
195 |
196 | - Verify the path in your MCP client configuration is correct
197 | - Ensure the server is executable from the specified directory
198 | - Check MCP client logs for detailed error messages
199 |
200 | ## License
201 |
202 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
203 |
204 | ## Acknowledgments
205 |
206 | - [Zipcloud](https://zipcloud.ibsnet.co.jp/) for providing the postal code API
207 | - [Model Context Protocol](https://modelcontextprotocol.io/) for the integration framework
208 | - [FastMCP](https://github.com/jlowin/fastmcp) for the server implementation
209 |
210 | ## Support
211 |
212 | If you encounter any issues or have questions:
213 |
214 | 1. Check the [Issues](https://github.com/rooking-oss/zipcode-search-mcp/issues) page
215 | 2. Create a new issue with detailed information
216 | 3. For general questions, start a [Discussion](https://github.com/rooking-oss/zipcode-search-mcp/discussions)
217 |
218 | ---
219 |
220 | **Note**: This service uses the Zipcloud API and is intended for development and educational purposes. For production use, please ensure proper error handling, rate limiting, and compliance with the Zipcloud API terms of service.
221 |
```
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
```python
1 | from mcp.server.fastmcp import FastMCP
2 | import httpx
3 |
4 | mcp = FastMCP(
5 | name="zipcode-search",
6 | description="A Model Context Protocol server for Japanese postal code address lookup"
7 | )
8 |
9 | @mcp.tool()
10 | def search_zipcode(zipcode: str) -> dict:
11 | """Search for address by Japanese postal code
12 |
13 | Args:
14 | zipcode: 7-digit postal code (e.g., "1000001")
15 |
16 | Returns:
17 | dict: Address information with "address" key
18 | """
19 | try:
20 | with httpx.Client() as client:
21 | response = client.get(f"https://zipcloud.ibsnet.co.jp/api/search?zipcode={zipcode}")
22 | response.raise_for_status()
23 | data = response.json()
24 |
25 | if data.get("results"):
26 | result = data["results"][0]
27 | address = f"{result['address1']}{result['address2']}{result['address3']}"
28 | return {"address": address}
29 |
30 | return {"address": "Address not found"}
31 |
32 | except Exception as e:
33 | return {"address": f"Error occurred: {str(e)}"}
34 |
35 | if __name__ == "__main__":
36 | mcp.run()
37 |
```
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
```toml
1 | [project]
2 | name = "zipcode-search-mcp"
3 | version = "0.1.0"
4 | description = "A Model Context Protocol (MCP) server for Japanese postal code address lookup"
5 | readme = "README.md"
6 | requires-python = ">=3.10"
7 | license = {text = "MIT"}
8 | authors = [
9 | {name = "RookingOSS", email = "[email protected]"}
10 | ]
11 | keywords = ["mcp", "postal-code", "zipcode", "address", "japan"]
12 | classifiers = [
13 | "Development Status :: 4 - Beta",
14 | "Intended Audience :: Developers",
15 | "License :: OSI Approved :: MIT License",
16 | "Programming Language :: Python :: 3",
17 | "Programming Language :: Python :: 3.10",
18 | "Programming Language :: Python :: 3.11",
19 | "Programming Language :: Python :: 3.12",
20 | "Topic :: Software Development :: Libraries :: Python Modules",
21 | ]
22 | dependencies = [
23 | "httpx>=0.28.1",
24 | "mcp[cli]>=1.9.3",
25 | ]
26 |
27 | [project.urls]
28 | Homepage = "https://github.com/rooking-oss/zipcode-search-mcp"
29 | Repository = "https://github.com/rooking-oss/zipcode-search-mcp"
30 | Issues = "https://github.com/rooking-oss/zipcode-search-mcp/issues"
31 |
32 | [build-system]
33 | requires = ["hatchling"]
34 | build-backend = "hatchling.build"
35 |
36 | [tool.uv]
37 | dev-dependencies = []
38 |
```