Example Model Context Protocol (MCP) Server providing sudoku puzzle generation and solving functions
An example Model Context Protocol (MCP) server developed in Rust that provides sudoku puzzle generation and solving capabilities. This project demonstrates how to build MCP servers with explicit computational logic for puzzle solving.
Enterprises who need to comply with regulations that make them to have their data secure and on-premise but at the same time want to leverage the power of AI usually rely on small models. These models albeit powerful sometimes are not capable enough to deal with complex, multi-step logic and hence are not as reliable as a highly regulated environment needs.
Some references around this subject:
- Mathematical Reasoning in Large Language Models: Assessing Logical and Arithmetic Errors across Wide Numerical Ranges
- The Validation Gap: A Mechanistic Analysis of How Language Models Compute Arithmetic but Fail to Validate It
- Self-Error-Instruct: Generalizing from Errors for LLMs Mathematical Reasoning
This server provides sudoku puzzle generation and solving functions that demonstrate computational patterns for puzzle solving. All logic is explicit and transparent.
This is a demonstration/example project only. The sudoku generation and solving logic implemented here is for educational and demonstration purposes. This software:
- Serves as a technical example of MCP server implementation
- Demonstrates puzzle solving capabilities
- Is NOT affiliated with any official entity
This Sudoku Engine MCP Server provides reliable sudoku puzzle generation and solving capabilities that can be integrated with AI agents. Unlike relying solely on LLM reasoning for puzzle solving, this server uses the sudokugen crate to provide deterministic, verifiable sudoku puzzle generation and solving.
- 2 Sudoku Functions: generate_sudoku, solve_sudoku
- Explicit Logic: Uses sudokugen crate for reliable puzzle generation and solving
- Robust Input Validation: Demonstrates JSON schema validation with detailed error handling
- Flexible Input Format: Accepts puzzles in raw string format or formatted table format
- Containerization: Example Podman setup for deployment
- Claude Desktop Integration: Example MCPB packaging for MCP integration
- Professional Version Management: Automated version sync with cargo-release
- CI/CD Pipeline: Comprehensive GitHub Actions workflow
- Clean Repository Structure: Organized scripts and clean project layout
| Task | Command | Description |
|---|---|---|
| 🧪 Test | make test |
Run all tests |
| 🧪 Test SSE | make test-sse |
Run MCP server with SSE transport |
| 🧪 Test MCP | make test-mcp |
Run MCP server with Streamable HTTP transport |
| 🚀 Release | make release-patch |
Create new patch release |
| 📦 Package | make pack |
Create Claude Desktop package |
| 🐳 Container | make image-build |
Build container image |
| ℹ️ Help | make help |
Show all commands |
| Function | Description | Example |
|---|---|---|
| generate_sudoku | Generate a random classic 9x9 sudoku puzzle | Returns puzzle and solution as 81-character strings |
| solve_sudoku | Solve a 9x9 sudoku puzzle from a string | Accepts raw or formatted puzzle, returns solution |
Note: Both functions use the
sudokugencrate for reliable puzzle generation and solving.
Generate a new random 9x9 sudoku puzzle:
Function: generate_sudoku
Response:
{
"puzzle": "...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................",
"solution": "123456789456789123789123456234567891567891234891234567345678912678912345912345678",
"puzzle_display": "... | ... | ...\n..1 | 6.. | 4..\n2.. | .5. | 69.\n...\n.3. | 9.. | ...\n..4 | .2. | 8.6\n.8. | 56. | ..7\n...\n758 | 3.2 | ...\n6.. | ... | ...\n... | ... | ...",
"solution_display": "123 | 456 | 789\n456 | 789 | 123\n789 | 123 | 456\n...\n234 | 567 | 891\n567 | 891 | 234\n891 | 234 | 567\n...\n345 | 678 | 912\n678 | 912 | 345\n912 | 345 | 678",
"errors": []
}Solve a sudoku puzzle from a string (raw or formatted):
Function: solve_sudoku
Input (raw format):
puzzle: "...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................"
Input (formatted table format):
puzzle: ". . . | . . . | . . .\n. . 1 | 6 . . | 4 . .\n2 . . | . 5 . | 6 9 .\n------+-------+------\n. 3 . | 9 . . | . . .\n. . 4 | . 2 . | 8 . 6\n. 8 . | 5 6 . | . . 7\n------+-------+------\n7 5 8 | 3 . 2 | . . .\n6 . . | . . . | . . .\n. . . | . . . | . . ."
Response:
{
"solution": "123456789456789123789123456234567891567891234891234567345678912678912345912345678",
"solution_display": "123 | 456 | 789\n456 | 789 | 123\n789 | 123 | 456\n...\n234 | 567 | 891\n567 | 891 | 234\n891 | 234 | 567\n...\n345 | 678 | 912\n678 | 912 | 345\n912 | 345 | 678",
"solved": true,
"errors": []
}When querying the LLM with this MCP agent:
- Generate puzzles - Ask to generate a new sudoku puzzle
- Solve puzzles - Provide a puzzle in any format (raw string or formatted table)
- Use natural language - No need to know the exact API parameters
- Flexible input - Puzzles can be provided as raw strings or formatted tables
- Get solutions - The tool returns both raw solution strings and formatted displays
- Rust 1.70+ (Install Rust)
- Cargo (included with Rust)
jqfor JSON processing (Install jq)cargo-releasefor version management:cargo install cargo-release- NodeJS 19+ has to be installed if you want to test the server with MCP Inspector
# Clone the repository
git clone https://github.com/alpha-hack-program/sudoku-engine-mcp-rs.git
cd sudoku-engine-mcp-rs# Build all servers
make build-all
# Or build individually
make build-sse # SSE Server
make build-mcp # MCP HTTP Server
make build-stdio # STDIO Server for Claude# Run all tests
make testNOTE:
By default
BIND_ADDRESS=127.0.0.1:8000for SSE andBIND_ADDRESS=127.0.0.1:8001for Streamable HTTPBUT in the Makefile both
test-sseandtest-mcptargets setBIND_ADDRESS=0.0.0.0:8001
# SSE Server (recommended for Llama Stack, being deprecated in MCP Standard)
make test-sse
# MCP Streamable HTTP Server
make test-mcp
# Or directly
RUST_LOG=info BIND_ADDRESS=127.0.0.1:8002 ./target/release/sse_serverLet's run the MCP server with SSE transport in one terminal:
make test-sseRun MCP inspector with make inspector:
NOTE: NodeJS 19+ has to be installed
$ make inspector
npx @modelcontextprotocol/inspector
Starting MCP inspector...
⚙️ Proxy server listening on 127.0.0.1:6277
🔑 Session token: 6f0fdc22e2a9775a95d60c976b37b873bffec1816002fc702ca8ec7186a7c338
Use this token to authenticate requests or set DANGEROUSLY_OMIT_AUTH=true to disable auth
🔗 Open inspector with token pre-filled:
http://localhost:6274/?MCP_PROXY_AUTH_TOKEN=6f0fdc22e2a9775a95d60c976b37b873bffec1816002fc702ca8ec7186a7c338
🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀Open a browser and point to the URL with the token pre-filled.
Make sure:
- Transport Type:
SSE - URL:
http://localhost:8002/sse
Then click connect.
Now click on List Tools, then you should see the list of tools:
Finally click on generate_sudoku and click Run tool (no parameters needed):
Congratulations your Sudoku Engine tool is ready to be used by an MCP enabled agent.
# Create MCPB package for Claude Desktop
$ make pack
cargo build --release --bin stdio_server
Compiling sudoku-engine-mcp-server v0.1.0 (/Users/.../sudoku-engine-mcp-rs)
Finished `release` profile [optimized] target(s) in 18.23s
Packing MCP server for Claude Desktop...
chmod +x ./target/release/stdio_server
zip -rX sudoku-engine-mcp-server.mcpb -j mcpb/manifest.json ./target/release/stdio_server
updating: manifest.json (deflated 49%)
updating: stdio_server (deflated 63%)Open Claude Desktop and go to Settings->Extensions dropping area.
Note: This demonstrates MCP integration patterns and is not intended for production use with real data.
Drag and drop the MCPB file.
Click on Install:
Click on Install:
Click on Configure then close the dialog.
Your're ready to go, open a new chat:
Use this example query "Can you generate a new sudoku puzzle for me?":
Congratulations the tool works with Claude Desktop.
# Logging level (debug, info, warn, error)
RUST_LOG=info
# Or use BIND_ADDRESS directly
BIND_ADDRESS=127.0.0.1:8000Function: generate_sudoku
Parameters: None (no parameters needed)
Response:
{
"puzzle": "...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................",
"solution": "123456789456789123789123456234567891567891234891234567345678912678912345912345678",
"puzzle_display": "... | ... | ...\n..1 | 6.. | 4..\n2.. | .5. | 69.\n...\n.3. | 9.. | ...\n..4 | .2. | 8.6\n.8. | 56. | ..7\n...\n758 | 3.2 | ...\n6.. | ... | ...\n... | ... | ...",
"solution_display": "123 | 456 | 789\n456 | 789 | 123\n789 | 123 | 456\n...\n234 | 567 | 891\n567 | 891 | 234\n891 | 234 | 567\n...\n345 | 678 | 912\n678 | 912 | 345\n912 | 345 | 678",
"errors": []
}Function: solve_sudoku
Parameters:
{
"puzzle": "...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................"
}Response:
{
"solution": "123456789456789123789123456234567891567891234891234567345678912678912345912345678",
"solution_display": "123 | 456 | 789\n456 | 789 | 123\n789 | 123 | 456\n...\n234 | 567 | 891\n567 | 891 | 234\n891 | 234 | 567\n...\n345 | 678 | 912\n678 | 912 | 345\n912 | 345 | 678",
"solved": true,
"errors": []
}Note: The puzzle string can be in raw format (81 characters) or formatted table format. Formatting characters (spaces, newlines, dashes, pipes) are automatically ignored.
This requires podman or docker. Configuration is managed through .env file.
# Build container image
scripts/image.sh build
# Run locally
scripts/image.sh run
# Run from remote registry
scripts/image.sh push
scripts/image.sh run-remote
# Show container information
scripts/image.sh info# Production configuration
podman run -p 8001:8001 \
-e BIND_ADDRESS=0.0.0.0:8001 \
-e RUST_LOG=info \
quay.io/atarazana/sudoku-engine-mcp-server:latestmake build-all # Build all servers
make build-mcp # Build MCP server (streamable-http)
make build-sse # Build SSE server
make build-stdio # Build stdio server
make pack # Pack MCP server for Claude Desktopmake release-patch # Create patch release (1.0.6 → 1.0.7)
make release-minor # Create minor release (1.0.6 → 1.1.0)
make release-major # Create major release (1.0.6 → 2.0.0)
make release-dry-run # Show what release-patch would do
make sync-version # Manually sync version to all filesmake test # Run all tests
make test-sse # Test SSE server locally
make test-mcp # Test MCP server locallymake clean # Clean build artifacts
make help # Show all available commands├── src/ # Source code
│ ├── common/
│ │ ├── sudoku_engine.rs # MCP logic and sudoku functions
│ │ └── mod.rs
│ ├── sse_server.rs # SSE Server
│ ├── mcp_server.rs # MCP HTTP Server
│ └── stdio_server.rs # STDIO Server
├── scripts/ # Utility scripts
│ ├── sync-manifest-version.sh # Version sync for cargo-release
│ └── image.sh # Container management script
├── mcpb/
│ └── manifest.json # Claude Desktop manifest
├── .github/workflows/ # CI/CD pipelines
│ └── ci.yml # GitHub Actions workflow
├── examples/ # Example code
│ └── generate.rs # Example puzzle generation
├── .env # Environment variables
├── Containerfile # Container definition
├── Cargo.toml # Rust package manifest
└── Makefile # Build commands
| Field | Type | Description |
|---|---|---|
| (no parameters) | - | No parameters needed for generation |
Response Fields:
| Field | Type | Description |
|---|---|---|
puzzle |
string | The generated puzzle as 81-character string (row by row) |
solution |
string | The solution as 81-character string (row by row) |
puzzle_display |
string | The puzzle formatted for display |
solution_display |
string | The solution formatted for display |
errors |
array | Any errors in generation (empty if successful) |
| Field | Type | Description |
|---|---|---|
puzzle |
string | Sudoku puzzle as a string (81 characters, digits 1-9 or '.' for empty cells, row by row). Can be raw format or formatted table format. Formatting characters (spaces, newlines, dashes, pipes) are automatically ignored. |
Response Fields:
| Field | Type | Description |
|---|---|---|
solution |
string | The solved puzzle as 81-character string (empty if unsolvable) |
solution_display |
string | The solution formatted for display (empty if unsolvable) |
solved |
boolean | Whether the puzzle was successfully solved |
errors |
array | Any errors in solving |
- Input validation: Strict JSON schemas
- Non-root user: Containers run as user
1001 - Security audit:
cargo auditin CI/CD - Minimal image: Based on UBI 9 minimal
- Fork the project
- Create feature branch:
git checkout -b feature/new-feature - Make changes and test:
make test - Commit changes:
git commit -am 'Add new feature' - Push to branch:
git push origin feature/new-feature - Create Pull Request
- Development: Make changes, test with
make test - Version Bump: Use
make release-patch/minor/major - Build: Use
make packfor Claude Desktop integration - Container: Use
make image-buildfor containerization
- Code Quality: Follow
cargo fmtand passcargo clippy - Testing: Add tests for new functionality
- Version Management: Let cargo-release handle versioning
- CI/CD: Ensure all GitHub Actions pass
- Documentation: Update README.md as needed
- Professional Structure: Keep scripts in
scripts/directory
This project uses cargo-release for professional version management with automatic synchronization across all configuration files.
From Cargo.toml release configuration:
[package.metadata.release]
# Don't publish to crates.io (since this is a binary project)
publish = false
# Don't push git tags (you can enable this if you want)
push = false
# Run pre-release hook
pre-release-hook = ["scripts/sync-manifest-version.sh"]
# Create git tag with 'v' prefix
tag-name = "v{{version}}"
# Sign tags (optional)
sign-tag = false- Single Source of Truth:
Cargo.tomlversion controls everything - Automatic Sync: Updates
mcpb/manifest.jsonand.envautomatically - Git Integration: Creates commits and tags automatically
Work on your code, then when happy with it:
# 1. Make your changes and commit them
git add -A && git commit -m "feat: your changes"
# 2. Create a release (choose appropriate version bump)
make release-patch # Bug fixes: 1.0.6 → 1.0.7
make release-minor # New features: 1.0.6 → 1.1.0
make release-major # Breaking changes: 1.0.6 → 2.0.0
# 3. Build and package
make pack
make image-build
make image-push
# 4. Push to repository
git push && git push --tags# See what would happen without making changes
make release-dry-run# Sync version from Cargo.toml to other files manually
make sync-versionWhen using this MCP agent with an LLM, users can ask natural language questions that trigger the appropriate sudoku tools. Here are realistic scenarios:
Query: "Can you generate a new sudoku puzzle for me?"
Result:
- Puzzle generated successfully ✅
- Returns puzzle and solution as 81-character strings
- Includes formatted display versions for both puzzle and solution
- Puzzle is a valid, solvable 9x9 sudoku
Query: "I'd like a new sudoku puzzle. Can you show me the puzzle in a readable format?"
Result:
- Puzzle generated with formatted display
- Puzzle shown in 3x3 grid format with separators
- Solution also provided in formatted display
- Both raw strings and formatted displays included
Query: "Generate three different sudoku puzzles for me to solve."
Result:
- Three unique puzzles generated
- Each with its own puzzle and solution
- All puzzles are valid and solvable
The LLM will use generate_sudoku to create new random puzzles using the sudokugen crate.
Query: "Can you solve this sudoku puzzle: '...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................'?"
Result: ✅ SOLVED
- Solution provided as 81-character string
- Formatted display of the complete solution
- All cells filled correctly following sudoku rules
Query: "Solve this puzzle:
. . . | . . . | . . .
. . 1 | 6 . . | 4 . .
2 . . | . 5 . | 6 9 .
------+-------+------
. 3 . | 9 . . | . . .
. . 4 | . 2 . | 8 . 6
. 8 . | 5 6 . | . . 7
------+-------+------
7 5 8 | 3 . 2 | . . .
6 . . | . . . | . . .
. . . | . . . | . . .
```"
**Result:** ✅ **SOLVED**
- Puzzle parsed successfully (formatting characters ignored)
- Complete solution provided
- Solution verified to be valid
#### Example 3: Unsolvable Puzzle
**Query:** "Solve this puzzle: '123456789234567891345678912456789123567891234678912345789123456891234567912345678'"
**Result:** ❌ **UNSOLVABLE**
- Error: Puzzle violates sudoku rules or has no valid solution
- Detailed error message explaining why it cannot be solved
#### Example 4: Partial Solution Check
**Query:** "I'm working on this sudoku and got stuck. Can you solve it for me? Here's what I have: [provides partial puzzle]"
**Result:** ✅ **SOLVED**
- Takes the partial puzzle
- Completes all empty cells
- Returns full solution with formatted display
#### Sudoku Solving Rules
- **Input Format:** 81 characters (digits 1-9 or '.' for empty cells)
- **Format Flexibility:** Accepts raw strings or formatted tables
- **Validation:** Automatically validates puzzle format and rules
- **Solving:** Uses backtracking algorithm from sudokugen crate
- **Output:** Returns complete solution or error if unsolvable
*The LLM will use `solve_sudoku` with the provided puzzle string, automatically handling formatting, and return the complete solution.*
### 🔄 Complex Multi-Tool Scenarios
#### Example 1: Generate and Verify
**Query:** "Generate a sudoku puzzle, then solve it to verify it's correct."
**Analysis Results:**
**🎲 Puzzle Generation:**
- New puzzle generated
- Puzzle string: `"...........16..4..2...5.69..3.9.....4.2.8.6.8.56...77583.2...6................"`
- Solution string: `"123456789456789123789123456234567891567891234891234567345678912678912345912345678"`
**🧩 Solution Verification:**
- Puzzle solved successfully ✅
- Generated solution matches verification solution
- Puzzle is valid and solvable
**Overall Result:**
- Puzzle generation and solving both work correctly
- Generated puzzles are guaranteed to be solvable
---
#### Example 2: Solve Multiple Puzzles
**Query:** "I have three sudoku puzzles I need solved. Can you solve them all? [provides three puzzle strings]"
**Analysis Results:**
**Puzzle 1:**
- ✅ Solved successfully
- Solution provided
**Puzzle 2:**
- ✅ Solved successfully
- Solution provided
**Puzzle 3:**
- ✅ Solved successfully
- Solution provided
**Summary:**
- All three puzzles solved
- Solutions provided for each
- All puzzles were valid and solvable
*The LLM will use both `generate_sudoku` and `solve_sudoku` tools as needed to provide comprehensive sudoku puzzle generation and solving capabilities.*
## 📄 License
This project is licensed under the MIT License - see [LICENSE](LICENSE) for details.
### CI/CD Pipeline
The project includes a comprehensive GitHub Actions workflow:
- ✅ **Automated Testing**: Unit tests and integration tests
- ✅ **Version Sync Validation**: Tests cargo-release functionality
- ✅ **Container Building**: Tests containerization process
- ✅ **Artifact Management**: Builds and uploads release artifacts
- ✅ **Cross-platform Support**: Tests on Ubuntu with multiple container runtimes
## 🙋 Support
- **Issues**: [GitHub Issues](https://github.com/alpha-hack-program/sudoku-engine-mcp-rs/issues)
- **Documentation**: [Project Wiki](https://github.com/alpha-hack-program/sudoku-engine-mcp-rs/wiki)
- **CI/CD**: Automated testing and deployment via GitHub Actions
## 🏷️ Tags
`mcp` `model-context-protocol` `rust` `sudoku-engine` `puzzle-solving` `sudoku` `explicit-logic` `claude` `computation-engine` `cargo-release` `professional-rust` `containerization` `ci-cd`
---
**Developed with ❤️ by [Alpha Hack Group](https://github.com/alpha-hack-program)**









